diff options
author | Ondřej Surý <ondrej@sury.org> | 2013-06-28 12:59:40 +0200 |
---|---|---|
committer | Ondřej Surý <ondrej@sury.org> | 2013-06-28 12:59:40 +0200 |
commit | 124965832295a277b9ca6ae9fac4f45a74a36b2a (patch) | |
tree | f299e2335863f74e0be0707f84b85211baaf2d03 /tests | |
parent | 3d2d198c71a6b844b60fa9ef68801b66bba93361 (diff) | |
download | knot-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/Makefile | 16 | ||||
-rw-r--r-- | tests/chkjournal.c | 541 | ||||
-rw-r--r-- | tests/querytcp.c | 797 |
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(¤t, 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(¤t, &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(¤t, &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(¤t, &start)) > TimeLimit * 1000000LL) { - finished = 1; - send_finished = current; - } - } - for(i = 0; i < nQueries; i++) { - q = &Queries[i]; - if (q->sent_flag) { - if ((t = timediff(¤t, &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(¤t, &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; -} |