]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
delay test program.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 22 Feb 2008 15:40:50 +0000 (15:40 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Fri, 22 Feb 2008 15:40:50 +0000 (15:40 +0000)
git-svn-id: file:///svn/unbound/trunk@988 be551aaa-1e26-0410-a405-d3ace91eadb9

Makefile.in
doc/Changelog
testcode/delayer.c [new file with mode: 0644]

index 9407c10f2039e5de24cc329ddf93dcfeaa3b90a7..d742a1a82e24108e6a2b6384537a5899148173c4 100644 (file)
@@ -96,13 +96,15 @@ STREAMTCP_SRC=testcode/streamtcp.c smallapp/worker_cb.c $(COMMON_SRC)
 STREAMTCP_OBJ=$(addprefix $(BUILD),$(STREAMTCP_SRC:.c=.o)) $(COMPAT_OBJ)
 PERF_SRC=testcode/perf.c smallapp/worker_cb.c $(COMMON_SRC)
 PERF_OBJ=$(addprefix $(BUILD),$(PERF_SRC:.c=.o)) $(COMPAT_OBJ)
+DELAYER_SRC=testcode/delayer.c smallapp/worker_cb.c $(COMMON_SRC)
+DELAYER_OBJ=$(addprefix $(BUILD),$(DELAYER_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=$(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) $(STREAMTCP_SRC) $(PERF_SRC))
+       $(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC))
 ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.o) \
        $(addprefix compat/,$(LIBOBJS))) $(COMPAT_OBJ)
 
@@ -122,7 +124,7 @@ $(BUILD)%.o:    $(srcdir)/%.c
 all:   $(COMMON_OBJ) unbound unbound-checkconf lib unbound-host
 
 tests: all unittest testbound lock-verify pktview signit memstats \
-       asynclook streamtcp perf
+       asynclook streamtcp perf delayer
 
 test:  tests
        bash testcode/do-tests.sh
@@ -190,6 +192,10 @@ perf:      $(PERF_OBJ) $(ldnslib)
        $(INFO) Link $@
        $Q$(LINK) -o $@ $(sort $(PERF_OBJ)) $(LIBS)
 
