summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2013-06-28 12:59:40 +0200
committerOndřej Surý <ondrej@sury.org>2013-06-28 12:59:40 +0200
commit124965832295a277b9ca6ae9fac4f45a74a36b2a (patch)
treef299e2335863f74e0be0707f84b85211baaf2d03 /tests
parent3d2d198c71a6b844b60fa9ef68801b66bba93361 (diff)
downloadknot-upstream/1.3.0_rc3.tar.gz
New upstream version 1.3.0~rc3upstream/1.3.0_rc3
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile16
-rw-r--r--tests/chkjournal.c541
-rw-r--r--tests/querytcp.c797
3 files changed, 0 insertions, 1354 deletions
diff --git a/tests/Makefile b/tests/Makefile
deleted file mode 100644
index bd3e9aa..0000000
--- a/tests/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-BASE = ../src
-CFLAGS += -std=gnu99 -g -I.. -I$(BASE) -I$(BASE)/libknot -I/usr/local/include
-
-chkjournal: chkjournal.c $(BASE)/libknotd.la
- libtool --mode=link $(CC) $(CFLAGS) chkjournal.c $(BASE)/libknotd.la -o chkjournal
-chkjournal-i386:
- @echo "!!! Make sure knot is compiled with -fpack-struct=4"
- @grep -q -- "-fpack-struct=4" $(BASE)/Makefile || exit 1
- libtool --mode=link $(CC) $(CFLAGS) -fpack-struct=4 chkjournal.c $(BASE)/libknotd.la -o chkjournal-i386
-chkjournal-amd64:
- @echo "!!! Make sure knot is compiled with -fpack-struct=8"
- @grep -q -- "-fpack-struct=8" $(BASE)/Makefile || exit 1
- libtool --mode=link $(CC) $(CFLAGS) -fpack-struct=8 chkjournal.c $(BASE)/libknotd.la -o chkjournal-amd64
-clean:
- rm chkjournal chkjournal-i386 chkjournal-amd64
-
diff --git a/tests/chkjournal.c b/tests/chkjournal.c
deleted file mode 100644
index b429a87..0000000
--- a/tests/chkjournal.c
+++ /dev/null
@@ -1,541 +0,0 @@
-/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- Usage: chkjournal --help
-
- How to make:
- (for this computer): make chkjournal
- (for 32bit journals): make chkjournal-i386
- (for 64bit journal): make chkjournal-amd64
-
- !!! For specific versions, make sure the libknotd.la is compiled
- with -fpack-struct=4 for 32bit or -fpack-struct=8 for 64bit chkjournal.
- f.e.:
- $ cd <knot_root>
- $ CFLAGS="-fpack-struct=4" ./configure
- $ make clean && make -j8
- $ cd tests
- $ make chkjournal-i386
- */
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#include <assert.h>
-#include <sys/stat.h>
-
-#ifndef KNOT_RRSET_DEBUG
-#define KNOT_RRSET_DEBUG 1
-#endif
-
-//#define KNOT_RDATA_DEBUG 1
-#include "src/common/log.h"
-#include "src/common/crc.h"
-#include "src/common/errcode.h"
-#include "src/knot/server/journal.h"
-#include "src/knot/server/zones.h"
-#include "src/libknot/updates/changesets.h"
-#include "src/libknot/util/debug.h"
-#include "src/libknot/util/debug.c"
-#include "config.h"
-
-/* Alignment. */
-static size_t ALIGNMENT = 1;
-static inline size_t a(size_t s) {
- return s + s % ALIGNMENT;
-}
-static size_t PADDING = 4;
-
-/*! \brief Return 'serial_from' part of the key. */
-static inline uint32_t ixfrdb_key_from(uint64_t k)
-{
- /* 64 32 0
- * key = [TO | FROM]
- * Need: Least significant 32 bits.
- */
- return (uint32_t)(k & ((uint64_t)0x00000000ffffffff));
-}
-
-/*----------------------------------------------------------------------------*/
-
-/*! \brief Return 'serial_to' part of the key. */
-static inline uint32_t ixfrdb_key_to(uint64_t k)
-{
- /* 64 32 0
- * key = [TO | FROM]
- * Need: Most significant 32 bits.
- */
- return (uint32_t)(k >> (uint64_t)32);
-}
-
-/*----------------------------------------------------------------------------*/
-
-#define MAGIC_LENGTH 7
-
-enum {
- SHOW = 0,
- UPDATE,
- FIXCRC,
- DUMP,
- XDUMP
-};
-
-void help(int argc, char **argv)
-{
- printf("Usage: chkjournal [parameters] <journal_file>\n");
- printf("Parameters:\n"
- " -p, --padding=N Padding after each node.\n"
- " -a, --align=N Expect journal structures aligned to N bytes.\n"
- " -f, --fixcrc Recompute CRC32.\n"
- " -u, --update Update version to latest.\n"
- " -x, --xdump=id Dump changeset (hexdump).\n"
- " -d, --dump=id Dump changeset (parsed).\n"
- " -h, --help Print help and usage.\n"
- );
-}
-
-/* Show. */
-int walkf(journal_t *j, journal_node_t *n) {
- printf("entry '%zu' flags=0x%hu fpos=%u len=%u\n", n->id, n->flags, n->pos, n->len);
- return 0;
-}
-
-int show(const char *fname)
-{
- /* Open journal. */
- journal_t *j = journal_open(fname, -1, 0, 0);
- if (j == NULL) {
- fprintf(stderr, "error: couldn't open journal '%s'\n", fname);
- return 1;
- }
-
- printf("journal: %s max_nodes=%hu queue=%u..%u\n",
- fname, j->max_nodes, j->qtail, j->qhead);
- journal_walk(j, walkf);
- journal_close(j);
- return 0;
-}
-
-/* Fix CRC. */
-int fixcrc(const char *fname)
-{
- int fd = open(fname, O_RDONLY);
- if (fd < 0) {
- return 1;
- }
-
- int ret = 1;
- if (journal_update_crc(fd) == 0) {
- ret = 0;
- }
-
- close(fd);
- return ret;
-}
-
-/* Fix file positions. */
-static int FPOSDELTA = 0;
-int walkfix(journal_t *j, journal_node_t *n) {
- n->pos += FPOSDELTA;
- journal_update(j, n);
- return 0;
-}
-
-int fixfpos(const char *fname, int delta)
-{
- /* Open journal. */
- journal_t *j = journal_open(fname, -1, 0, 0);
- if (j == NULL) {
- fprintf(stderr, "error: couldn't open journal '%s'\n", fname);
- return 1;
- }
- FPOSDELTA = delta;
- journal_walk(j, walkfix);
- journal_close(j);
- return 0;
-}
-
-/* Update journal file. */
-int update(const char *fname)
-{
- int fd = open(fname, O_RDONLY);
- if (fd < 0) {
- return 1;
- }
-
- /* Check source magic bytes. */
- int rb = 0;
- int ret = 0;
- char buf[4096];
- char mbytes[MAGIC_LENGTH] = {};
- read(fd, mbytes, MAGIC_LENGTH);
- if (memcmp(mbytes, "knot100", MAGIC_LENGTH) == 0) {
- /* 100 -> 101 +crc after MB. */
- char *nfname = malloc(strlen(fname) + 4 + 1);
- assert(nfname != NULL);
- strncpy(nfname, fname, strlen(fname));
- strncat(nfname, ".new", 4);
- int nfd = open(nfname, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
- const char nmbytes[] = "knot101";
- if (nfd >= 0) {
- /* Extend header. */
- write(nfd, nmbytes, MAGIC_LENGTH);
- write(nfd, buf, sizeof(crc_t));
- read(fd, buf, sizeof(uint16_t) * 3);
- write(nfd, buf, sizeof(uint16_t) * 3);
-
- /* Copy nodes. */
- uint16_t ncount = *((uint16_t*)buf) + 1;
- printf("Will update %hu nodes.\n", ncount - 1);
- for (uint16_t i = 0; i < ncount; ++i) {
- /* Copy id+flags. */
- read(fd, buf, a(sizeof(uint64_t)+sizeof(uint16_t)));
- write(nfd, buf, a(sizeof(uint64_t)+sizeof(uint16_t)));
- read(fd, buf, a(2*sizeof(uint32_t)));
- *((uint32_t*)buf) += sizeof(crc_t);
- write(nfd, buf, a(2*sizeof(uint32_t)));
- /* Copy padding. */
- read(fd, buf, PADDING);
- write(nfd, buf, PADDING);
- }
-
- /* Copy remaining. */
- while((rb = read(fd, buf, sizeof(buf))) > 0) {
- if (write(nfd, buf, rb) != rb) {
- ret = 1;
- break;
- }
- }
- /* Update CRC. */
- if (ret == 0) {
- journal_update_crc(nfd);
- }
- }
-
- /* Replace if success. */
- close(nfd);
- close(fd);
- if (ret == 0) {
- remove(fname);
- rename(nfname, fname);
- printf("Converted journal v1.0.0 -> v1.0.1\n");
- }
- free(nfname);
- } else if (memcmp(mbytes, "knot101", MAGIC_LENGTH) == 0) {
- /* 101 -> 102, transactions, +uint16 'next' in jnode */
- char *nfname = malloc(strlen(fname) + 4 + 1);
- assert(nfname != NULL);
- strncpy(nfname, fname, strlen(fname));
- strncat(nfname, ".new", 4);
- int nfd = open(nfname, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
- size_t hs102 = (MAGIC_LENGTH + sizeof(crc_t) + sizeof(uint16_t) * 3);
- const char nmbytes[] = "knot102";
-
- if (nfd >= 0) {
- /* Copy header. */
- lseek(fd, 0, SEEK_SET);
- read(fd, buf, hs102);
- write(nfd, buf, hs102);
- lseek(nfd, 0, SEEK_SET);
- write(nfd, nmbytes, MAGIC_LENGTH);
-
- /* Read node count. */
- lseek(fd, MAGIC_LENGTH + sizeof(crc_t), SEEK_SET);
- uint16_t ncount = 0;
- read(fd, &ncount, sizeof(uint16_t));
- printf("Will update %hu nodes.\n", ncount);
- ncount += 1; /* Free segment. */
- lseek(fd, hs102, SEEK_SET);
- lseek(nfd, hs102, SEEK_SET);
-
- /* Extend nodes. */
- /*! \todo Calculate offset from difference of struct size. */
- for (uint16_t i = 0; i < ncount; ++i) {
- /* Copy id+flags. */
- read(fd, buf, a(sizeof(uint64_t)+sizeof(uint16_t)));
- write(nfd, buf, sizeof(uint64_t)+sizeof(uint16_t));
- /* Append 'next'. */
- memset(buf, 0, sizeof(uint16_t));
- write(nfd, buf, sizeof(uint16_t));
-
- /* Copy rest. */
- read(fd, buf, a(2*sizeof(uint32_t)));
- //*((uint32_t*)buf) += offs;
- write(nfd, buf, a(2*sizeof(uint32_t)));
- /* Copy padding. */
- read(fd, buf, PADDING);
- write(nfd, buf, PADDING);
- }
-
- /* Copy remaining. */
- while((rb = read(fd, buf, sizeof(buf))) > 0) {
- if (write(nfd, buf, rb) != rb) {
- ret = 1;
- break;
- }
- }
- /* Update CRC. */
- if (ret == 0) {
- journal_update_crc(nfd);
- }
- }
-
- /* Replace if success. */
- close(nfd);
- close(fd);
- if (ret == 0) {
- remove(fname);
- rename(nfname, fname);
- printf("Converted journal v1.0.1-> v1.0.2\n");
- }
- free(nfname);
- } else if (memcmp(mbytes, "knot102", MAGIC_LENGTH) == 0) {
- /* Update magic bytes. */
- const char nmbytes[] = "knot104";
- int nfd = open(fname, O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
- lseek(nfd, 0, SEEK_SET);
- write(nfd, nmbytes, MAGIC_LENGTH);
- journal_update_crc(nfd);
- close(nfd);
- printf("Converted journal v1.0.2-> v.1.0.4\n");
- } else if (memcmp(mbytes, "knot104", MAGIC_LENGTH) == 0) {
- /* Update magic bytes and add 4bytes to each journal node. */
- const char nmbytes[] = "knot105";
- int nfd = open(fname, O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
- lseek(nfd, 0, SEEK_SET);
- write(nfd, nmbytes, MAGIC_LENGTH);
- journal_update_crc(nfd);
- close(nfd);
-
- /* Fix crc. */
- fixcrc(fname);
-
- /* Open as source journal. */
- journal_t *src = journal_open(fname, 0, 0, 0);
- assert(src != NULL);
-
- /* Recreate as new journal. */
- char *nfname = malloc(strlen(fname) + 4 + 1);
- assert(nfname != NULL);
- strncpy(nfname, fname, strlen(fname));
- strncat(nfname, ".new", 4);
- journal_create(nfname, src->max_nodes);
- journal_t *dst = journal_open(nfname, 0, 0, 0);
- assert(dst != NULL);
-
- /* Convert journal entries, adding dummy flags. */
- uint32_t flags = 1;
- size_t i = src->qhead;
- for(; i != src->qtail; i = (i + 1) % src->max_nodes) {
- journal_node_t *n = src->nodes + i;
- char *ibuf = malloc(n->len + sizeof(uint32_t));
- memset(ibuf, &flags, sizeof(uint32_t));
- journal_read(src, n->id, NULL, ibuf + sizeof(uint32_t));
- journal_write(dst, n->id, ibuf, n->len + sizeof(uint32_t));
- free(ibuf);
- }
- journal_close(src);
- journal_close(dst);
-
- /* Switch journals. */
- remove(fname);
- rename(nfname, fname);
- free(nfname);
- printf("Converted journal v1.0.4-> v.1.0.5\n");
- } else {
- close(fd);
- }
-
-
- return ret;
-}
-
-/* Hexdump. */
-int xdump(const char *fname, uint64_t id)
-{
- /* Open journal. */
- journal_t *j = journal_open(fname, -1, 0, 0);
- if (j == NULL) {
- fprintf(stderr, "error: couldn't open journal '%s'\n", fname);
- return 1;
- }
-
- int ret = 1;
- journal_node_t *n = NULL;
- journal_fetch(j, id, NULL, &n);
- if (n != NULL) {
- char *buf = malloc(n->len);
- assert(buf != NULL);
- journal_read(j, id, NULL, buf);
- size_t rf = 0;
- while(rf < n->len) {
- if (rf % 16 == 0) printf("\n%08lx |", (unsigned long)rf);
- printf(" %02x", (unsigned)buf[rf] & 0xffU);
- ++rf;
- }
- printf("\n");
- printf("-- index %llu fpos=%u length=%u\n",
- (unsigned long long)id, n->pos, n->len);
- free(buf);
- ret = 0;
- }
-
- journal_close(j);
- return ret;
-}
-
-/* Hexdump. */
-int dump(const char *fname, uint64_t id)
-{
- /* Open journal. */
- journal_t *j = journal_open(fname, -1, 0, 0);
- if (j == NULL) {
- fprintf(stderr, "error: couldn't open journal '%s'\n", fname);
- return 1;
- }
-
- journal_node_t *n = NULL;
- journal_fetch(j, id, NULL, &n);
- if (n == NULL) {
- journal_close(j);
- return 1;
- }
-
- /* Reserve and read changeset. */
- knot_changesets_t* chsets = malloc(sizeof(knot_changesets_t));
- assert(chsets != NULL);
- memset(chsets, 0, sizeof(knot_changesets_t));
- chsets->count = 1;
- knot_changesets_check_size(chsets);
- assert(chsets->sets != NULL);
- knot_changeset_t *chs = chsets->sets;
- memset(chs, 0, sizeof(knot_changeset_t));
- chs->serial_from = ixfrdb_key_from(n->id);
- chs->serial_to = ixfrdb_key_to(n->id);
- chs->data = malloc(n->len);
- assert(chs->data != NULL);
- journal_read(j, n->id, NULL, chs->data);
- chs->size = chs->allocated = n->len;
-
- /* Unpack */
- int ks = zones_changesets_from_binary(chsets);
- printf("=== index %llu fpos=%u length=%u\n",
- (unsigned long long)id, n->pos, n->len);
-
- /* TODO: dump wireformat? */
- printf("--- %zu records\n", chs->remove_count);
- for (unsigned i = 0; i < chs->remove_count; ++i) {
- knot_rrset_dump(chs->remove[i], 1);
- }
- printf("+++ %zu records\n", chs->add_count);
- for (unsigned i = 0; i < chs->add_count; ++i) {
- knot_rrset_dump(chs->add[i], 1);
- }
- printf("=== index %llu fpos=%u length=%u\n",
- (unsigned long long)id, n->pos, n->len);
-
- /* Close. */
- //knot_free_changesets(&chsets);
- journal_close(j);
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
- /* Long options. */
- struct option opts[] = {
- {"padding",required_argument, 0, 'p'},
- {"align", required_argument, 0, 'a'},
- {"fixcrc", no_argument, 0, 'f'},
- {"update", no_argument, 0, 'u'},
- {"dump", required_argument, 0, 'd'},
- {"xdump", required_argument, 0, 'x'},
- {"help", no_argument, 0, 'h'},
- {0, 0, 0, 0}
- };
-
- int c = 0, li = 0;
- int action = SHOW;
- uint64_t dump_id = 0;
- while ((c = getopt_long(argc, argv, "p:a:fuhd:x:", opts, &li)) != -1) {
- switch (c)
- {
- case 'p':
- PADDING = strtoull(optarg, NULL, 10);
- break;
- case 'a':
- ALIGNMENT = strtoull(optarg, NULL, 10);
- break;
- case 'f':
- action = FIXCRC;
- break;
- case 'u':
- action = UPDATE;
- break;
- case 'd':
- action = DUMP;
- dump_id = strtoull(optarg, NULL, 10);
- break;
- case 'x':
- action = XDUMP;
- dump_id = strtoull(optarg, NULL, 10);
- break;
- case 'h':
- case '?':
- default:
- help(argc, argv);
- return 1;
- }
- }
-
- /* Check if there's at least one remaining non-option. */
- if (argc - optind < 1) {
- help(argc, argv);
- return 1;
- }
- const char *fname = argv[optind];
-
- /* Init log. */
- log_init();
- log_levels_set(LOGT_SYSLOG, LOG_ANY, 0);
- log_levels_set(LOGT_STDERR, LOG_ANY, 0);
- log_levels_set(LOGT_STDOUT, LOG_ANY, ~0);
-
- /* Execute operation. */
- int ret = 0;
- switch(action) {
- case SHOW:
- ret = show(fname);
- break;
- case UPDATE:
- ret = update(fname);
- break;
- case FIXCRC:
- ret = fixcrc(fname);
- break;
- case DUMP:
- ret = dump(fname, dump_id);
- break;
- case XDUMP:
- ret = xdump(fname, dump_id);
- break;
- default:
- fprintf(stderr, "Unsupported operation.\n");
- break;
- }
-
- return ret;
-}
diff --git a/tests/querytcp.c b/tests/querytcp.c
deleted file mode 100644
index 7e1418f..0000000
--- a/tests/querytcp.c
+++ /dev/null
@@ -1,797 +0,0 @@
-/*
-TCP query version of queryperf
-querytcp.c
- fujiwara@jprs.co.jp
- 2009.08.12
- version 0.4
-
-queryperf for tcp query
-
-This program measures DNS server performance of TCP query.
-
-o Running environment:
- Development environment:
- Linux
- FreeBSD
- MacOS X 10.3.4
-
-o How to make:
- Linux: gcc -D_LINUX -Wall -O2 -g -lm -o querytcp querytcp.c
- FreeBSD: gcc -Wall -O2 -g -lm -o querytcp querytcp.c
- MacOS X: gcc -Wall -O2 -g -lm -lresolv -o querytcp querytcp.c
-
-o changes
-
- 2010/6/7: Linux compatibility
- 2009/8/12: Remove use of res_mkquery
-*/
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <netdb.h>
-#include <errno.h>
-#include <math.h>
-#include <err.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <math.h>
-#ifndef NO_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-
-#ifdef __APPLE__
-#include <nameser8_compat.h>
-#endif
-
-#ifndef ns_t_soa
-#define ns_t_soa T_SOA
-#endif
-#ifndef ns_t_ns
-#define ns_t_ns T_NS
-#endif
-#ifndef ns_c_in
-#define ns_c_in C_IN
-#endif
-
-#ifdef NOINET6
-#undef AF_INET6
-#endif
-
-#define Global
-
-#ifndef PACKETSZ
-#define PACKETSZ 512
-#endif
-
-/* debug.c */
-void hexdump(char *title, unsigned char *memory, int len)
-{
- printf("[ %s ", title);
- while (len-- > 0)
- printf("%02x ", *memory++);
- printf("]\n");
-}
-
-#define Xmalloc(size) Xrealloc(NULL, size)
-
-void *Xrealloc(void *p, int size)
-{
- int sz;
-
- sz = (size > 0) ? size : -size;
- if (p == NULL) {
- p = malloc(sz);
- } else {
- p = realloc(p, sz);
- }
- if (p == NULL) {
- char buf[100];
- snprintf(buf, sizeof buf, "size=%d", size);
- perror(buf);
- exit(1);
- }
- if (size < 0)
- memset(p, 0, sz);
- return p;
-}
-
-/* strlcpy() emulation for Linux. */
-#ifdef _LINUX
-static inline size_t strlcpy(char *destination, const char *source, size_t size)
-{
- if(strncpy(destination, source, size) == NULL)
- return 0;
-
- return size;
-}
-#endif
-
-/*
- NULL ... returns NULL
- */
-char *Xstrdup(char *p)
-{
- char *q;
- int len;
-
- if (p == NULL)
- return NULL;
- len = strlen(p) + 1;
- q = Xmalloc(len);
- strlcpy(q, p, len);
- return q;
-}
-
-
-typedef int64_t timediff_t;
-
-/* packet buffer */
-static struct timeval current;
-static struct timeval start, send_finished;;
-static fd_set fdset0r, fdset0w;
-static int nfds;
-static struct sockaddr_storage remote;
-static int remote_len = 0;
-static int finished = 0;
-static timediff_t Timeout = 10*1000000LL;
-unsigned short counter = 0;
-
-#define UpdateCurrentTime gettimeofday(&current, NULL)
-
-#define RECVBUFSIZ 65537
-#define SENDBUFSIZ 512
-
-struct dnsheader {
- unsigned short id; // 2
- unsigned char flag1, flag2; // 2
- unsigned short qdcount, ancount, nscount, arcount; // 8
-};
-
-/*
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-*/
-
-struct queries {
- struct tcpdns {
- unsigned short len;
- union {
- struct dnsheader h;
- unsigned char dnsdata[SENDBUFSIZ];
- } u;
- } send;
- unsigned char recvbuf[RECVBUFSIZ];
- int sendlen;
- int sent_flag:1;
- int tcpstate:2;
- int fd;
- int rpos;
- int wpos;
- int no;
- struct timeval sent; /* long tv_sec, long tv_usec */
-};
-
-struct queries *Queries;
-
-#define NQUERY 100
-
-#define TCP_NONE 0
-#define TCP_WRITABLE 1
-#define TCP_READABLE 2
-
-/* input */
-char *ServerName = "127.0.0.1";
-char *ServerPort = "53";
-int family = PF_UNSPEC;
-char *datafile = NULL;
-int TimeLimit = 20;
-int EDNS0 = 0;
-int DNSSEC = 0;
-int recursion = 0;
-FILE *fp = NULL;
-int datafileloop = 0;
-int verbose = 0;
-int nQueries = 120;
-int printrcode = 0;
-char *rcodestr[]= {
- "NOERROR", "FormatError", "ServerFailure", "NameError",
- "NotImplemented", "Reused", "RCODE06", "RCODE07",
- "RCODE08", "RCODE09", "RCODE10", "RCODE11",
- "RCODE12", "RCODE13", "RCODE14", "RCODE15",
-};
-
-timediff_t timediff(struct timeval *a, struct timeval *b) /* u sec */
-{
- return (a->tv_sec - b->tv_sec) * 1000000 + (a->tv_usec - b->tv_usec);
-}
-
-#define TIMEOUTERROR -10000
-#define ERROROFFSET -20000
-#define ERRZEROREAD -30000
-
-uint64_t countrcode[16];
-uint64_t response_size_sum = 0;
-uint64_t response_size_sum2 = 0;
-uint64_t countanswers = 0;
-uint64_t countqueries = 0;
-uint64_t countzeroread = 0;
-uint64_t counttimeout = 0;
-uint64_t counterror = 0;
-
-int response_size_min = 0;
-int response_size_max = 0;
-
-
-
-void register_response(struct queries *q, int timeout, char *note)
-{
- u_char *p;
- int size;
- int rcode;
- int id;
-
- id = ntohs(q->send.u.h.id);
- if (note == NULL)
- note = "";
- countqueries++;
- if (timeout >= 0) {
- p = q->recvbuf;
- NS_GET16(size, p);
- response_size_sum += size;
- response_size_sum2 += size * size;
- if (response_size_min == 0 || response_size_min > size)
- response_size_min = size;
- if (response_size_max == 0 || response_size_max < size)
- response_size_max = size;
- rcode = p[3] & 0x0f;
- countrcode[rcode]++;
- countanswers++;
- if (verbose)
- printf("recv response id=%d rcode=%d size=%d rtt=%d\n", id, rcode, size, timeout);
- } else if (timeout == ERRZEROREAD) {
- countzeroread++;
- if (verbose)
- printf("recv response id=%d zeroread\n", id);
- } else if (timeout == TIMEOUTERROR) {
- counttimeout++;
- if (verbose)
- printf("recv timeout id=%d %lld usec\n", id, timediff(&current, &q->sent));
- } else {
- counterror++;
- if (verbose) {
- printf("recv error id=%d errno=%d at %s (%s)\n", id, ERROROFFSET - timeout, note, strerror(errno));
- }
- }
-#ifdef DEBUG
- printf("%ld.%03ld no=%d fd=%d %d %s\n", q->sent.tv_sec, q->sent.tv_usec/1000, q->no, q->fd, timeout, note);
- fflush(stdout);
-#endif
-}
-
-void output()
-{
- double response_size_average, response_size_variance, et;
-
- et = ((double)timediff(&current, &start))/1000000.0;
-
- printf("elapsed time: %.3f\n", et);
- printf("tcp qps: %.3f\n", (double)countanswers/et);
- printf("sent: %lld\n", countqueries);
- printf("answer: %lld %3.1f%%\n", countanswers,
- (double)((double)countanswers/(double)countqueries*100.0));
- printf("error: %lld %3.1f%%\n", counterror,
- (double)((double)counterror/(double)countqueries*100.0));
- printf("zeroread: %lld %3.1f%%\n", countzeroread,
- (double)((double)countzeroread/(double)countqueries*100.0));
- printf("timeout: %lld %3.1f%%\n", counttimeout,
- (double)((double)counttimeout/(double)countqueries*100.0));
- response_size_average = (double)response_size_sum/countanswers;
- response_size_variance = (double)response_size_sum2 / countanswers
- - response_size_average * response_size_average;
- printf("response size: %d/%.3f/%d/%.3f bytes\n", response_size_min, response_size_average, response_size_max, sqrt(response_size_variance));
- if (printrcode) {
- int i;
- for (i = 0; i < 16; i++) {
- if (countrcode[i] != 0) {
- printf("%s %lld %5.1f\n", rcodestr[i], countrcode[i], ((double)countrcode[i])/((double)countanswers)*100.0);
- }
- }
- }
-}
-
-void tcp_close(struct queries *q)
-{
-
-#ifdef DEBUG
-printf("tcp_close no=%d fd=%d\n", q->no, q->fd);
-#endif
- if (q->fd >= 0) {
- close(q->fd);
- FD_CLR(q->fd, &fdset0r);
- FD_CLR(q->fd, &fdset0w);
- }
- q->sent_flag = 0;
- q->tcpstate = TCP_NONE;
- q->fd = -1;
-}
-
-void tcp_send(struct queries *q)
-{
- int len;
-
- len = send(q->fd, &q->send, q->sendlen, MSG_NOSIGNAL);
-#ifdef DEBUG
-printf("tcp_send no=%d fd=%d %d:%d:%d\n", q->no, q->fd, len, q->wpos, q->sendlen);
-#endif
- if (len < 0) {
- if (errno == ENOTCONN) {
-printf("tcp_send no=%d fd=%d ENOTCONN return\n", q->no, q->fd);
- return;
- }
- register_response(q, ERROROFFSET - errno, "tcp_send");
- tcp_close(q);
- return;
- }
- if (len != q->sendlen) {
- register_response(q, ERROROFFSET - errno, "tcp_send:sendto");
- tcp_close(q);
- return;
- }
- FD_CLR(q->fd, &fdset0w);
- FD_SET(q->fd, &fdset0r);
-}
-
-struct typecodes {
- char *name;
- int code;
-} typecodes[] = {
- { "A", ns_t_a },
- { "NS", ns_t_ns },
- { "SOA", ns_t_soa },
- { "PTR", ns_t_ptr },
- { "HINFO", ns_t_hinfo },
- { "MX", ns_t_mx },
- { "TXT", ns_t_txt },
- { "SIG", ns_t_sig },
- { "KEY", ns_t_key },
- { "AAAA", ns_t_aaaa },
- { "NXT", ns_t_nxt },
- { "SRV", ns_t_srv },
- { "NAPTR", ns_t_naptr },
- { NULL, -1 },
-};
-
-int stringtodname(unsigned char *qname, unsigned char *buff, unsigned char *lim)
-{
- unsigned char *p, *s, *t;
- int count, total;
-
- t = qname;
- p = buff;
- total = 0;
- for ( ;; ) {
- s = p++;
- count = 0;
- if (p >= lim) return -1;
- while (*t != 0 && *t != '.')
- if (p < lim) {
- *p++ = *t++;
- count++;
- } else
- return -1;
- *s = count;
- if (count == 0)
- break;
- if (count > 63)
- return -1;
- total += count + 1;
- if (*t == '.') t++;
- }
- if (total > 250 || !(*t == 0 || (*t == '.' && t[1] == 0)))
- return -1;
- return p - buff;
-}
-
-void send_query_error(char *mesg)
-{
- err(1, "Packet size exceed: %s", mesg);
-}
-
-void send_query(struct queries *q)
-{
- u_char *p, *lim;
- char *qname;
- int qclass;
- int qtype;
- int tmp;
- struct typecodes *t = typecodes;
- u_char buff[512];
- static char sep[] = "\n\t ";
- static int lineno = 0;
-
- /*
- SEND E[send_packet_pos]
- */
- if (q->sent_flag) {
- register_response(q, TIMEOUTERROR, "send_query");
- tcp_close(q);
- }
- if (fp == NULL) {
- qname = "version.bind";
- qclass = ns_c_chaos;
- qtype = ns_t_txt;
- } else {
- do {
- if (fgets((char*)buff, sizeof(char)*512, fp) == NULL) {
- if (datafileloop == 1) {
- finished = 1;
- fclose(fp);
- fp = NULL;
- return;
- }
- if (datafileloop > 0)
- datafileloop--;
- rewind(fp);
- lineno = 0;
- if (fgets((char*)buff, sizeof(char)*512, fp) == NULL)
- err(1, "cannot rewind input file");
- }
- lineno++;
- } while(buff[0] == '#');
- qname = strtok((char*)buff, sep);
- p = (u_char*) strtok(NULL, sep);
- if (p != NULL) {
- while(t->name != NULL) {
- if (!strcasecmp(t->name, (char*)p))
- break;
- t++;
- }
- qtype = t->code;
- } else {
- qtype = ns_t_a;
- }
- if (qname == NULL || qtype < 0)
- err(1, "datafile format error at line %d, qname=%s qtype=%d", lineno, qname, qtype);
- qclass = ns_c_in;
- }
- q->send.u.h.id = counter++;
- q->send.u.h.flag1 = recursion ? 1 : 0; /* Query,OP=0,AA=0,TC=0,RD=0/1 */
- q->send.u.h.flag2 = 0;
- q->send.u.h.qdcount = htons(1);
- q->send.u.h.ancount = 0;
- q->send.u.h.nscount = 0;
- q->send.u.h.arcount = 0;
- p = q->send.u.dnsdata + sizeof(q->send.u.h);
- lim = p + sizeof(q->send.u.dnsdata);
- if ((tmp = stringtodname((u_char*) qname, p, lim)) < 0)
- send_query_error(qname);
- p += tmp;
- *(unsigned short *)p = htons(qtype);
- p += sizeof(unsigned short);
- *(unsigned short *)p = htons(qclass);
- p += sizeof(unsigned short);
- q->sendlen = p - q->send.u.dnsdata;
- if (EDNS0) {
-#define EDNS0size 11
- if (q->sendlen + EDNS0size >= sizeof(q->send.u.dnsdata))
- send_query_error("ENDS0");
- *p++ = 0; /* . */
- *(unsigned short *)p = htons(ns_t_opt);
- p += 2;
- *(unsigned short *)p = htons(4096);
- p += 2;
- *p++ = 0;
- *p++ = 0;
- *p++ = (DNSSEC == 0) ? 0 : 0x80; /* eflag: DO bit */
- *p++ = 0;
- *p++ = 0;
- *p++ = 0;
- q->sendlen += EDNS0size;
- p = (u_char*) &q->send.u.dnsdata;
- q->send.u.h.ancount = htons(1);
- }
- q->send.len = htons(q->sendlen);
- q->sendlen += sizeof(q->send.len);
- q->wpos = 0;
- q->rpos = 0;
- q->sent = current;
- if (verbose > 0) {
- int id = ntohs(*(unsigned short *)&q->send.u.dnsdata);
- printf("sending query(%s,%d,%d) id=%d %d bytes to %s\n", qname, qclass, qtype, id, q->sendlen, ServerName);
- hexdump("sending packet header:", (unsigned char*) &q->send.u.h, 12);
- }
- if (q->fd > 0)
- err(1, "q->fd > 0 but ignored\n");
-
- q->fd = socket(remote.ss_family, SOCK_STREAM, 0);
- tmp = fcntl(q->fd, F_GETFL, 0);
- fcntl(q->fd, F_SETFL, O_NONBLOCK | tmp);
- int conn_ret = connect(q->fd, (struct sockaddr *)&remote, remote_len);
- if(conn_ret < 0 && errno != EINPROGRESS) {
- register_response(q, ERROROFFSET - errno, "send_query:socket+fcntl+connect");
- tcp_close(q);
- return;
- }
-#ifdef DEBUG
-printf("send_query no=%d fd=%d socket|connect\n", q->no, q->fd);
-#endif
- q->tcpstate = TCP_WRITABLE;
- FD_SET(q->fd, &fdset0w);
- FD_CLR(q->fd, &fdset0r);
- if (nfds <= q->fd) {
- nfds = q->fd + 1;
- }
- q->sent = current;
- q->sent_flag = 1;
-}
-
-int UpdateQuery()
-{
- int i;
- timediff_t t, min = Timeout;
- struct queries *q;
- int free = 0;
-
- if (!finished && TimeLimit > 0) {
- if ((t = timediff(&current, &start)) > TimeLimit * 1000000LL) {
- finished = 1;
- send_finished = current;
- }
- }
- for(i = 0; i < nQueries; i++) {
- q = &Queries[i];
- if (q->sent_flag) {
- if ((t = timediff(&current, &q->sent)) > Timeout) {
- /* timeouted */
- register_response(q, TIMEOUTERROR, "UpdateQuery");
- tcp_close(q);
- } else
- if (t < min)
- min = t;
- }
- if (!q->sent_flag) {
- if (!finished)
- send_query(q);
- else
- free++;
- }
- }
- if (free == nQueries)
- min = -1; /* finished */
- return min;
-}
-
-char *skipname(char *p)
-{
- while(*p > 0 && *p < 0x40) p += *p + 1;
- if (*p == 0)
- return p+1;
- return p+2;
-}
-
-#define Hexdump(A,B,C)
-
-void tcp_receive(struct queries *q)
-{
- int len, len2;
- timediff_t tmp;
- unsigned char *recvp;
-
-/*printf("tcp_receive %s\n", q->nameserverlabel);*/
-
- len = read(q->fd, q->recvbuf + q->rpos, len2 = RECVBUFSIZ - q->rpos);
- if (len < 0) {
- if (errno == EAGAIN)
- return;
- register_response(q, ERROROFFSET - errno, "tcp_receive:read");
- tcp_close(q);
- return;
- }
- if (len == 0) {
- register_response(q, ERRZEROREAD, "tcp_receive:read");
- tcp_close(q);
- return;
- }
- q->rpos += len;
- if (q->rpos < 2)
- return;
- len2 = ntohs(*(unsigned short *)(q->recvbuf));
- if (q->rpos >= len2 + 2) {
- /* finished */
- recvp = q->recvbuf + 2;
- if (memcmp(recvp, q->send.u.dnsdata, 2) == 0) {
- if ((recvp[2] & 1) == 0 /* RA bit */
- || (recvp[3] & 15) != 0 /* RCODE must be 0 */
- ) {
-/*
- fprintf(stderr, "WRONG AA=%d RCODE=%d\n",
- ((recvp[2]>>2) & 1), recvp[3]&15);
-*/
- }
- tmp = timediff(&current, &q->sent);
- register_response(q, tmp, "tcp_receive");
- tcp_close(q);
- return;
- } else {
-printf("no=%d fd=%d unknown recv %d bytes, len=%d\n", q->no, q->fd, q->rpos, ntohs(*(unsigned short *)(q->recvbuf)));
- hexdump("", q->recvbuf, len);
- /*
- fprintf(stderr, "unknown recv from %s, %d bytes %02x %02x\n", q->nameserverlabel, q->rpos, recvp[0], recvp[1]);
- */
- tcp_close(q);
- }
- }
-}
-
-void query()
-{
- fd_set fdsetr, fdsetw;
- struct timeval timeout;
- int min;
- struct queries *q;
- int i, n;
- struct addrinfo hints, *res0;
- int error;
-
- Queries = Xmalloc(sizeof(Queries[0]) * nQueries);
- memset(&remote, 0, sizeof(remote));
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = family;
- hints.ai_socktype = SOCK_STREAM;
- printf("resolving: %s:%s\n", ServerName, ServerPort);
- error = getaddrinfo(ServerName, 0, &hints, &res0);
- if (error) {
- errx(1, "%s", gai_strerror(error));
- }
-
- /* Update server port. */
- int port = atoi(ServerPort);
- if (res0->ai_family == AF_INET6) {
- struct sockaddr_in6 *ipv6 = (struct sockaddr_in6*)res0->ai_addr;
- ipv6->sin6_port = htons(port);
- } else {
- struct sockaddr_in *ipv4 = (struct sockaddr_in*)res0->ai_addr;
- ipv4->sin_port = htons(port);
- }
-
- remote_len = res0->ai_addrlen;
- memcpy(&remote, res0->ai_addr, res0->ai_addrlen);
- memset(&countrcode, 0, sizeof(countrcode));
-
- res_init();
- _res.options ^= ~RES_RECURSE;
- _res.options |= RES_AAONLY;
-
- for (i = 0; i < nQueries; i++) {
- Queries[i].sent_flag = 0;
- Queries[i].no = i;
- }
-
- FD_ZERO(&fdset0r);
- FD_ZERO(&fdset0w);
- nfds = 0;
- UpdateCurrentTime;
- start = current;
- finished = 0;
-
- for (;;) {
- UpdateCurrentTime;
- if ((min = UpdateQuery()) < 0)
- break;
- timeout.tv_sec = min / 1000000;
- timeout.tv_usec = min % 1000000;
- fdsetr = fdset0r;
- fdsetw = fdset0w;
- n = select(nfds, &fdsetr, &fdsetw, NULL, &timeout);
- UpdateCurrentTime;
- for(i = 0; i < nQueries; i++) {
- q = &Queries[i];
- if (q->fd < 0 || !q->sent_flag)
- continue;
- if (FD_ISSET(q->fd, &fdsetw)) {
- tcp_send(q);
- } else if (FD_ISSET(q->fd, &fdsetr)) {
- tcp_receive(q);
- }
- }
- }
-}
-
-void usage()
-{
- fprintf(stderr,
-"querytcp [-d datafile] [-s server_addr] [-p port] [-q num_queries] [-t timeout] [l limit] [-4] [-6] [-h]\n"
-" -d specifies the input data file (default: stdin)\n"
-" -s sets the server to query (default: 127.0.0.1)\n"
-" -p sets the port on which to query the server (default: 53)\n"
-" -q specifies the maximum number of queries outstanding (default: 120)\n"
-" -t specifies the timeout for query completion in seconds (default: 10)\n"
-" -l specifies how a limit for how long to run tests in seconds (no default)\n"
-" -e enable EDNS0\n"
-" -D set DO bit\n"
-" -r set RD bit\n"
-"\n"
-"\n"
-"\n"
-" -c print the number of packets with each rcode\n"
-" -v verbose: report the RCODE of each response on stdout\n"
-" -h print this usage\n"
-);
- exit(1);
-}
-
-int main(int argc, char *argv[])
-{
- int ch, i;
- printf("dnsheader size: %d\n", sizeof(struct dnsheader));
- while ((ch = getopt(argc, argv, "d:s:p:q:t:l:46eDrvh")) != -1) {
- switch (ch) {
- case 'q':
- nQueries = atoi(optarg);
- if (nQueries < 1)
- err(1, "-q requires natural number");
- break;
- case 'p':
- ServerPort = Xstrdup(optarg);
- break;
- case 's':
- ServerName = Xstrdup(optarg);
- break;
- case 'd':
- datafile = Xstrdup(optarg);
- if ((fp = fopen(datafile, "r")) == NULL)
- err(1, "cannot open %s", optarg);
- break;
- case 't':
- i = atoi(optarg);
- if (i < 1)
- err(1, "-t timeout > 0");
- Timeout = (int64_t)i * 1000000LL;
- break;
- case 'l':
- TimeLimit = atoi(optarg);
- break;
- case '4':
- family = AF_INET;
- break;
- case '6':
- family = AF_INET6;
- break;
- case 'e':
- EDNS0 = 1;
- break;
- case 'D':
- DNSSEC = 1;
- break;
- case 'r':
- recursion = 1;
- break;
- case 'v':
- verbose = 1;
- break;
- case 'c':
- printrcode = 1;
- break;
- case 'h':
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- query();
- output();
-
- return 0;
-}