summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2022-11-19 14:45:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2022-11-19 14:45:45 +0000
commit843f8a24f27eb0c724a1aec4d95b3790d95e48c7 (patch)
tree447c083f0d4eceafca3e377ad1d574ebc1a0061d
parentReleasing debian version 2.9.0-1. (diff)
downloaddnsperf-843f8a24f27eb0c724a1aec4d95b3790d95e48c7.tar.xz
dnsperf-843f8a24f27eb0c724a1aec4d95b3790d95e48c7.zip
Merging upstream version 2.10.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--CHANGES23
-rw-r--r--Makefile.am2
-rw-r--r--Makefile.in2
-rw-r--r--README.md2
-rwxr-xr-xconfigure20
-rw-r--r--configure.ac4
-rwxr-xr-xcontrib/queryparse/queryparse2
-rw-r--r--contrib/queryparse/queryparse.12
-rw-r--r--m4/dnsperf.m42
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile.in2
-rw-r--r--src/buffer.h2
-rw-r--r--src/datafile.c101
-rw-r--r--src/datafile.h23
-rw-r--r--src/dns.c2
-rw-r--r--src/dns.h2
-rw-r--r--src/dnsperf.1.in44
-rw-r--r--src/dnsperf.c108
-rw-r--r--src/edns.c2
-rw-r--r--src/edns.h2
-rw-r--r--src/list.h2
-rw-r--r--src/log.c2
-rw-r--r--src/log.h2
-rw-r--r--src/net.c2
-rw-r--r--src/net.h2
-rw-r--r--src/net_doh.c2
-rw-r--r--src/net_dot.c2
-rw-r--r--src/net_tcp.c2
-rw-r--r--src/net_udp.c2
-rw-r--r--src/opt.c2
-rw-r--r--src/opt.h2
-rw-r--r--src/os.c2
-rw-r--r--src/os.h2
-rw-r--r--src/qtype.c2
-rw-r--r--src/qtype.h2
-rwxr-xr-xsrc/resperf-report2
-rw-r--r--src/resperf.1.in2
-rw-r--r--src/resperf.c6
-rw-r--r--src/result.h2
-rw-r--r--src/strerror.c2
-rw-r--r--src/strerror.h2
-rw-r--r--src/test/Makefile.am12
-rw-r--r--src/test/Makefile.in19
-rw-r--r--src/test/empty.blob0
-rw-r--r--src/test/emptypayload.blobbin0 -> 2 bytes
-rw-r--r--src/test/largesttcp.blob1
-rw-r--r--src/test/largestudp.blob1
-rw-r--r--src/test/missingpayload.blobbin0 -> 2 bytes
-rw-r--r--src/test/querywithcookie.blobbin0 -> 42 bytes
-rw-r--r--src/test/shortpayload.blobbin0 -> 3 bytes
-rwxr-xr-xsrc/test/test7.sh83
-rw-r--r--src/test/tooshortlength.blobbin0 -> 1 bytes
-rw-r--r--src/test/twoquerieswithnsid.blobbin0 -> 98 bytes
-rw-r--r--src/tsig.c2
-rw-r--r--src/tsig.h2
-rw-r--r--src/util.h2
56 files changed, 405 insertions, 112 deletions
diff --git a/CHANGES b/CHANGES
index 514c008..5d686d3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,26 @@
+2022-11-11 Jerry Lundström
+
+ Release 2.10.0
+
+ This release adds a binary datafile (DNS wire) format to `dnsperf`
+ thanks to a contribution from Petr Špaček @pspacek (ISC).
+
+ The new binary format greatly improves performance in some cases, for
+ Petr's case it was testing dynamic updates. Switching to this
+ pre-compiled DNS wire format increased QPS from 4k to 600k, an increase
+ of 150 times throughput from `dnsperf`!
+
+ See man-page for `-B` for more information and examples how to use.
+
+ 5971cb9 Doc
+ a241068 CodeQL
+ 2a7d10a Fix CodeQL workflow
+ 0ce15f6 Fix COPR
+ 0ae4a54 CodeQL
+ f52e4b1 wire format input
+ c423aa9 wire format input
+ 2b0693d Input binary format
+
2021-12-08 Jerry Lundström
Release 2.9.0
diff --git a/Makefile.am b/Makefile.am
index 2cc5781..a992b0e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 OARC, Inc.
+# Copyright 2019-2022 OARC, Inc.
# Copyright 2017-2018 Akamai Technologies
# Copyright 2006-2016 Nominum, Inc.
# All rights reserved.
diff --git a/Makefile.in b/Makefile.in
index 3169099..1fe1047 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -14,7 +14,7 @@
@SET_MAKE@
-# Copyright 2019-2021 OARC, Inc.
+# Copyright 2019-2022 OARC, Inc.
# Copyright 2017-2018 Akamai Technologies
# Copyright 2006-2016 Nominum, Inc.
# All rights reserved.
diff --git a/README.md b/README.md
index 6985c70..123c7a5 100644
--- a/README.md
+++ b/README.md
@@ -100,7 +100,7 @@ The contrib directory contains additional software related to `dnsperf` and
## License
```
-Copyright 2019-2021 OARC, Inc.
+Copyright 2019-2022 OARC, Inc.
Copyright 2017-2018 Akamai Technologies
Copyright 2006-2016 Nominum, Inc.
All rights reserved.
diff --git a/configure b/configure
index af827f6..de90675 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for dnsperf 2.9.0.
+# Generated by GNU Autoconf 2.69 for dnsperf 2.10.0.
#
# Report bugs to <admin@dns-oarc.net>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='dnsperf'
PACKAGE_TARNAME='dnsperf'
-PACKAGE_VERSION='2.9.0'
-PACKAGE_STRING='dnsperf 2.9.0'
+PACKAGE_VERSION='2.10.0'
+PACKAGE_STRING='dnsperf 2.10.0'
PACKAGE_BUGREPORT='admin@dns-oarc.net'
PACKAGE_URL='https://github.com/DNS-OARC/dnsperf/issues'
@@ -1360,7 +1360,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures dnsperf 2.9.0 to adapt to many kinds of systems.
+\`configure' configures dnsperf 2.10.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1431,7 +1431,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of dnsperf 2.9.0:";;
+ short | recursive ) echo "Configuration of dnsperf 2.10.0:";;
esac
cat <<\_ACEOF
@@ -1570,7 +1570,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-dnsperf configure 2.9.0
+dnsperf configure 2.10.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1939,7 +1939,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by dnsperf $as_me 2.9.0, which was
+It was created by dnsperf $as_me 2.10.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2802,7 +2802,7 @@ fi
# Define the identity of the package.
PACKAGE='dnsperf'
- VERSION='2.9.0'
+ VERSION='2.10.0'
cat >>confdefs.h <<_ACEOF
@@ -14410,7 +14410,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by dnsperf $as_me 2.9.0, which was
+This file was extended by dnsperf $as_me 2.10.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14477,7 +14477,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-dnsperf config.status 2.9.0
+dnsperf config.status 2.10.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 08ab00b..0a0130b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 OARC, Inc.
+# Copyright 2019-2022 OARC, Inc.
# Copyright 2017-2018 Akamai Technologies
# Copyright 2006-2016 Nominum, Inc.
# All rights reserved.
@@ -16,7 +16,7 @@
# limitations under the License.
AC_PREREQ(2.64)
-AC_INIT([dnsperf], [2.9.0], [admin@dns-oarc.net], [dnsperf], [https://github.com/DNS-OARC/dnsperf/issues])
+AC_INIT([dnsperf], [2.10.0], [admin@dns-oarc.net], [dnsperf], [https://github.com/DNS-OARC/dnsperf/issues])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
AC_CONFIG_SRCDIR([src/dnsperf.c])
AC_CONFIG_HEADER([src/config.h])
diff --git a/contrib/queryparse/queryparse b/contrib/queryparse/queryparse
index 01edeaf..b138406 100755
--- a/contrib/queryparse/queryparse
+++ b/contrib/queryparse/queryparse
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2019-2021 OARC, Inc.
+# Copyright 2019-2022 OARC, Inc.
# Copyright 2017-2018 Akamai Technologies
# Copyright 2006-2016 Nominum, Inc.
# All rights reserved.
diff --git a/contrib/queryparse/queryparse.1 b/contrib/queryparse/queryparse.1
index bfcac8c..3483d27 100644
--- a/contrib/queryparse/queryparse.1
+++ b/contrib/queryparse/queryparse.1
@@ -1,4 +1,4 @@
-.\" Copyright 2019-2021 OARC, Inc.
+.\" Copyright 2019-2022 OARC, Inc.
.\" Copyright 2017-2018 Akamai Technologies
.\" Copyright 2006-2016 Nominum, Inc.
.\" All rights reserved.
diff --git a/m4/dnsperf.m4 b/m4/dnsperf.m4
index d0d8d03..fb5378d 100644
--- a/m4/dnsperf.m4
+++ b/m4/dnsperf.m4
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 OARC, Inc.
+# Copyright 2019-2022 OARC, Inc.
# Copyright 2017-2018 Akamai Technologies
# Copyright 2006-2016 Nominum, Inc.
# All rights reserved.
diff --git a/src/Makefile.am b/src/Makefile.am
index 45d2dec..119e187 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright 2019-2021 OARC, Inc.
+# Copyright 2019-2022 OARC, Inc.
# Copyright 2017-2018 Akamai Technologies
# Copyright 2006-2016 Nominum, Inc.
# All rights reserved.
diff --git a/src/Makefile.in b/src/Makefile.in
index 335c659..1772980 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -14,7 +14,7 @@
@SET_MAKE@
-# Copyright 2019-2021 OARC, Inc.
+# Copyright 2019-2022 OARC, Inc.
# Copyright 2017-2018 Akamai Technologies
# Copyright 2006-2016 Nominum, Inc.
# All rights reserved.
diff --git a/src/buffer.h b/src/buffer.h
index ab46f9b..52bfef2 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/datafile.c b/src/datafile.c
index da2acac..06ea0ea 100644
--- a/src/datafile.c
+++ b/src/datafile.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
@@ -33,7 +33,10 @@
#include <sys/stat.h>
#include <assert.h>
-perf_datafile_t* perf_datafile_open(const char* filename)
+static perf_result_t read_one_blob(perf_datafile_t* dfile, perf_buffer_t* wire);
+static perf_result_t read_one_line(perf_datafile_t* dfile, perf_buffer_t* lines);
+
+perf_datafile_t* perf_datafile_open(const char* filename, perf_input_format_t format)
{
perf_datafile_t* dfile;
struct stat buf;
@@ -63,6 +66,18 @@ perf_datafile_t* perf_datafile_open(const char* filename)
dfile->size = buf.st_size;
}
}
+ dfile->format = format;
+ switch (format) {
+ case input_format_text_query:
+ case input_format_text_update:
+ dfile->readfunc = read_one_line;
+ break;
+ case input_format_tcp_wire_format:
+ dfile->readfunc = read_one_blob;
+ break;
+ default:
+ perf_log_fatal("invalid datafile format");
+ };
return dfile;
}
@@ -129,13 +144,15 @@ static perf_result_t read_more(perf_datafile_t* dfile)
dfile->at = 0;
}
+ /* leave space for \0 string termination at the end */
n = read(dfile->fd, &dfile->databuf[dfile->have], sizeof(dfile->databuf) - dfile->have - 1);
if (n < 0) {
return (PERF_R_FAILURE);
+ } else if (n == 0) {
+ return (PERF_R_EOF);
}
dfile->have += n;
- dfile->databuf[dfile->have] = 0;
if (dfile->is_file && dfile->have == dfile->size) {
dfile->cached = true;
@@ -144,6 +161,61 @@ static perf_result_t read_more(perf_datafile_t* dfile)
return (PERF_R_SUCCESS);
}
+/* Binary format: (<uint16_t> for blob length, <bytes>), repeat
+ * Outputs single packet _without_ the length preambule. */
+static perf_result_t read_one_blob(perf_datafile_t* dfile, perf_buffer_t* wire)
+{
+ perf_result_t result;
+ uint16_t packet_size; /* 2-byte preambule like in the TCP stream */
+
+ while (true) {
+ if ((dfile->have - dfile->at) < sizeof(packet_size)) {
+ /* we don't have complete preambule yet */
+ if (dfile->cached) {
+ if ((dfile->have - dfile->at) == 0) {
+ return PERF_R_EOF;
+ } else {
+ return PERF_R_INVALIDFILE;
+ }
+ }
+ result = read_more(dfile);
+ if (result != PERF_R_SUCCESS) {
+ if (result == PERF_R_EOF && (dfile->have - dfile->at) != 0) {
+ /* incomplete preambule at the end of file */
+ result = PERF_R_INVALIDFILE;
+ }
+ return (result);
+ }
+ continue;
+ }
+ memcpy(&packet_size, &dfile->databuf[dfile->at], sizeof(uint16_t));
+ packet_size = ntohs(packet_size);
+ break;
+ }
+ while (true) {
+ if (sizeof(packet_size) + packet_size > (dfile->have - dfile->at)) {
+ if (dfile->cached) {
+ return PERF_R_INVALIDFILE;
+ }
+ result = read_more(dfile);
+ if (result != PERF_R_SUCCESS) {
+ if (result == PERF_R_EOF) {
+ /* incomplete blob at the end of file */
+ result = PERF_R_INVALIDFILE;
+ }
+ return (result);
+ }
+ continue;
+ }
+ break;
+ }
+
+ perf_buffer_putmem(wire, ((unsigned char*)&dfile->databuf[dfile->at]) + sizeof(packet_size), packet_size);
+ dfile->at += sizeof(packet_size) + packet_size;
+ return (PERF_R_SUCCESS);
+}
+
+/* String in output buffer is not \0 terminated, check length in dfile->have */
static perf_result_t read_one_line(perf_datafile_t* dfile, perf_buffer_t* lines)
{
const char* cur;
@@ -163,11 +235,12 @@ static perf_result_t read_one_line(perf_datafile_t* dfile, perf_buffer_t* lines)
if (curlen == nrem) {
if (!dfile->cached) {
result = read_more(dfile);
+ /* line terminator for text input */
+ dfile->databuf[dfile->have] = 0;
if (result != PERF_R_SUCCESS)
return (result);
}
if (dfile->have - dfile->at == 0) {
- dfile->nruns++;
return (PERF_R_EOF);
}
if (dfile->have - dfile->at > nrem)
@@ -176,7 +249,7 @@ static perf_result_t read_one_line(perf_datafile_t* dfile, perf_buffer_t* lines)
/* We now have a line. Advance the buffer past it. */
dfile->at += curlen;
- if (dfile->have - dfile->at > 0) {
+ if (dfile->at < dfile->have) {
dfile->at += 1;
}
@@ -194,7 +267,7 @@ static perf_result_t read_one_line(perf_datafile_t* dfile, perf_buffer_t* lines)
return (PERF_R_SUCCESS);
}
-perf_result_t perf_datafile_next(perf_datafile_t* dfile, perf_buffer_t* lines, bool is_update)
+perf_result_t perf_datafile_next(perf_datafile_t* dfile, perf_buffer_t* lines)
{
const char* current;
perf_result_t result;
@@ -206,15 +279,16 @@ perf_result_t perf_datafile_next(perf_datafile_t* dfile, perf_buffer_t* lines, b
goto done;
}
- result = read_one_line(dfile, lines);
+ result = dfile->readfunc(dfile, lines);
if (result == PERF_R_EOF) {
if (!dfile->read_any) {
result = PERF_R_INVALIDFILE;
goto done;
}
+ dfile->nruns++;
if (dfile->maxruns != dfile->nruns) {
reopen_file(dfile);
- result = read_one_line(dfile, lines);
+ result = dfile->readfunc(dfile, lines);
}
}
if (result != PERF_R_SUCCESS) {
@@ -222,12 +296,15 @@ perf_result_t perf_datafile_next(perf_datafile_t* dfile, perf_buffer_t* lines, b
}
dfile->read_any = true;
- if (is_update) {
+ if (dfile->format == input_format_text_update) {
while (true) {
current = perf_buffer_used(lines);
- result = read_one_line(dfile, lines);
- if (result == PERF_R_EOF && dfile->maxruns != dfile->nruns) {
- reopen_file(dfile);
+ result = dfile->readfunc(dfile, lines);
+ if (result == PERF_R_EOF) {
+ dfile->nruns++;
+ if (dfile->maxruns != dfile->nruns) {
+ reopen_file(dfile);
+ }
}
if (result != PERF_R_SUCCESS || strcasecmp(current, "send") == 0)
break;
diff --git a/src/datafile.h b/src/datafile.h
index 7b6caf3..a1b737e 100644
--- a/src/datafile.h
+++ b/src/datafile.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
@@ -25,27 +25,38 @@
#include <pthread.h>
#include <stdbool.h>
+#include <stdint.h>
-typedef struct perf_datafile {
+typedef enum {
+ input_format_text_query,
+ input_format_text_update,
+ input_format_tcp_wire_format
+} perf_input_format_t;
+
+typedef struct perf_datafile perf_datafile_t;
+struct perf_datafile {
pthread_mutex_t lock;
int pipe_fd;
int fd;
bool is_file;
size_t size, at, have;
bool cached;
- char databuf[(64 * 1024) + 1];
+ char databuf[(64 * 1024) + sizeof(uint16_t)]; /* pad for null-terminated string or TCP wire length */
unsigned int maxruns;
unsigned int nruns;
bool read_any;
-} perf_datafile_t;
-perf_datafile_t* perf_datafile_open(const char* filename);
+ perf_input_format_t format;
+ perf_result_t (*readfunc)(perf_datafile_t* dfile, perf_buffer_t* lines);
+};
+
+perf_datafile_t* perf_datafile_open(const char* filename, perf_input_format_t format);
void perf_datafile_close(perf_datafile_t** dfilep);
void perf_datafile_setmaxruns(perf_datafile_t* dfile, unsigned int maxruns);
void perf_datafile_setpipefd(perf_datafile_t* dfile, int pipe_fd);
-perf_result_t perf_datafile_next(perf_datafile_t* dfile, perf_buffer_t* lines, bool is_update);
+perf_result_t perf_datafile_next(perf_datafile_t* dfile, perf_buffer_t* lines);
unsigned int perf_datafile_nruns(const perf_datafile_t* dfile);
diff --git a/src/dns.c b/src/dns.c
index 8c4999f..20bb354 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/dns.h b/src/dns.h
index cb8cb49..c126f97 100644
--- a/src/dns.h
+++ b/src/dns.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/dnsperf.1.in b/src/dnsperf.1.in
index 787f89f..9ae24bd 100644
--- a/src/dnsperf.1.in
+++ b/src/dnsperf.1.in
@@ -1,4 +1,4 @@
-.\" Copyright 2019-2021 OARC, Inc.
+.\" Copyright 2019-2022 OARC, Inc.
.\" Copyright 2017-2018 Akamai Technologies
.\" Copyright 2006-2016 Nominum, Inc.
.\" All rights reserved.
@@ -22,6 +22,7 @@ dnsperf \- test the performance of a DNS server
.ad l
\fBdnsperf\fR\ [\fB\-a\ \fIlocal_addr\fR]
[\fB\-b\ \fIbufsize\fR]
+[\fB\-B\fR]
[\fB\-c\ \fIclients\fR]
[\fB\-d\ \fIdatafile\fR]
[\fB\-D\fR]
@@ -192,6 +193,42 @@ Sets the size of the socket's send and receive buffers, in kilobytes.
If not specified, the operating system's default is used.
.RE
+\fB-B\fR
+.br
+.RS
+Instructs \fBdnsperf\fR to read datafile in TCP-stream binary format
+as specified by RFC 1035 section "4.2.2. TCP usage".
+Each packet is preceded by 2-byte preambule which specifies length of
+the following DNS packet in network byte order, immediatelly followed
+by raw bytes of the packet.
+First two bytes of any packet should contain message ID and are
+overwritten by \fBdnsperf\fR on the fly. All other bytes are left
+intact.
+Packets shorter than two bytes are sent intact.
+Packets in datafile can contain arbitrary bytes and are not checked for
+validity.
+Malformed packets probably will not be responded to by servers and will
+cause timeouts.
+This option is mutually exclusive with \fB-D\fR, \fB-e\fR, \fB-E\fR,
+\fB-u\fR and \fB-y\fR.
+
+These binary datafiles can be generated using arbitrary TCP listeners such
+as \fBnetcat\fR (nc) and \fBsockat\fR.
+TCP must be used so that the length is prepended.
+Following example shows how to generate a datafile with two query and
+then using it, you need two terminals.
+
+.EX
+(terminal 1) $ nc -l 127.0.0.1 5300 > dns.blob
+(terminal 2) $ echo "example.com A" | dnsperf -s 127.0.0.1 -p 5300 -m tcp
+...wait for dnsperf to finish...
+(terminal 1) $ nc -l 127.0.0.1 5300 >> dns.blob
+(terminal 2) $ echo "example.com AAAA" | dnsperf -s 127.0.0.1 -p 5300 -m tcp
+...wait for dnsperf to finish...
+(terminal 1) $ dnsperf -B -d dns.blob -s $IP
+.EE
+.RE
+
\fB-c \fIclients\fR
.br
.RS
@@ -212,12 +249,14 @@ If not specified, \fBdnsperf\fR will read from standard input.
.RS
Sets the DO (DNSSEC OK) bit [RFC3225] in all packets sent.
This also enables EDNS0, which is required for DNSSEC.
+This option is mutually exclusive with \fB-B\fR.
.RE
\fB-e\fR
.br
.RS
Enables EDNS0 [RFC2671], by adding an OPT record to all packets sent.
+This option is mutually exclusive with \fB-B\fR.
.RE
\fB-E \fIcode:value\fR
@@ -226,6 +265,7 @@ Enables EDNS0 [RFC2671], by adding an OPT record to all packets sent.
Add an EDNS [RFC2671] option to all packets sent, using the specified
numeric option code and value expressed as a a hex-encoded string.
This also enables EDNS0.
+This option is mutually exclusive with \fB-B\fR.
.RE
\fB-f \fIfamily\fR
@@ -331,6 +371,7 @@ Instructs \fBdnsperf\fR to send DNS dynamic update messages, rather than
queries.
The format of the input file is different in this case; see the
"Constructing a dynamic update input file" section for more details.
+This option is mutually exclusive with \fB-B\fR.
.RE
\fB-v\fR
@@ -373,6 +414,7 @@ key algorithm, name and secret, where the algorithm defaults to hmac-md5 and
the secret is expressed as a base-64 encoded string.
Available algorithms are: hmac-md5, hmac-sha1, hmac-sha224, hmac-sha256,
hmac-sha384 and hmac-sha512.
+This option is mutually exclusive with \fB-B\fR.
.RE
\fB-O \fIoption=value\fR
diff --git a/src/dnsperf.c b/src/dnsperf.c
index 40cedb4..7d10212 100644
--- a/src/dnsperf.c
+++ b/src/dnsperf.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
@@ -67,29 +67,31 @@
#define RECV_BATCH_SIZE 16
typedef struct {
- int argc;
- char** argv;
- int family;
- uint32_t clients;
- uint32_t threads;
- uint32_t maxruns;
- uint64_t timelimit;
- perf_sockaddr_t server_addr;
- perf_sockaddr_t local_addr;
- uint64_t timeout;
- uint32_t bufsize;
- bool edns;
- bool dnssec;
- perf_tsigkey_t* tsigkey;
- perf_ednsoption_t* edns_option;
- uint32_t max_outstanding;
- uint32_t max_qps;
- uint64_t stats_interval;
- bool updates;
- bool verbose;
- enum perf_net_mode mode;
- perf_suppress_t suppress;
- size_t num_queries_per_conn;
+ int argc;
+ char** argv;
+ int family;
+ uint32_t clients;
+ uint32_t threads;
+ uint32_t maxruns;
+ uint64_t timelimit;
+ perf_sockaddr_t server_addr;
+ perf_sockaddr_t local_addr;
+ uint64_t timeout;
+ uint32_t bufsize;
+ bool edns;
+ bool dnssec;
+ perf_tsigkey_t* tsigkey;
+ perf_ednsoption_t* edns_option;
+ uint32_t max_outstanding;
+ uint32_t max_qps;
+ uint64_t stats_interval;
+ bool updates;
+ bool binary_input;
+ perf_input_format_t input_format;
+ bool verbose;
+ enum perf_net_mode mode;
+ perf_suppress_t suppress;
+ size_t num_queries_per_conn;
} config_t;
typedef struct {
@@ -483,6 +485,9 @@ setup(int argc, char** argv, config_t* config)
perf_opt_add('u', perf_opt_boolean, NULL,
"send dynamic updates instead of queries",
NULL, &config->updates);
+ perf_opt_add('B', perf_opt_boolean, NULL,
+ "read input file as TCP-stream binary format",
+ NULL, &config->binary_input);
perf_opt_add('v', perf_opt_boolean, NULL,
"verbose: report each query and additional information to stdout",
NULL, &config->verbose);
@@ -538,7 +543,19 @@ setup(int argc, char** argv, config_t* config)
perf_net_parselocal(config->server_addr.sa.sa.sa_family,
local_name, local_port, &config->local_addr);
- input = perf_datafile_open(filename);
+ if (config->binary_input
+ && (config->edns || config->edns_option || config->dnssec
+ || config->tsigkey || config->updates)) {
+ fprintf(stderr, "-B is mutually exclusive with -D, -e, -E, -u, -y\n");
+ exit(1);
+ }
+ if (config->updates)
+ config->input_format = input_format_text_update;
+ else if (config->binary_input)
+ config->input_format = input_format_tcp_wire_format;
+ else
+ config->input_format = input_format_text_query;
+ input = perf_datafile_open(filename, config->input_format);
if (config->maxruns == 0 && config->timelimit == 0)
config->maxruns = 1;
@@ -736,20 +753,35 @@ do_send(void* arg)
PERF_UNLOCK(&tinfo->lock);
perf_buffer_clear(&lines);
- result = perf_datafile_next(input, &lines, config->updates);
+ result = perf_datafile_next(input, &lines);
if (result != PERF_R_SUCCESS) {
if (result == PERF_R_INVALIDFILE)
perf_log_fatal("input file contains no data");
break;
}
- qid = q - tinfo->queries;
- perf_buffer_usedregion(&lines, &used);
- perf_buffer_clear(&msg);
- result = perf_dns_buildrequest(&used, qid,
- config->edns, config->dnssec, config->updates,
- config->tsigkey, config->edns_option,
- &msg);
+ perf_buffer_t* send = &msg;
+ qid = q - tinfo->queries;
+ switch (config->input_format) {
+ case input_format_text_query:
+ case input_format_text_update:
+ perf_buffer_clear(&msg);
+ perf_buffer_usedregion(&lines, &used);
+ result = perf_dns_buildrequest(&used, qid,
+ config->edns, config->dnssec, config->input_format == input_format_text_update,
+ config->tsigkey, config->edns_option,
+ &msg);
+ break;
+
+ case input_format_tcp_wire_format:
+ send = &lines;
+ if (perf_buffer_usedlength(send) > 1) {
+ ((uint8_t*)perf_buffer_base(send))[0] = qid >> 8;
+ ((uint8_t*)perf_buffer_base(send))[1] = qid;
+ }
+ result = PERF_R_SUCCESS;
+ break;
+ }
if (result != PERF_R_SUCCESS) {
PERF_LOCK(&tinfo->lock);
query_move(tinfo, q, prepend_unused);
@@ -758,13 +790,17 @@ do_send(void* arg)
continue;
}
- base = perf_buffer_base(&msg);
- length = perf_buffer_usedlength(&msg);
+ base = perf_buffer_base(send);
+ length = perf_buffer_usedlength(send);
now = perf_get_time();
if (config->verbose) {
free(q->desc);
- q->desc = strdup(lines.base);
+ if (config->input_format == input_format_tcp_wire_format) {
+ q->desc = strdup("binary input");
+ } else {
+ q->desc = strdup(lines.base);
+ }
if (q->desc == NULL)
perf_log_fatal("out of memory");
}
diff --git a/src/edns.c b/src/edns.c
index 9c04f9b..fa66cc4 100644
--- a/src/edns.c
+++ b/src/edns.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/edns.h b/src/edns.h
index 300d462..8064cc4 100644
--- a/src/edns.h
+++ b/src/edns.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/list.h b/src/list.h
index f110b79..d52ad04 100644
--- a/src/list.h
+++ b/src/list.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/log.c b/src/log.c
index bba5ba6..e807dcc 100644
--- a/src/log.c
+++ b/src/log.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/log.h b/src/log.h
index 76ad7b7..e922ca1 100644
--- a/src/log.h
+++ b/src/log.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/net.c b/src/net.c
index 1fe21ba..ca3750f 100644
--- a/src/net.c
+++ b/src/net.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/net.h b/src/net.h
index 19fdb35..89af773 100644
--- a/src/net.h
+++ b/src/net.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/net_doh.c b/src/net_doh.c
index 6bf673d..f483e0d 100644
--- a/src/net_doh.c
+++ b/src/net_doh.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/net_dot.c b/src/net_dot.c
index a68a84f..9fd718d 100644
--- a/src/net_dot.c
+++ b/src/net_dot.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/net_tcp.c b/src/net_tcp.c
index 5473e4a..61676fc 100644
--- a/src/net_tcp.c
+++ b/src/net_tcp.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/net_udp.c b/src/net_udp.c
index 685e609..5ca100f 100644
--- a/src/net_udp.c
+++ b/src/net_udp.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/opt.c b/src/opt.c
index 75830bd..d65a0f8 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/opt.h b/src/opt.h
index 0864e2b..e30ea8c 100644
--- a/src/opt.h
+++ b/src/opt.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/os.c b/src/os.c
index d149cea..24304bc 100644
--- a/src/os.c
+++ b/src/os.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/os.h b/src/os.h
index da4e09f..b21e6ed 100644
--- a/src/os.h
+++ b/src/os.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/qtype.c b/src/qtype.c
index 3f2a9fd..c41348f 100644
--- a/src/qtype.c
+++ b/src/qtype.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/qtype.h b/src/qtype.h
index 8c1a17d..87e157c 100644
--- a/src/qtype.h
+++ b/src/qtype.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/resperf-report b/src/resperf-report
index b3b7697..2d154bc 100755
--- a/src/resperf-report
+++ b/src/resperf-report
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright 2019-2021 OARC, Inc.
+# Copyright 2019-2022 OARC, Inc.
# Copyright 2017-2018 Akamai Technologies
# Copyright 2006-2016 Nominum, Inc.
# All rights reserved.
diff --git a/src/resperf.1.in b/src/resperf.1.in
index 8a37457..28f9bbb 100644
--- a/src/resperf.1.in
+++ b/src/resperf.1.in
@@ -1,4 +1,4 @@
-.\" Copyright 2019-2021 OARC, Inc.
+.\" Copyright 2019-2022 OARC, Inc.
.\" Copyright 2017-2018 Akamai Technologies
.\" Copyright 2006-2016 Nominum, Inc.
.\" All rights reserved.
diff --git a/src/resperf.c b/src/resperf.c
index ac41b38..aa58dc0 100644
--- a/src/resperf.c
+++ b/src/resperf.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
@@ -401,7 +401,7 @@ static void setup(int argc, char** argv)
perf_net_parselocal(server_addr.sa.sa.sa_family, local_name,
local_port, &local_addr);
- input = perf_datafile_open(filename);
+ input = perf_datafile_open(filename, input_format_text_query);
if (reopen_datafile) {
perf_datafile_setmaxruns(input, -1);
}
@@ -635,7 +635,7 @@ do_one_line(perf_buffer_t* lines, perf_buffer_t* msg)
}
perf_buffer_clear(lines);
- result = perf_datafile_next(input, lines, false);
+ result = perf_datafile_next(input, lines);
if (result != PERF_R_SUCCESS)
perf_log_fatal("ran out of query data");
perf_buffer_usedregion(lines, &used);
diff --git a/src/result.h b/src/result.h
index 076fcc5..7670a91 100644
--- a/src/result.h
+++ b/src/result.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/strerror.c b/src/strerror.c
index a283bc8..1a771f8 100644
--- a/src/strerror.c
+++ b/src/strerror.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/strerror.h b/src/strerror.h
index 72bca6d..915e06d 100644
--- a/src/strerror.h
+++ b/src/strerror.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
index 3c5e0d2..155e9cf 100644
--- a/src/test/Makefile.am
+++ b/src/test/Makefile.am
@@ -1,9 +1,15 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = test*.log test*.trs \
- test2.out test4.out test4err.out key.pem cert.pem test6.out
+ test2.out test4.out test4err.out key.pem cert.pem test6.out \
+ 10queries.tmp.blob 10queries.tmp.out empty.out emptypayload.out \
+ largesttcp.out largestudp.out missingpayload.out querywithcookie.out \
+ shortpayload.out tooshortlength.out twoquerieswithnsid.out
-TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh test6.sh
+TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh test6.sh test7.sh
EXTRA_DIST = $(TESTS) \
- datafile datafile2 updatefile datafile3 datafile4 datafile5 datafile6
+ datafile datafile2 updatefile datafile3 datafile4 datafile5 datafile6 \
+ empty.blob emptypayload.blob largesttcp.blob largestudp.blob \
+ missingpayload.blob querywithcookie.blob shortpayload.blob \
+ tooshortlength.blob twoquerieswithnsid.blob
diff --git a/src/test/Makefile.in b/src/test/Makefile.in
index 78b3759..04eafad 100644
--- a/src/test/Makefile.in
+++ b/src/test/Makefile.in
@@ -465,11 +465,17 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = test*.log test*.trs \
- test2.out test4.out test4err.out key.pem cert.pem test6.out
+ test2.out test4.out test4err.out key.pem cert.pem test6.out \
+ 10queries.tmp.blob 10queries.tmp.out empty.out emptypayload.out \
+ largesttcp.out largestudp.out missingpayload.out querywithcookie.out \
+ shortpayload.out tooshortlength.out twoquerieswithnsid.out
-TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh test6.sh
+TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh test6.sh test7.sh
EXTRA_DIST = $(TESTS) \
- datafile datafile2 updatefile datafile3 datafile4 datafile5 datafile6
+ datafile datafile2 updatefile datafile3 datafile4 datafile5 datafile6 \
+ empty.blob emptypayload.blob largesttcp.blob largestudp.blob \
+ missingpayload.blob querywithcookie.blob shortpayload.blob \
+ tooshortlength.blob twoquerieswithnsid.blob
all: all-am
@@ -701,6 +707,13 @@ test6.sh.log: test6.sh
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
+test7.sh.log: test7.sh
+ @p='test7.sh'; \
+ b='test7.sh'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
.test.log:
@p='$<'; \
$(am__set_b); \
diff --git a/src/test/empty.blob b/src/test/empty.blob
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/test/empty.blob
diff --git a/src/test/emptypayload.blob b/src/test/emptypayload.blob
new file mode 100644
index 0000000..09f370e
--- /dev/null
+++ b/src/test/emptypayload.blob
Binary files differ
diff --git a/src/test/largesttcp.blob b/src/test/largesttcp.blob
new file mode 100644
index 0000000..9608069
--- /dev/null
+++ b/src/test/largesttcp.blob
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/test/largestudp.blob b/src/test/largestudp.blob
new file mode 100644
index 0000000..cf58abd
--- /dev/null
+++ b/src/test/largestudp.blob
@@ -0,0 +1 @@
+ \ No newline at end of file
diff --git a/src/test/missingpayload.blob b/src/test/missingpayload.blob
new file mode 100644
index 0000000..bdc955b
--- /dev/null
+++ b/src/test/missingpayload.blob
Binary files differ
diff --git a/src/test/querywithcookie.blob b/src/test/querywithcookie.blob
new file mode 100644
index 0000000..d320083
--- /dev/null
+++ b/src/test/querywithcookie.blob
Binary files differ
diff --git a/src/test/shortpayload.blob b/src/test/shortpayload.blob
new file mode 100644
index 0000000..180cf4b
--- /dev/null
+++ b/src/test/shortpayload.blob
Binary files differ
diff --git a/src/test/test7.sh b/src/test/test7.sh
new file mode 100755
index 0000000..8e55905
--- /dev/null
+++ b/src/test/test7.sh
@@ -0,0 +1,83 @@
+#!/bin/sh -xe
+
+# expect non-zero exit code
+malformed_input_fmt() {
+ FILESTEM="$1"
+ ! ../dnsperf -vvv -B -d "$srcdir/$FILESTEM.blob" > "$FILESTEM.out" 2>&1
+ grep -F "Error: input file contains no data" "$FILESTEM.out"
+}
+
+malformed_input_fmt "empty"
+malformed_input_fmt "tooshortlength"
+malformed_input_fmt "missingpayload"
+
+test "$TEST_DNSPERF_WITH_NETWORK" = "1" || exit 0
+
+check_sent_and_lost() {
+ FILESTEM="$1"
+ EXPECTEDCOUNT="$2"
+ grep "Queries sent: $EXPECTEDCOUNT$" "$FILESTEM.out"
+ grep -F "Queries lost: $EXPECTEDCOUNT (" "$FILESTEM.out"
+}
+
+# send to an address which does not reply anyway;
+# typically for weird blobs which do not even have DNS header - so we cannot expect a response
+blackhole() {
+ FILESTEM="$1"
+ EXTRAARGS="$2"
+ EXPECTEDCOUNT="$3"
+ ../dnsperf -t 0.001 -vvv -B -d "$srcdir/$FILESTEM.blob" -s 192.0.2.1 $EXTRAARGS > "$FILESTEM.out" 2>&1
+ check_sent_and_lost "$FILESTEM" "$EXPECTEDCOUNT"
+}
+blackhole2() {
+ FILESTEM="$1"
+ EXTRAARGS="$2"
+ EXPECTEDCOUNT="$3"
+ ../dnsperf -t 0.001 -vvv -B -d "$FILESTEM.blob" -s 192.0.2.1 $EXTRAARGS > "$FILESTEM.out" 2>&1
+ check_sent_and_lost "$FILESTEM" "$EXPECTEDCOUNT"
+}
+
+blackhole "emptypayload" "" 1
+blackhole "shortpayload" "" 1
+blackhole "largestudp" "" 1
+# too large for UDP; at least it should not crash
+blackhole "largesttcp" "" 0
+grep -F 'failed to send packet' largesttcp.out
+
+# valid DNS queries as blobs
+expect_noerror() {
+ FILESTEM="$1"
+ EXTRAARGS="$2"
+ EXPECTEDCOUNT="$3"
+ ../dnsperf -vvv -B -d "$srcdir/$FILESTEM.blob" -s 1.1.1.1 $EXTRAARGS > "$FILESTEM.out" 2>&1
+ grep "Queries sent: $EXPECTEDCOUNT$" "$FILESTEM.out"
+ grep -F "Queries completed: $EXPECTEDCOUNT (" "$FILESTEM.out"
+}
+
+# single plain run
+expect_noerror "querywithcookie" "" 1
+
+# loop over the binary twice
+expect_noerror "querywithcookie" "-n 2" 2
+
+# multiple queries in one file
+expect_noerror "twoquerieswithnsid" "" 2
+
+# file too big to cache
+rm -f 10queries.tmp.blob
+cat "$srcdir/twoquerieswithnsid.blob" "$srcdir/querywithcookie.blob" "$srcdir/emptypayload.blob" \
+ "$srcdir/largestudp.blob" "$srcdir/twoquerieswithnsid.blob" "$srcdir/querywithcookie.blob" \
+ "$srcdir/emptypayload.blob" "$srcdir/largestudp.blob" \
+ > 10queries.tmp.blob
+blackhole2 "10queries.tmp" "" 10
+
+# repeat non-cacheable file the same twice
+blackhole2 "10queries.tmp" "-n 2" 20
+
+# large binary on stdin should work too
+cat 10queries.tmp.blob | ../dnsperf -t 0.001 -vvv -B -s 192.0.2.1 > "stdinlarge.out" 2>&1
+check_sent_and_lost "stdinlarge" 10
+
+# small binary on stdin
+cat "$srcdir/twoquerieswithnsid.blob" | ../dnsperf -t 0.001 -vvv -B -s 192.0.2.1 > "stdinsmall.out" 2>&1
+check_sent_and_lost "stdinsmall" 2
diff --git a/src/test/tooshortlength.blob b/src/test/tooshortlength.blob
new file mode 100644
index 0000000..f76dd23
--- /dev/null
+++ b/src/test/tooshortlength.blob
Binary files differ
diff --git a/src/test/twoquerieswithnsid.blob b/src/test/twoquerieswithnsid.blob
new file mode 100644
index 0000000..fb49f03
--- /dev/null
+++ b/src/test/twoquerieswithnsid.blob
Binary files differ
diff --git a/src/tsig.c b/src/tsig.c
index 0b660c1..ce10eea 100644
--- a/src/tsig.c
+++ b/src/tsig.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/tsig.h b/src/tsig.h
index ca4cf85..637b348 100644
--- a/src/tsig.h
+++ b/src/tsig.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.
diff --git a/src/util.h b/src/util.h
index 1b83487..c59e459 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2019-2021 OARC, Inc.
+ * Copyright 2019-2022 OARC, Inc.
* Copyright 2017-2018 Akamai Technologies
* Copyright 2006-2016 Nominum, Inc.
* All rights reserved.