+delayer:       $(DELAYER_OBJ) $(ldnslib)
+       $(INFO) Link $@
+       $Q$(LINK) -o $@ $(sort $(DELAYER_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
index 8e91bf0825cfe640248ea2a75cfcbc7d74e4087b..47d47805b1df59ae1502efe1e27ba35cd16a2265 100644 (file)
@@ -17,6 +17,7 @@
          www with DO bit set : BIND 8269.31 Ub 28735.6 qps.
          So, unbound can be about equal qps to NSD in cache hits.
          And about 3.4x faster than BIND in cache performance.
+       - delay utility for testing.
 
 21 February 2008: Wouter
        - speedup of root-delegation message encoding by 15%.
diff --git a/testcode/delayer.c b/testcode/delayer.c
new file mode 100644 (file)
index 0000000..688f281
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * testcode/delayer.c - debug program that delays queries to a server.
+ *
+ * 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 delays queries made. It performs as a proxy to another
+ * server and delays queries to it.
+ */
+
+#include "config.h"
+#include "util/net_help.h"
+#include "util/config_file.h"
+#include <signal.h>
+
+/**
+ * The ring buffer
+ */
+struct ringbuf {
+       /** base of buffer */
+       uint8_t* buf;
+       /** size of buffer */
+       size_t size;
+       /** low mark, items start here */
+       size_t low;
+       /** high mark, items end here */
+       size_t high;
+};
+
+/** usage information for delayer */
+void usage(char* argv[])
+{
+       printf("usage: %s [options]\n", argv[0]);
+       printf("        -f addr : use addr, forward to that server, @port.\n");
+       printf("        -b addr : bind to this address to listen.\n");
+       printf("        -p port : bind to this port (0 for random).\n");
+       printf("        -m mem  : use this much memory for waiting queries.\n");
+       printf("        -d delay: queries are delayed n milliseconds.\n");
+       printf("        -h      : this help message\n");
+       exit(1);
+}
+
+/** create new ring buffer */
+static struct ringbuf*
+ring_create(size_t sz)
+{
+       struct ringbuf* r = (struct ringbuf*)calloc(1, sizeof(*r));
+       if(!r) fatal_exit("out of memory");
+       r->buf = (uint8_t*)malloc(sz);
+       if(!r->buf) fatal_exit("out of memory");
+       r->size = sz;
+       r->low = 0;
+       r->high = 0;
+       return r;
+}
+
+/** delete ring buffer */
+static void
+ring_delete(struct ringbuf* r)
+{
+       if(!r) return;
+       free(r->buf);
+       free(r);
+}
+
+/** signal handler global info */
+static volatile int do_quit = 0;
+
+/** signal handler for user quit */
+static RETSIGTYPE delayer_sigh(int sig)
+{
+       printf("exit on signal %d\n", sig);
+       do_quit = 1;
+}
+
+/** delayer main service routine */
+static void
+service(char* bind_str, int bindport, char* serv_str, size_t memsize, 
+       int delay_msec)
+{
+       struct sockaddr_storage bind_addr, srv_addr;
+       socklen_t bind_len, srv_len;
+       struct ringbuf* ring = ring_create(memsize);
+       struct timeval delay;
+       int s;
+       delay.tv_sec = delay_msec / 1000;
+       delay.tv_usec = (delay_msec % 1000)*1000;
+       if(bindport == 0)
+               bindport = 1024 + random()%64000;
+       if(!ipstrtoaddr(bind_str, bindport, &bind_addr, &bind_len)) {
+               printf("cannot parse listen address: %s\n", bind_str);
+               exit(1);
+       }
+       if(!extstrtoaddr(serv_str, &srv_addr, &srv_len)) {
+               printf("cannot parse forward address: %s\n", serv_str);
+               exit(1);
+       }
+       if( signal(SIGINT, delayer_sigh) == SIG_ERR ||
+               signal(SIGTERM, delayer_sigh) == SIG_ERR ||
+               signal(SIGHUP, delayer_sigh) == SIG_ERR ||
+               signal(SIGQUIT, delayer_sigh) == SIG_ERR ||
+               signal(SIGALRM, delayer_sigh) == SIG_ERR)
+               fatal_exit("could not bind to signal");
+       /* bind UDP port */
+       if((s = socket(addr_is_ip6(&bind_addr, bind_len)?AF_INET6:AF_INET,
+               SOCK_DGRAM, 0)) == -1)
+               fatal_exit("socket: %s", strerror(errno));
+       if(bind(s, (struct sockaddr*)&bind_addr, bind_len) == -1)
+               fatal_exit("bind: %s", strerror(errno));
+       printf("listening on port: %d\n", bindport);
+
+       /* process loop */
+       /* wait for events */
+       while(!do_quit) {
+               /* get current time */
+               /* sendout delayed queries to master server (frees up buffer)*/
+               /* see what can be received to start waiting */
+               /* see what next timeout is (if any) */
+       }
+       /* cleanup */
+       close(s);
+       ring_delete(ring);
+}
+
+/** getopt global, in case header files fail to declare it. */
+extern int optind;
+/** getopt global, in case header files fail to declare it. */
+extern char* optarg;
+
+/** main program for delayer */
+int main(int argc, char** argv) 
+{
+       int c;          /* defaults */
+       char* server = "127.0.0.1@53";
+       char* bindto = "0.0.0.0";
+       int bindport = 0;
+       size_t memsize = 10*1024*1024;
+       int delay = 100;
+
+       srandom(time(NULL) ^ getpid());
+       while( (c=getopt(argc, argv, "b:d:f:hm:p:")) != -1) {
+               switch(c) {
+                       case 'b':
+                               bindto = optarg;
+                               break;
+                       case 'd':
+                               if(atoi(optarg)==0 && strcmp(optarg,"0")!=0) {
+                                       printf("bad delay: %s\n", optarg);
+                                       return 1;
+                               }
+                               delay = atoi(optarg);
+                               break;
+                       case 'f':
+                               server = optarg;
+                               break;
+                       case 'm':
+                               if(!cfg_parse_memsize(optarg, &memsize)) {
+                                       printf("bad memsize: %s\n", optarg);
+                                       return 1;
+                               }
+                               break;
+                       case 'p':
+                               if(atoi(optarg)==0 && strcmp(optarg,"0")!=0) {
+                                       printf("bad port nr: %s\n", optarg);
+                                       return 1;
+                               }
+                               bindport = atoi(optarg);
+                               break;
+                       case 'h':
+                       case '?':
+                       default:
+                               usage(argv);
+               }
+       }
+       argc -= optind;
+       argv += optind;
+       if(argc != 0)
+               usage(argv);
+
+       printf("bind to %s @ %d and forward to %s\n"
+               "after %d msec (buffer %d)\n", 
+               bindto, bindport, server, delay, (int)memsize);
+       service(bindto, bindport, server, memsize, delay);
+       return 0;
+}