From: Evan Hunt Date: Wed, 21 Jan 2015 00:10:30 +0000 (-0800) Subject: [master] add TCP pipelining support X-Git-Tag: v9.11.0a1~1091 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=761d135ed686601f36fe3d0d4aaa6bf41287bb0f;p=thirdparty%2Fbind9.git [master] add TCP pipelining support 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 "keep-response-order" option allows clients to be specified for which the old behavior will still be used.) [RT #37821] --- diff --git a/CHANGES b/CHANGES index c70a532fed6..7c64bdfe50d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +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 + "keep-response-order" option allows clients to be + specified for which the old behavior will still be + used.) [RT #37821] + 4039. [cleanup] Cleaned up warnings from gcc -Wshadow. [RT #37381] 4038. [bug] Add 'rpz' flag to node and use it to determine whether diff --git a/bin/named/client.c b/bin/named/client.c index d60509f9e9b..143a6a14943 100644 --- a/bin/named/client.c +++ b/bin/named/client.c @@ -244,6 +244,8 @@ static void client_request(isc_task_t *task, isc_event_t *event); static void ns_client_dumpmessage(ns_client_t *client, const char *reason); static isc_result_t get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, dns_dispatch_t *disp, isc_boolean_t tcp); +static isc_result_t get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, + isc_socket_t *socket); static inline isc_boolean_t allowed(isc_netaddr_t *addr, dns_name_t *signer, isc_netaddr_t *ecs_addr, isc_uint8_t ecs_addrlen, isc_uint8_t *ecs_scope, dns_acl_t *acl); @@ -385,9 +387,13 @@ exit_check(ns_client_t *client) { INSIST(client->recursionquota == NULL); if (NS_CLIENTSTATE_READING == client->newstate) { - client_read(client); - client->newstate = NS_CLIENTSTATE_MAX; - return (ISC_TRUE); /* We're done. */ + if (!client->pipelined) { + client_read(client); + client->newstate = NS_CLIENTSTATE_MAX; + return (ISC_TRUE); /* We're done. */ + } else if (client->mortal) { + client->newstate = NS_CLIENTSTATE_INACTIVE; + } } } @@ -424,6 +430,8 @@ exit_check(ns_client_t *client) { client->timerset = ISC_FALSE; } + client->pipelined = ISC_FALSE; + client->peeraddr_valid = ISC_FALSE; client->state = NS_CLIENTSTATE_READY; @@ -625,7 +633,11 @@ client_start(isc_task_t *task, isc_event_t *event) { return; if (TCP_CLIENT(client)) { - client_accept(client); + if (client->pipelined) { + client_read(client); + } else { + client_accept(client); + } } else { client_udprecv(client); } @@ -2151,6 +2163,24 @@ client_request(isc_task_t *task, isc_event_t *event) { goto cleanup; } + /* + * Pipeline TCP query processing. + */ + if (client->message->opcode != dns_opcode_query) + client->pipelined = ISC_FALSE; + if (TCP_CLIENT(client) && client->pipelined) { + result = isc_quota_reserve(&ns_g_server->tcpquota); + if (result == ISC_R_SUCCESS) + result = ns_client_replace(client); + if (result != ISC_R_SUCCESS) { + ns_client_log(client, NS_LOGCATEGORY_CLIENT, + NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, + "no more TCP clients(read): %s", + isc_result_totext(result)); + client->pipelined = ISC_FALSE; + } + } + dns_opcodestats_increment(ns_g_server->opcodestats, client->message->opcode); switch (client->message->opcode) { @@ -2676,6 +2706,7 @@ client_create(ns_clientmgr_t *manager, ns_client_t **clientp) { client->signer = NULL; dns_name_init(&client->signername, NULL); client->mortal = ISC_FALSE; + client->pipelined = ISC_FALSE; client->tcpquota = NULL; client->recursionquota = NULL; client->interface = NULL; @@ -2866,6 +2897,7 @@ client_newconn(isc_task_t *task, isc_event_t *event) { * telnetting to port 53 (once per CPU) will * deny service to legitimate TCP clients. */ + client->pipelined = ISC_FALSE; result = isc_quota_attach(&ns_g_server->tcpquota, &client->tcpquota); if (result == ISC_R_SUCCESS) @@ -2873,8 +2905,12 @@ client_newconn(isc_task_t *task, isc_event_t *event) { if (result != ISC_R_SUCCESS) { ns_client_log(client, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, ISC_LOG_WARNING, - "no more TCP clients: %s", + "no more TCP clients(accept): %s", isc_result_totext(result)); + } else if (ns_g_server->keepresporder == NULL || + !allowed(&netaddr, NULL, NULL, 0, NULL, + ns_g_server->keepresporder)) { + client->pipelined = ISC_TRUE; } client_read(client); @@ -2972,14 +3008,21 @@ ns_client_shuttingdown(ns_client_t *client) { isc_result_t ns_client_replace(ns_client_t *client) { isc_result_t result; + isc_boolean_t tcp; CTRACE("replace"); REQUIRE(client != NULL); REQUIRE(client->manager != NULL); - result = get_client(client->manager, client->interface, - client->dispatch, TCP_CLIENT(client)); + tcp = TCP_CLIENT(client); + if (tcp && client->pipelined) { + result = get_worker(client->manager, client->interface, + client->tcpsocket); + } else { + result = get_client(client->manager, client->interface, + client->dispatch, tcp); + } if (result != ISC_R_SUCCESS) return (result); @@ -3186,6 +3229,72 @@ get_client(ns_clientmgr_t *manager, ns_interface_t *ifp, return (ISC_R_SUCCESS); } +static isc_result_t +get_worker(ns_clientmgr_t *manager, ns_interface_t *ifp, isc_socket_t *socket) +{ + isc_result_t result = ISC_R_SUCCESS; + isc_event_t *ev; + ns_client_t *client; + MTRACE("get worker"); + + REQUIRE(manager != NULL); + + if (manager->exiting) + return (ISC_R_SHUTTINGDOWN); + + /* + * Allocate a client. First try to get a recycled one; + * if that fails, make a new one. + */ + client = NULL; + if (!ns_g_clienttest) + ISC_QUEUE_POP(manager->inactive, ilink, client); + + if (client != NULL) + MTRACE("recycle"); + else { + MTRACE("create new"); + + LOCK(&manager->lock); + result = client_create(manager, &client); + UNLOCK(&manager->lock); + if (result != ISC_R_SUCCESS) + return (result); + + LOCK(&manager->listlock); + ISC_LIST_APPEND(manager->clients, client, link); + UNLOCK(&manager->listlock); + } + + client->manager = manager; + ns_interface_attach(ifp, &client->interface); + client->newstate = client->state = NS_CLIENTSTATE_WORKING; + INSIST(client->recursionquota == NULL); + client->tcpquota = &ns_g_server->tcpquota; + + client->dscp = ifp->dscp; + + client->attributes |= NS_CLIENTATTR_TCP; + client->pipelined = ISC_TRUE; + + isc_socket_attach(ifp->tcpsocket, &client->tcplistener); + isc_socket_attach(socket, &client->tcpsocket); + isc_socket_setname(client->tcpsocket, "worker-tcp", NULL); + (void)isc_socket_getpeername(client->tcpsocket, &client->peeraddr); + client->peeraddr_valid = ISC_TRUE; + + INSIST(client->tcpmsg_valid == ISC_FALSE); + dns_tcpmsg_init(client->mctx, client->tcpsocket, &client->tcpmsg); + client->tcpmsg_valid = ISC_TRUE; + + INSIST(client->nctls == 0); + client->nctls++; + ev = &client->ctlevent; + isc_task_send(client->task, &ev); + + return (ISC_R_SUCCESS); +} + isc_result_t ns_clientmgr_createclients(ns_clientmgr_t *manager, unsigned int n, ns_interface_t *ifp, isc_boolean_t tcp) diff --git a/bin/named/config.c b/bin/named/config.c index de685e9b04e..90530a0493f 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -70,6 +70,7 @@ options {\n\ heartbeat-interval 60;\n\ host-statistics no;\n\ interface-interval 60;\n\ +# keep-response-order {none;};\n\ listen-on {any;};\n\ listen-on-v6 {any;};\n\ match-mapped-addresses no;\n\ @@ -101,7 +102,7 @@ options {\n\ startup-notify-rate 20;\n\ statistics-file \"named.stats\";\n\ statistics-interval 60;\n\ - tcp-clients 100;\n\ + tcp-clients 150;\n\ tcp-listen-queue 10;\n\ # tkey-dhkey \n\ # tkey-gssapi-credential \n\ diff --git a/bin/named/include/named/client.h b/bin/named/include/named/client.h index 5b806baafd1..7e09dcb53e8 100644 --- a/bin/named/include/named/client.h +++ b/bin/named/include/named/client.h @@ -135,6 +135,7 @@ struct ns_client { dns_name_t signername; /*%< [T]SIG key name */ dns_name_t * signer; /*%< NULL if not valid sig */ isc_boolean_t mortal; /*%< Die after handling request */ + isc_boolean_t pipelined; /*%< TCP queries not in sequence */ isc_quota_t *tcpquota; isc_quota_t *recursionquota; ns_interface_t *interface; diff --git a/bin/named/include/named/server.h b/bin/named/include/named/server.h index 04151d25409..4fa8de128f4 100644 --- a/bin/named/include/named/server.h +++ b/bin/named/include/named/server.h @@ -52,6 +52,7 @@ struct ns_server { isc_quota_t tcpquota; isc_quota_t recursionquota; dns_acl_t *blackholeacl; + dns_acl_t *keepresporder; char * statsfile; /*%< Statistics file name */ char * dumpfile; /*%< Dump file name */ char * secrootsfile; /*%< Secroots file name */ diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index 9917715e159..3b7351f3e5d 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -211,6 +211,7 @@ options { host-statistics-max number; // not implemented hostname ( quoted_string | none ); interface-interval integer; + keep-response-order { address_match_element; ... }; listen-on port integer { address_match_element; ... }; listen-on-v6 port integer { address_match_element; ... }; match-mapped-addresses boolean; diff --git a/bin/named/server.c b/bin/named/server.c index 264e208f300..f3c0768b398 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -5594,6 +5594,10 @@ load_configuration(const char *filename, ns_server_t *server, dns_dispatchmgr_setblackhole(ns_g_dispatchmgr, server->blackholeacl); + CHECK(configure_view_acl(NULL, config, "keep-response-order", NULL, + ns_g_aclconfctx, ns_g_mctx, + &server->keepresporder)); + obj = NULL; result = ns_config_get(maps, "match-mapped-addresses", &obj); INSIST(result == ISC_R_SUCCESS); @@ -6671,6 +6675,9 @@ shutdown_server(isc_task_t *task, isc_event_t *event) { dns_name_free(&ns_g_sessionkeyname, server->mctx); } + if (server->keepresporder != NULL) + dns_acl_detach(&server->keepresporder); + if (server->blackholeacl != NULL) dns_acl_detach(&server->blackholeacl); @@ -6722,6 +6729,7 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { ISC_LIST_INIT(server->viewlist); server->in_roothints = NULL; server->blackholeacl = NULL; + server->keepresporder = NULL; /* Must be first. */ CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy, diff --git a/bin/tests/named.conf b/bin/tests/named.conf index 722d2626f61..5b4004559aa 100644 --- a/bin/tests/named.conf +++ b/bin/tests/named.conf @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2007, 2011, 2014 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -116,6 +116,7 @@ options { allow-transfer { any; }; allow-recursion { !any; }; blackhole { 45/24; }; + keep-response-order { 46/24; }; listen-on { 10/24; diff --git a/bin/tests/system/Makefile.in b/bin/tests/system/Makefile.in index 0bf725ec521..ae3d62fac41 100644 --- a/bin/tests/system/Makefile.in +++ b/bin/tests/system/Makefile.in @@ -21,8 +21,8 @@ top_srcdir = @top_srcdir@ @BIND9_MAKE_INCLUDES@ -SUBDIRS = builtin dlzexternal filter-aaaa geoip lwresd resolver rndc rpz \ - rsabigexponent tkey tsiggss +SUBDIRS = builtin dlzexternal filter-aaaa geoip lwresd pipelined \ + resolver rndc rpz rsabigexponent tkey tsiggss TARGETS = @BIND9_MAKE_RULES@ diff --git a/bin/tests/system/checkconf/bad-keep-response-order.conf b/bin/tests/system/checkconf/bad-keep-response-order.conf new file mode 100644 index 00000000000..24c1f6c8b2a --- /dev/null +++ b/bin/tests/system/checkconf/bad-keep-response-order.conf @@ -0,0 +1,21 @@ +/* + * Copyright (C) 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +options { + keep-response-order { + does_not_exist; + }; +}; diff --git a/bin/tests/system/checkconf/bad-many.conf b/bin/tests/system/checkconf/bad-many.conf index cfc4d0252be..09add877fbf 100644 --- a/bin/tests/system/checkconf/bad-many.conf +++ b/bin/tests/system/checkconf/bad-many.conf @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2005, 2012, 2014 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 @@ -33,6 +33,7 @@ options { host-statistics-max 100; hostname none; interface-interval 30; + keep-response-order { 10.0.0.10/24; }; listen-on port 90 { any; }; listen-on port 100 { 127.0.0.1; }; listen-on-v6 port 53 { none; }; diff --git a/bin/tests/system/checkconf/good.conf b/bin/tests/system/checkconf/good.conf index f1cb1429963..8706ee0fc42 100644 --- a/bin/tests/system/checkconf/good.conf +++ b/bin/tests/system/checkconf/good.conf @@ -43,6 +43,9 @@ options { host-statistics-max 100; hostname none; interface-interval 30; + keep-response-order { + 10.0.0.10/24; + }; listen-on port 90 { "any"; }; diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index d3d5b08aab9..d8e4c4acddd 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -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 @PKCS11_TEST@ + metadata notify nslookup nsupdate pending piplined @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 diff --git a/bin/tests/system/pipelined/Makefile.in b/bin/tests/system/pipelined/Makefile.in new file mode 100644 index 00000000000..4d16d78fb4d --- /dev/null +++ b/bin/tests/system/pipelined/Makefile.in @@ -0,0 +1,51 @@ +# Copyright (C) 2014 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 +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +@BIND9_MAKE_INCLUDES@ + +CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} + +CDEFINES = +CWARNINGS = + +DNSLIBS = ../../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ +ISCLIBS = ../../../../lib/isc/libisc.@A@ + +DNSDEPLIBS = ../../../../lib/dns/libdns.@A@ +ISCDEPLIBS = ../../../../lib/isc/libisc.@A@ + +DEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} + +LIBS = ${DNSLIBS} ${ISCLIBS} @LIBS@ + +TARGETS = pipequeries@EXEEXT@ + +SRCS = pipequeries.c + +@BIND9_MAKE_RULES@ + +all: pipequeries@EXEEXT@ + +pipequeries@EXEEXT@: pipequeries.@O@ ${DEPLIBS} + ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ pipequeries.@O@ ${LIBS} + +clean distclean:: + rm -f ${TARGETS} + diff --git a/bin/tests/system/pipelined/clean.sh b/bin/tests/system/pipelined/clean.sh new file mode 100644 index 00000000000..1cca633dd19 --- /dev/null +++ b/bin/tests/system/pipelined/clean.sh @@ -0,0 +1,19 @@ +#!/bin/sh +# +# Copyright (C) 2014 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 +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +rm -f */named.memstats +rm -f */named.run +rm -f raw* output* diff --git a/bin/tests/system/pipelined/input b/bin/tests/system/pipelined/input new file mode 100644 index 00000000000..485cf81fa91 --- /dev/null +++ b/bin/tests/system/pipelined/input @@ -0,0 +1,8 @@ +a.examplea +a.exampleb +b.examplea +b.exampleb +c.examplea +c.exampleb +d.examplea +d.exampleb diff --git a/bin/tests/system/pipelined/inputb b/bin/tests/system/pipelined/inputb new file mode 100644 index 00000000000..6ea367e2783 --- /dev/null +++ b/bin/tests/system/pipelined/inputb @@ -0,0 +1,8 @@ +e.examplea +e.exampleb +f.examplea +f.exampleb +g.examplea +g.exampleb +h.examplea +h.exampleb diff --git a/bin/tests/system/pipelined/ns1/named.conf b/bin/tests/system/pipelined/ns1/named.conf new file mode 100644 index 00000000000..1bbf401c069 --- /dev/null +++ b/bin/tests/system/pipelined/ns1/named.conf @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + listen-on-v6 { none; }; + recursion no; + notify yes; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; }; +}; + +zone "." { + type master; + file "root.db"; +}; diff --git a/bin/tests/system/pipelined/ns1/root.db b/bin/tests/system/pipelined/ns1/root.db new file mode 100644 index 00000000000..b5186e57677 --- /dev/null +++ b/bin/tests/system/pipelined/ns1/root.db @@ -0,0 +1,30 @@ +; Copyright (C) 2014 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 +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +$TTL 300 +. IN SOA gson.nominum.com. a.root.servers.nil. ( + 2000042100 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +. NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 + +examplea. NS ns2.examplea. +ns2.examplea. A 10.53.0.2 + +exampleb. NS ns3.exampleb. +ns3.exampleb. A 10.53.0.3 diff --git a/bin/tests/system/pipelined/ns2/examplea.db b/bin/tests/system/pipelined/ns2/examplea.db new file mode 100644 index 00000000000..678034a216b --- /dev/null +++ b/bin/tests/system/pipelined/ns2/examplea.db @@ -0,0 +1,35 @@ +; Copyright (C) 2014 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 +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +$ORIGIN . +$TTL 300 ; 5 minutes +examplea IN SOA mname1. . ( + 1 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) +examplea. NS ns2.examplea. +ns2.examplea. A 10.53.0.2 + +$ORIGIN examplea. +a A 10.0.1.1 +b A 10.0.1.2 +c A 10.0.1.3 +d A 10.0.1.4 +e A 10.0.1.5 +f A 10.0.1.6 +g A 10.0.1.7 +h A 10.0.1.8 diff --git a/bin/tests/system/pipelined/ns2/named.conf b/bin/tests/system/pipelined/ns2/named.conf new file mode 100644 index 00000000000..83a9ec7a497 --- /dev/null +++ b/bin/tests/system/pipelined/ns2/named.conf @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.2; + notify-source 10.53.0.2; + transfer-source 10.53.0.2; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.2; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.2 port 9953 allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../common/root.hint"; +}; + +zone "examplea" { + type master; + file "examplea.db"; + allow-update { any; }; +}; diff --git a/bin/tests/system/pipelined/ns3/exampleb.db b/bin/tests/system/pipelined/ns3/exampleb.db new file mode 100644 index 00000000000..7d10493465a --- /dev/null +++ b/bin/tests/system/pipelined/ns3/exampleb.db @@ -0,0 +1,35 @@ +; Copyright (C) 2014 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 +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +$ORIGIN . +$TTL 300 ; 5 minutes +exampleb IN SOA mname1. . ( + 1 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) +exampleb. NS ns3.exampleb. +ns3.exampleb. A 10.53.0.3 + +$ORIGIN exampleb. +a A 10.0.2.1 +b A 10.0.2.2 +c A 10.0.2.3 +d A 10.0.2.4 +e A 10.0.2.5 +f A 10.0.2.6 +g A 10.0.2.7 +h A 10.0.2.8 diff --git a/bin/tests/system/pipelined/ns3/named.args b/bin/tests/system/pipelined/ns3/named.args new file mode 100644 index 00000000000..a6b0f54e56e --- /dev/null +++ b/bin/tests/system/pipelined/ns3/named.args @@ -0,0 +1 @@ +-m record,size,mctx -c named.conf -d 99 -g -T delay=200 diff --git a/bin/tests/system/pipelined/ns3/named.conf b/bin/tests/system/pipelined/ns3/named.conf new file mode 100644 index 00000000000..8b15622e551 --- /dev/null +++ b/bin/tests/system/pipelined/ns3/named.conf @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.3 port 9953 allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../common/root.hint"; +}; + +zone "exampleb" { + type master; + file "exampleb.db"; + allow-update { any; }; +}; diff --git a/bin/tests/system/pipelined/ns4/named.conf b/bin/tests/system/pipelined/ns4/named.conf new file mode 100644 index 00000000000..7e7923a1431 --- /dev/null +++ b/bin/tests/system/pipelined/ns4/named.conf @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2014 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.4; + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port 5300; + directory "."; + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + listen-on-v6 { none; }; + keep-response-order { 10.53.0.7/32; }; + recursion yes; + notify yes; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.4 port 9953 allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../common/root.hint"; +}; diff --git a/bin/tests/system/pipelined/pipequeries.c b/bin/tests/system/pipelined/pipequeries.c new file mode 100644 index 00000000000..41794ec84a8 --- /dev/null +++ b/bin/tests/system/pipelined/pipequeries.c @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2014 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define CHECK(str, x) { \ + if ((x) != ISC_R_SUCCESS) { \ + fprintf(stderr, "I:%s: %s\n", (str), isc_result_totext(x)); \ + exit(-1); \ + } \ +} + +#define RUNCHECK(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS) + +#define PORT 5300 +#define TIMEOUT 30 + +static isc_mem_t *mctx; +static dns_requestmgr_t *requestmgr; +isc_sockaddr_t address; +static int onfly; + +static void +recvresponse(isc_task_t *task, isc_event_t *event) { + dns_requestevent_t *reqev = (dns_requestevent_t *)event; + isc_result_t result; + dns_message_t *query, *response; + isc_buffer_t outbuf; + char output[1024]; + + UNUSED(task); + + REQUIRE(reqev != NULL); + + if (reqev->result != ISC_R_SUCCESS) { + fprintf(stderr, "I:request event result: %s\n", + isc_result_totext(reqev->result)); + exit(-1); + } + + query = reqev->ev_arg; + + response = NULL; + result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response); + CHECK("dns_message_create", result); + + result = dns_request_getresponse(reqev->request, response, + DNS_MESSAGEPARSE_PRESERVEORDER); + CHECK("dns_request_getresponse", result); + + if (response->rcode != dns_rcode_noerror) { + result = ISC_RESULTCLASS_DNSRCODE + response->rcode; + fprintf(stderr, "I:response rcode: %s\n", + isc_result_totext(result)); + exit(-1); + } + if (response->counts[DNS_SECTION_ANSWER] != 1U) { + fprintf(stderr, "I:response answer count (%u!=1)\n", + response->counts[DNS_SECTION_ANSWER]); + } + + isc_buffer_init(&outbuf, output, sizeof(output)); + result = dns_message_sectiontotext(response, DNS_SECTION_ANSWER, + &dns_master_style_simple, + DNS_MESSAGETEXTFLAG_NOCOMMENTS, + &outbuf); + CHECK("dns_message_sectiontotext", result); + printf("%.*s", (int)isc_buffer_usedlength(&outbuf), + (char *)isc_buffer_base(&outbuf)); + fflush(stdout); + + dns_message_destroy(&query); + dns_message_destroy(&response); + dns_request_destroy(&reqev->request); + isc_event_free(&event); + + if (--onfly == 0) + isc_app_shutdown(); + return; +} + +static isc_result_t +sendquery(isc_task_t *task) +{ + dns_request_t *request; + dns_message_t *message; + dns_name_t *qname; + dns_rdataset_t *qrdataset; + isc_result_t result; + dns_fixedname_t queryname; + isc_buffer_t buf; + static char host[256]; + int c; + + c = scanf("%255s", host); + if (c == EOF) + return ISC_R_NOMORE; + + onfly++; + + dns_fixedname_init(&queryname); + isc_buffer_init(&buf, host, strlen(host)); + isc_buffer_add(&buf, strlen(host)); + result = dns_name_fromtext(dns_fixedname_name(&queryname), &buf, + dns_rootname, 0, NULL); + CHECK("dns_name_fromtext", result); + + message = NULL; + result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message); + CHECK("dns_message_create", result); + + message->opcode = dns_opcode_query; + message->flags |= DNS_MESSAGEFLAG_RD; + message->rdclass = dns_rdataclass_in; + message->id = (unsigned short)(random() & 0xFFFF); + + qname = NULL; + result = dns_message_gettempname(message, &qname); + CHECK("dns_message_gettempname", result); + + qrdataset = NULL; + result = dns_message_gettemprdataset(message, &qrdataset); + CHECK("dns_message_gettemprdataset", result); + + dns_name_init(qname, NULL); + dns_name_clone(dns_fixedname_name(&queryname), qname); + dns_rdataset_init(qrdataset); + dns_rdataset_makequestion(qrdataset, dns_rdataclass_in, + dns_rdatatype_a); + ISC_LIST_APPEND(qname->list, qrdataset, link); + 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); + CHECK("dns_request_create", result); + + return ISC_R_SUCCESS; +} + +static void +sendqueries(isc_task_t *task, isc_event_t *event) +{ + isc_result_t result; + + isc_event_free(&event); + + do { + result = sendquery(task); + } while (result == ISC_R_SUCCESS); + + if (onfly == 0) + isc_app_shutdown(); + 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; + struct in_addr inaddr; + isc_result_t result; + + UNUSED(argv); + + RUNCHECK(isc_app_start()); + + dns_result_register(); + + mctx = NULL; + RUNCHECK(isc_mem_create(0, 0, &mctx)); + + lctx = NULL; + lcfg = NULL; + RUNCHECK(isc_log_create(mctx, &lctx, &lcfg)); + + ectx = NULL; + RUNCHECK(isc_entropy_create(mctx, &ectx)); + RUNCHECK(isc_entropy_createfilesource(ectx, "../random.data")); + RUNCHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)); + + RUNCHECK(dst_lib_init(mctx, ectx, ISC_ENTROPY_GOODONLY)); + + taskmgr = NULL; + RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr)); + task = NULL; + RUNCHECK(isc_task_create(taskmgr, 0, &task)); + timermgr = NULL; + + RUNCHECK(isc_timermgr_create(mctx, &timermgr)); + socketmgr = NULL; + 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; + attrmask = DNS_DISPATCHATTR_UDP | + DNS_DISPATCHATTR_TCP | + DNS_DISPATCHATTR_IPV4 | + DNS_DISPATCHATTR_IPV6; + dispatchv4 = NULL; + RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr, + &bind_addr, 4096, 4, 2, 3, 5, + attrs, attrmask, &dispatchv4)); + requestmgr = NULL; + RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr, + dispatchmgr, dispatchv4, NULL, + &requestmgr)); + + 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); + + (void)isc_app_run(); + + dns_view_detach(&view); + + dns_requestmgr_shutdown(requestmgr); + dns_requestmgr_detach(&requestmgr); + + dns_dispatch_detach(&dispatchv4); + dns_dispatch_detach(&tcpdispatch); + dns_dispatchmgr_destroy(&dispatchmgr); + + isc_socketmgr_destroy(&socketmgr); + isc_timermgr_destroy(&timermgr); + + isc_task_shutdown(task); + isc_task_detach(&task); + isc_taskmgr_destroy(&taskmgr); + + dst_lib_destroy(); + isc_hash_destroy(); + isc_entropy_detach(&ectx); + + isc_log_destroy(&lctx); + + isc_mem_destroy(&mctx); + + isc_app_finish(); + + return (0); +} + diff --git a/bin/tests/system/pipelined/ref b/bin/tests/system/pipelined/ref new file mode 100644 index 00000000000..fe123f6c3ca --- /dev/null +++ b/bin/tests/system/pipelined/ref @@ -0,0 +1,8 @@ +a.examplea. 10.0.1.1 +a.exampleb. 10.0.2.1 +b.examplea. 10.0.1.2 +b.exampleb. 10.0.2.2 +c.examplea. 10.0.1.3 +c.exampleb. 10.0.2.3 +d.examplea. 10.0.1.4 +d.exampleb. 10.0.2.4 diff --git a/bin/tests/system/pipelined/refb b/bin/tests/system/pipelined/refb new file mode 100644 index 00000000000..a24c6bc4b86 --- /dev/null +++ b/bin/tests/system/pipelined/refb @@ -0,0 +1,8 @@ +e.examplea. 10.0.1.5 +e.exampleb. 10.0.2.5 +f.examplea. 10.0.1.6 +f.exampleb. 10.0.2.6 +g.examplea. 10.0.1.7 +g.exampleb. 10.0.2.7 +h.examplea. 10.0.1.8 +h.exampleb. 10.0.2.8 diff --git a/bin/tests/system/pipelined/setup.sh b/bin/tests/system/pipelined/setup.sh new file mode 100644 index 00000000000..6fc981d48c6 --- /dev/null +++ b/bin/tests/system/pipelined/setup.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# +# Copyright (C) 2014 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 +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +$SHELL clean.sh + +test -r $RANDFILE || $GENRANDOM 400 $RANDFILE diff --git a/bin/tests/system/pipelined/tests.sh b/bin/tests/system/pipelined/tests.sh new file mode 100644 index 00000000000..a34e573686e --- /dev/null +++ b/bin/tests/system/pipelined/tests.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# +# Copyright (C) 2014 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 +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +status=0 + +echo "I:check pipelined TCP queries" +ret=0 +./pipequeries < input > raw || ret=1 +awk '{ print $1 " " $5 }' < raw > output +sort < output > output-sorted +diff ref output-sorted || { ret=1 ; echo "I: diff sorted failed"; } +diff ref output > /dev/null && { ret=1 ; echo "I: diff out of order failed"; } +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:check keep response order" +ret=0 +./pipequeries ++ < inputb > rawb || ret=1 +awk '{ print $1 " " $5 }' < rawb > outputb +diff refb outputb || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:exit status: $status" +exit $status diff --git a/configure b/configure index d80c612c3e2..eb9d19a869c 100755 --- a/configure +++ b/configure @@ -21853,7 +21853,7 @@ ac_config_commands="$ac_config_commands chmod" # elsewhere if there's a good reason for doing so. # -ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/delv/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/dnssec-checkds.py bin/python/dnssec-coverage.py bin/rndc/Makefile bin/tests/Makefile bin/tests/atomic/Makefile bin/tests/db/Makefile bin/tests/dst/Makefile bin/tests/dst/Kdh.+002+18602.key bin/tests/dst/Kdh.+002+18602.private bin/tests/dst/Kdh.+002+48957.key bin/tests/dst/Kdh.+002+48957.private bin/tests/dst/Ktest.+001+00002.key bin/tests/dst/Ktest.+001+54622.key bin/tests/dst/Ktest.+001+54622.private bin/tests/dst/Ktest.+003+23616.key bin/tests/dst/Ktest.+003+23616.private bin/tests/dst/Ktest.+003+49667.key bin/tests/dst/dst_2_data bin/tests/dst/t2_data_1 bin/tests/dst/t2_data_2 bin/tests/dst/t2_dsasig bin/tests/dst/t2_rsasig bin/tests/hashes/Makefile bin/tests/headerdep_test.sh bin/tests/master/Makefile bin/tests/mem/Makefile bin/tests/names/Makefile bin/tests/net/Makefile bin/tests/pkcs11/Makefile bin/tests/pkcs11/benchmarks/Makefile bin/tests/rbt/Makefile bin/tests/resolver/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/builtin/Makefile bin/tests/system/conf.sh bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/named.conf bin/tests/system/filter-aaaa/Makefile bin/tests/system/geoip/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/lwresd/Makefile bin/tests/system/resolver/Makefile bin/tests/system/rndc/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/sit/prereq.sh bin/tests/system/tkey/Makefile bin/tests/system/tsiggss/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/scripts/check-secure-delegation.pl contrib/scripts/zone-edit.sh doc/Makefile doc/arm/Makefile doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl doc/xsl/isc-notes-html.xsl doc/xsl/isc-notes-latex.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/include/pk11/Makefile lib/isc/include/pkcs11/Makefile lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/tests/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile lib/samples/Makefile lib/samples/Makefile-postinstall unit/Makefile unit/unittest.sh" +ac_config_files="$ac_config_files make/Makefile make/mkdep Makefile bin/Makefile bin/check/Makefile bin/confgen/Makefile bin/confgen/unix/Makefile bin/delv/Makefile bin/dig/Makefile bin/dnssec/Makefile bin/named/Makefile bin/named/unix/Makefile bin/nsupdate/Makefile bin/pkcs11/Makefile bin/python/Makefile bin/python/dnssec-checkds.py bin/python/dnssec-coverage.py bin/rndc/Makefile bin/tests/Makefile bin/tests/atomic/Makefile bin/tests/db/Makefile bin/tests/dst/Makefile bin/tests/dst/Kdh.+002+18602.key bin/tests/dst/Kdh.+002+18602.private bin/tests/dst/Kdh.+002+48957.key bin/tests/dst/Kdh.+002+48957.private bin/tests/dst/Ktest.+001+00002.key bin/tests/dst/Ktest.+001+54622.key bin/tests/dst/Ktest.+001+54622.private bin/tests/dst/Ktest.+003+23616.key bin/tests/dst/Ktest.+003+23616.private bin/tests/dst/Ktest.+003+49667.key bin/tests/dst/dst_2_data bin/tests/dst/t2_data_1 bin/tests/dst/t2_data_2 bin/tests/dst/t2_dsasig bin/tests/dst/t2_rsasig bin/tests/hashes/Makefile bin/tests/headerdep_test.sh bin/tests/master/Makefile bin/tests/mem/Makefile bin/tests/names/Makefile bin/tests/net/Makefile bin/tests/pkcs11/Makefile bin/tests/pkcs11/benchmarks/Makefile bin/tests/rbt/Makefile bin/tests/resolver/Makefile bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/builtin/Makefile bin/tests/system/conf.sh bin/tests/system/dlz/prereq.sh bin/tests/system/dlzexternal/Makefile bin/tests/system/dlzexternal/ns1/named.conf bin/tests/system/filter-aaaa/Makefile bin/tests/system/geoip/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/lwresd/Makefile bin/tests/system/pipelined/Makefile bin/tests/system/resolver/Makefile bin/tests/system/rndc/Makefile bin/tests/system/rpz/Makefile bin/tests/system/rsabigexponent/Makefile bin/tests/system/sit/prereq.sh bin/tests/system/tkey/Makefile bin/tests/system/tsiggss/Makefile bin/tests/tasks/Makefile bin/tests/timers/Makefile bin/tests/virtual-time/Makefile bin/tests/virtual-time/conf.sh bin/tools/Makefile contrib/scripts/check-secure-delegation.pl contrib/scripts/zone-edit.sh doc/Makefile doc/arm/Makefile doc/doxygen/Doxyfile doc/doxygen/Makefile doc/doxygen/doxygen-input-filter doc/misc/Makefile doc/xsl/Makefile doc/xsl/isc-docbook-chunk.xsl doc/xsl/isc-docbook-html.xsl doc/xsl/isc-docbook-latex.xsl doc/xsl/isc-manpage.xsl doc/xsl/isc-notes-html.xsl doc/xsl/isc-notes-latex.xsl isc-config.sh lib/Makefile lib/bind9/Makefile lib/bind9/include/Makefile lib/bind9/include/bind9/Makefile lib/dns/Makefile lib/dns/include/Makefile lib/dns/include/dns/Makefile lib/dns/include/dst/Makefile lib/dns/tests/Makefile lib/irs/Makefile lib/irs/include/Makefile lib/irs/include/irs/Makefile lib/irs/include/irs/netdb.h lib/irs/include/irs/platform.h lib/isc/$arch/Makefile lib/isc/$arch/include/Makefile lib/isc/$arch/include/isc/Makefile lib/isc/$thread_dir/Makefile lib/isc/$thread_dir/include/Makefile lib/isc/$thread_dir/include/isc/Makefile lib/isc/Makefile lib/isc/include/Makefile lib/isc/include/isc/Makefile lib/isc/include/isc/platform.h lib/isc/include/pk11/Makefile lib/isc/include/pkcs11/Makefile lib/isc/tests/Makefile lib/isc/nls/Makefile lib/isc/unix/Makefile lib/isc/unix/include/Makefile lib/isc/unix/include/isc/Makefile lib/isc/unix/include/pkcs11/Makefile lib/isccc/Makefile lib/isccc/include/Makefile lib/isccc/include/isccc/Makefile lib/isccfg/Makefile lib/isccfg/include/Makefile lib/isccfg/include/isccfg/Makefile lib/lwres/Makefile lib/lwres/include/Makefile lib/lwres/include/lwres/Makefile lib/lwres/include/lwres/netdb.h lib/lwres/include/lwres/platform.h lib/lwres/man/Makefile lib/lwres/tests/Makefile lib/lwres/unix/Makefile lib/lwres/unix/include/Makefile lib/lwres/unix/include/lwres/Makefile lib/tests/Makefile lib/tests/include/Makefile lib/tests/include/tests/Makefile lib/samples/Makefile lib/samples/Makefile-postinstall unit/Makefile unit/unittest.sh" # @@ -22905,6 +22905,7 @@ do "bin/tests/system/geoip/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/geoip/Makefile" ;; "bin/tests/system/inline/checkdsa.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/inline/checkdsa.sh" ;; "bin/tests/system/lwresd/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/lwresd/Makefile" ;; + "bin/tests/system/pipelined/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/pipelined/Makefile" ;; "bin/tests/system/resolver/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/resolver/Makefile" ;; "bin/tests/system/rndc/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rndc/Makefile" ;; "bin/tests/system/rpz/Makefile") CONFIG_FILES="$CONFIG_FILES bin/tests/system/rpz/Makefile" ;; diff --git a/configure.in b/configure.in index c3d7c2ec5f2..0c7efd09638 100644 --- a/configure.in +++ b/configure.in @@ -4588,6 +4588,7 @@ AC_CONFIG_FILES([ bin/tests/system/geoip/Makefile bin/tests/system/inline/checkdsa.sh bin/tests/system/lwresd/Makefile + bin/tests/system/pipelined/Makefile bin/tests/system/resolver/Makefile bin/tests/system/rndc/Makefile bin/tests/system/rpz/Makefile diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 53c504f4d6b..b7dbe4409e7 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -3052,8 +3052,9 @@ $ORIGIN 0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. allow-query-cache-on, allow-transfer, allow-update, - allow-update-forwarding, and - blackhole all use address match + allow-update-forwarding, + blackhole, and + keep-response-order all use address match lists. Similarly, the listen-on option will cause the server to refuse queries on any of the machine's addresses which do not match the list. @@ -4852,6 +4853,7 @@ badresp:1,adberr:0,findfail:0,valfail:0] try-tcp-refresh yes_or_no; allow-v6-synthesis { address_match_list }; blackhole { address_match_list }; + keep-response-order { address_match_list }; no-case-compress { address_match_list }; use-v4-udp-ports { port_list }; avoid-v4-udp-ports { port_list }; @@ -7449,6 +7451,19 @@ options { + + keep-response-order + + + Specifies a list of addresses to which the server + will send responses to TCP queries in the same order + in which they were received. This disables the + processing of TCP queries in parallel. The default + is none. + + + + no-case-compress diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 1bfa23de057..44ead5249c8 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -270,6 +270,21 @@ configuration for a specified zone. + + + Added server-side support for pipelined TCP queries. Multiple + queries from a single client can be received over the same TCP + connection; the connection is no longer closed after the first + query. All queries received over such a connection are handled + in parallel. + + + To revert to the former behavior for a particular + client address or range of addresses, specify the address prefix + in the "keep-response-order" option. To revert to the former + behavior for all clients, use "keep-response order { any; };". + + diff --git a/doc/misc/options b/doc/misc/options index 9a36f080816..2933bee1b4b 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -160,6 +160,7 @@ options { inline-signing ; interface-interval ; ixfr-from-differences ; + keep-response-order { ; ... }; key-directory ; lame-ttl ; listen-on [ port ] [ dscp ] { diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 9afe8117c17..a9fbcd83a85 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -465,8 +465,8 @@ check_viewacls(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions, static const char *acls[] = { "allow-query", "allow-query-on", "allow-query-cache", "allow-query-cache-on", - "blackhole", "match-clients", "match-destinations", - "sortlist", "filter-aaaa", NULL }; + "blackhole", "keep-response-order", "match-clients", + "match-destinations", "sortlist", "filter-aaaa", NULL }; while (acls[i] != NULL) { tresult = checkacl(acls[i++], actx, NULL, voptions, config, diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index c5e73506ab5..1e31209f16d 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -2636,7 +2636,6 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr, isc_result_t result; isc_sockaddr_t peeraddr; isc_sockaddr_t sockname; - isc_sockaddr_t any; unsigned int attributes, mask; isc_boolean_t match = ISC_FALSE; @@ -2644,23 +2643,9 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr, REQUIRE(destaddr != NULL); REQUIRE(dispp != NULL && *dispp == NULL); - attributes = DNS_DISPATCHATTR_TCP; + attributes = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_CONNECTED; mask = DNS_DISPATCHATTR_TCP | DNS_DISPATCHATTR_PRIVATE | - DNS_DISPATCHATTR_EXCLUSIVE; - - if (localaddr == NULL) { - switch (isc_sockaddr_pf(destaddr)) { - case AF_INET: - isc_sockaddr_any(&any); - break; - case AF_INET6: - isc_sockaddr_any6(&any); - break; - default: - return (ISC_R_NOTFOUND); - } - localaddr = &any; - } + DNS_DISPATCHATTR_EXCLUSIVE | DNS_DISPATCHATTR_CONNECTED; LOCK(&mgr->lock); disp = ISC_LIST_HEAD(mgr->list); @@ -2677,7 +2662,8 @@ dns_dispatch_gettcp(dns_dispatchmgr_t *mgr, isc_sockaddr_t *destaddr, &peeraddr); if (result == ISC_R_SUCCESS && isc_sockaddr_equal(destaddr, &peeraddr) && - isc_sockaddr_eqaddr(localaddr, &sockname)) { + (localaddr == NULL || + isc_sockaddr_eqaddr(localaddr, &sockname))) { /* attach */ disp->refcount++; *dispp = disp; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index aff3b113ebb..deefb7ee1fd 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -961,6 +961,7 @@ options_clauses[] = { { "host-statistics-max", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP }, { "hostname", &cfg_type_qstringornone, 0 }, { "interface-interval", &cfg_type_uint32, 0 }, + { "keep-response-order", &cfg_type_bracketed_aml, 0 }, { "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI }, { "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI }, #ifdef ISC_PLATFORM_USESIT diff --git a/util/copyrights b/util/copyrights index a1c921ffbba..e62dd1da1f3 100644 --- a/util/copyrights +++ b/util/copyrights @@ -1576,6 +1576,23 @@ ./bin/tests/system/pending/prereq.sh SH 2009,2012,2014 ./bin/tests/system/pending/setup.sh SH 2009,2012,2014 ./bin/tests/system/pending/tests.sh SH 2009,2010,2012 +./bin/tests/system/pipelined/Makefile.in MAKE 2014 +./bin/tests/system/pipelined/clean.sh SH 2014 +./bin/tests/system/pipelined/input X 2014 +./bin/tests/system/pipelined/inputb X 2014 +./bin/tests/system/pipelined/ns1/named.conf CONF-C 2014 +./bin/tests/system/pipelined/ns1/root.db ZONE 2014 +./bin/tests/system/pipelined/ns2/examplea.db ZONE 2014 +./bin/tests/system/pipelined/ns2/named.conf CONF-C 2014 +./bin/tests/system/pipelined/ns3/exampleb.db ZONE 2014 +./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/ref X 2014 +./bin/tests/system/pipelined/refb X 2014 +./bin/tests/system/pipelined/setup.sh SH 2014 +./bin/tests/system/pipelined/tests.sh SH 2014 ./bin/tests/system/pkcs11/.gitignore X 2012 ./bin/tests/system/pkcs11/clean.sh SH 2010,2012,2014 ./bin/tests/system/pkcs11/ns1/example.db.in ZONE 2010