From 04edbb68b7ba2f2307173016d63e5f8f1026b9eb Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Fri, 8 Feb 2008 10:59:18 +0000 Subject: [PATCH] do multiple queries over TCP. git-svn-id: file:///svn/unbound/trunk@935 be551aaa-1e26-0410-a405-d3ace91eadb9 --- Makefile.in | 13 ++- doc/Changelog | 5 + testcode/streamtcp.c | 239 +++++++++++++++++++++++++++++++++++++++ testdata/stream_tcp.tpkg | Bin 0 -> 2502 bytes util/netevent.c | 6 +- 5 files changed, 256 insertions(+), 7 deletions(-) create mode 100644 testcode/streamtcp.c create mode 100644 testdata/stream_tcp.tpkg diff --git a/Makefile.in b/Makefile.in index 0a2341ea2..fc3aefb2e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -92,13 +92,15 @@ MEMSTATS_SRC=testcode/memstats.c smallapp/worker_cb.c $(COMMON_SRC) MEMSTATS_OBJ=$(addprefix $(BUILD),$(MEMSTATS_SRC:.c=.o)) $(COMPAT_OBJ) ASYNCLOOK_SRC=testcode/asynclook.c ASYNCLOOK_OBJ=$(addprefix $(BUILD),$(ASYNCLOOK_SRC:.c=.o)) $(COMPAT_OBJ) +STREAMTCP_SRC=testcode/streamtcp.c smallapp/worker_cb.c $(COMMON_SRC) +STREAMTCP_OBJ=$(addprefix $(BUILD),$(STREAMTCP_SRC:.c=.o)) $(COMPAT_OBJ) LIBUNBOUND_SRC=$(patsubst $(srcdir)/%,%, \ $(wildcard $(srcdir)/libunbound/*.c) $(COMMON_SRC)) LIBUNBOUND_OBJ=$(addprefix $(BUILD),$(LIBUNBOUND_SRC:.c=.o)) $(COMPAT_OBJ) -ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \ +ALL_SRC=$(sort $(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \ $(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) $(SIGNIT_SRC) \ $(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \ - $(ASYNCLOOK_SRC) + $(ASYNCLOOK_SRC) $(STREAMTCP_SRC)) ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.o) \ $(addprefix compat/,$(LIBOBJS))) $(COMPAT_OBJ) @@ -117,7 +119,8 @@ $(BUILD)%.o: $(srcdir)/%.c all: $(COMMON_OBJ) unbound unbound-checkconf lib unbound-host -tests: all unittest testbound lock-verify pktview signit memstats asynclook +tests: all unittest testbound lock-verify pktview signit memstats \ + asynclook streamtcp test: tests bash testcode/do-tests.sh @@ -177,6 +180,10 @@ asynclook: $(ASYNCLOOK_OBJ) $(ldnslib) libunbound.la $(INFO) Link $@ $Q$(LINK) -o $@ $(sort $(ASYNCLOOK_OBJ)) $(LIBS) -L. -L.libs -lunbound +streamtcp: $(STREAMTCP_OBJ) $(ldnslib) + $(INFO) Link $@ + $Q$(LINK) -o $@ $(sort $(STREAMTCP_OBJ)) $(LIBS) + #testcode/ldns-testpkts.c: $(ldnsdir)/examples/ldns-testpkts.c \ # $(ldnsdir)/examples/ldns-testpkts.h # cp $(ldnsdir)/examples/ldns-testpkts.c testcode/ldns-testpkts.c diff --git a/doc/Changelog b/doc/Changelog index 76dcc0691..ff85eb9a9 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,8 @@ +8 February 2008: Wouter + - test program for multiple queries over a TCP channel. + - tpkg test for stream tcp queries. + - unbound replies to multiple TCP queries on a TCP channel. + 7 February 2008: Wouter - moved up all current level 2 to be level 3. And 3 to 4. to make room for new debug level 2 for detailed information diff --git a/testcode/streamtcp.c b/testcode/streamtcp.c new file mode 100644 index 000000000..6fbeb3904 --- /dev/null +++ b/testcode/streamtcp.c @@ -0,0 +1,239 @@ +/* + * testcode/streamtcp.c - debug program perform multiple DNS queries on tcp. + * + * Copyright (c) 2008, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * \file + * + * This program performs multiple DNS queries on a TCP stream. + */ + +#include "config.h" +#include +#include "util/locks.h" +#include "util/log.h" +#include "util/net_help.h" +#include "util/data/msgencode.h" +#include "util/data/msgreply.h" +#include "util/data/dname.h" + +/** usage information for streamtcp */ +void usage(char* argv[]) +{ + printf("usage: %s [options] name type class ...\n", argv[0]); + printf(" sends the name-type-class queries over TCP.\n"); + printf("-f server what ipaddr@portnr to send the queries to\n"); + printf("-h this help text\n"); + exit(1); +} + +/** open TCP socket to svr */ +static int +open_svr(char* svr) +{ + struct sockaddr_storage addr; + socklen_t addrlen; + int fd = -1; + /* svr can be ip@port */ + if(!extstrtoaddr(svr, &addr, &addrlen)) { + printf("fatal: bad server specs '%s'\n", svr); + exit(1); + } + fd = socket(addr_is_ip6(&addr, addrlen)?PF_INET6:PF_INET, + SOCK_STREAM, 0); + if(fd == -1) { + perror("socket() error"); + exit(1); + } + if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) { + perror("connect() error"); + exit(1); + } + return fd; +} + +/** write a query over the TCP fd */ +static void +write_q(int fd, ldns_buffer* buf, int id, + char* strname, char* strtype, char* strclass) +{ + struct query_info qinfo; + ldns_rdf* rdf; + int labs; + uint16_t len; + /* qname */ + rdf = ldns_dname_new_frm_str(strname); + if(!rdf) { + printf("cannot parse query name: '%s'\n", strname); + exit(1); + } + qinfo.qname = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf)); + labs = dname_count_size_labels(qinfo.qname, &qinfo.qname_len); + ldns_rdf_deep_free(rdf); + if(!qinfo.qname) fatal_exit("out of memory"); + + /* qtype and qclass */ + qinfo.qtype = ldns_get_rr_type_by_name(strtype); + qinfo.qclass = ldns_get_rr_class_by_name(strclass); + + /* make query */ + qinfo_query_encode(buf, &qinfo); + ldns_buffer_write_u16_at(buf, 0, (uint16_t)id); + ldns_buffer_write_u16_at(buf, 2, BIT_RD); + + /* send it */ + len = (uint16_t)ldns_buffer_limit(buf); + len = htons(len); + if(write(fd, &len, sizeof(len)) < (ssize_t)sizeof(len)) { + perror("write() len failed"); + exit(1); + } + if(write(fd, ldns_buffer_begin(buf), ldns_buffer_limit(buf)) < + (ssize_t)ldns_buffer_limit(buf)) { + perror("write() data failed"); + exit(1); + } + + free(qinfo.qname); +} + +/** receive DNS datagram over TCP and print it */ +static void +recv_one(int fd, ldns_buffer* buf) +{ + uint16_t len; + ldns_pkt* pkt; + ldns_status status; + if(read(fd, &len, sizeof(len)) < (ssize_t)sizeof(len)) { + perror("read() len failed"); + exit(1); + } + len = ntohs(len); + ldns_buffer_clear(buf); + ldns_buffer_set_limit(buf, len); + if(read(fd, ldns_buffer_begin(buf), len) < (ssize_t)len) { + perror("read() data failed"); + exit(1); + } + printf("\nnext received packet\n"); + log_buf(0, "data", buf); + + status = ldns_wire2pkt(&pkt, ldns_buffer_begin(buf), len); + if(status != LDNS_STATUS_OK) { + printf("could not parse incoming packet: %s\n", + ldns_get_errorstr_by_id(status)); + log_buf(0, "data was", buf); + exit(1); + } + ldns_pkt_print(stdout, pkt); + ldns_pkt_free(pkt); +} + +/** send the TCP queries and print answers */ +static void +send_em(char* svr, int num, char** qs) +{ + ldns_buffer* buf = ldns_buffer_new(65553); + int fd = open_svr(svr); + int i; + if(!buf) fatal_exit("out of memory"); + for(i=0; if0>zc`M&Sm&x!IK*K@eOx9zq1ieWlA@+hDJ<#I82mKG+S zA&91yiv=}bD(CY=)d~v>CBll2#F_*KuBSVUk)b{CxHCK5QSl#AxRdQ4`}DZ$os16A zz@1F{5B#ecN`J zX)*sDfu_C#m3`fHO{){Cn#?evWg?2wjYe%bEmSLMdZYSEZFx`MjMBH8yC9-JBPwEHJwn@*m43>eUC6*BpVTGZ-&QlbjZ90(Ti_@7f66Q8nHrSm3 zclH&^TV0!_E5Rol4u=ZAr|Ruu2HdjUL7t<_jai&H^3hdzbOb_vPX`I14qV6VDlK zE57r|fI>Xr_>G@bF%F(kBzwxE?>1c2w zL`)xD$F?B|Gpdl_So$6hz6?8yxhLz-ui2j6(tBOo^?cdbCJc4Q$bQqdI7$%a!GfBK zVsyiB5Hy}qFE`hHJJZQ=@T6k)_&40v3F$a${4bPBKE{zt<;(7=S zKMm}tuddx-WknMo&lB>q>{~DY^Sw>-M*hKz+|hB$wR#r!disuww;AbP4+Q31r={uul=sDPgY|Me^(e+J(J-v#f3KL>vb{s{aY z_+4-p+y)!q74RkS8Svj9C*&XC-@reC?}L8?e+#|~z5~7iegypc#}E#_4Za2b1pEQ` zI(Qen1AYa(1y;c#cnH{h?q``|CYAA;Wp-vsY~CfEi!SOrU<28ur> z{4Drs@KZFbO9=@H2?+@ai4O+?Cn0QeOcMGIkx7>#BHWC~*zJfsfS1xS#U*{HjwdbY z-$kZ+hLME-7>PTVk(k#Rnd+Aom^jUqEi!Sc`AJtfGT})_;!bvCx+C5+t)c54ndR+zmq-X#Cys^G`=F*@^Hs$oZ@D>W&8Cy_TeUnyL*$dV>pTV zixcv2&gSHyz1hkC>Nrmx#yx+wm;Vv>KUnTbEGkF&f0c_P|F6=5@DtI>YAG-MKTZQn zOt?)3UZ6o2^?j)`>y5RSF<|2Zl4hFC>#R^xRZ461X5+Q(D>bB{H>%B*Ys~JqY=g5q z-hLlHg;3h4ZCrni-E6RGmDSg4jmCO|R#(5Ywb^7XyT89}8g#R^(p+1wvzuGBP4Pl8 z3#8WSsp=@ETHm}?YmCBEvH3Z)qE=shviP|KffWnI1$O>C zjqh2OGf`rC_0~AoC=}T=WLe*8j^d(p7eqv`otcyv|4Oq;C23!fXRI!Io0e9z3HqvE zLBhKo^@rrO#&XZF+-$I1kM8t1BkCy~Zgnz#y4&gK(ug2iu50h{TaT%PLzEPj+cpY|5itLEwc87<70wY??}q zw&ZP=(ZmpL2Pd!$4*UqHBmJEKRMbr+Oa(4-D=(%Ir zA{zbRPTZ8FxXqxp(8SPcn1+80@+o(?vsc1`uPBzr&_?JGAB|V`q>Zw!J zZTkJ*Zu_0cZ1I`e;vGBfCUT{x?KLF+|8U6u&pxI5|8UkjaQ{zHEzAAiY2e`g&pze* z|6*FAE#F}}9(d~~N?_P*ACVA@3DzE3%ol`+U9;B{^Cc|sU!%=Qv=MO!NH-A^TaSX< z(;_M1JQ${qt=v;&#bOW0n|?o+goK2IgoK2IgoK2IgoK2IgoK2IgoK2IgoK2IgoK2I Qgv4R^FHX`IF93J|0O2A7IRF3v literal 0 Hc-jL100001 diff --git a/util/netevent.c b/util/netevent.c index 832cf948a..c72dc9d11 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -521,11 +521,9 @@ tcp_callback_writer(struct comm_point* c) if(c->tcp_do_toggle_rw) c->tcp_is_reading = 1; c->tcp_byte_count = 0; + /* switch from listening(write) to listening(read) */ comm_point_stop_listening(c); - if(c->tcp_parent) /* for listening socket */ - reclaim_tcp_handler(c); - else /* its outgoing socket, start listening for reading */ - comm_point_start_listening(c, -1, -1); + comm_point_start_listening(c, -1, -1); } /** do the callback when reading is done */ -- 2.47.2