summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/dnsjit/core/object/gre.c (renamed from src/output/null.hh)36
-rw-r--r--include/dnsjit/core/producer.c (renamed from src/input/zero.h)13
-rw-r--r--include/dnsjit/filter/copy.h (renamed from src/output/dnssim.h)13
-rw-r--r--include/dnsjit/filter/copy.hh (renamed from src/input/zero.hh)25
-rw-r--r--include/dnsjit/output/respdiff.h (renamed from src/output/null.h)12
-rwxr-xr-xinclude/dnsjit/test/test3.sh (renamed from src/test/test5.sh)8
-rw-r--r--src/Makefile.am37
-rw-r--r--src/Makefile.in1652
-rw-r--r--src/config.h.in295
-rw-r--r--src/core/assert.h2
-rw-r--r--src/core/channel.h6
-rw-r--r--src/core/file.c37
-rw-r--r--src/core/file.h26
-rw-r--r--src/core/file.hh21
-rw-r--r--src/core/file.lua37
-rw-r--r--src/core/loader.lua68
-rw-r--r--src/core/log.h2
-rw-r--r--src/core/object.h2
-rw-r--r--src/core/object/dns.h6
-rw-r--r--src/core/object/ether.h6
-rw-r--r--src/core/object/gre.h6
-rw-r--r--src/core/object/icmp.h6
-rw-r--r--src/core/object/icmp6.h6
-rw-r--r--src/core/object/ieee802.h6
-rw-r--r--src/core/object/ip.h6
-rw-r--r--src/core/object/ip6.h6
-rw-r--r--src/core/object/linuxsll.h6
-rw-r--r--src/core/object/loop.h6
-rw-r--r--src/core/object/null.h6
-rw-r--r--src/core/object/payload.h6
-rw-r--r--src/core/object/pcap.h6
-rw-r--r--src/core/object/tcp.h6
-rw-r--r--src/core/object/udp.h6
-rw-r--r--src/core/producer.h4
-rw-r--r--src/core/receiver.h4
-rw-r--r--src/core/thread.h4
-rw-r--r--src/core/timespec.h2
-rw-r--r--src/core/timespec.lua26
-rw-r--r--src/dnsjit.c11
-rw-r--r--src/filter/copy.h8
-rw-r--r--src/filter/ipsplit.h6
-rw-r--r--src/filter/layer.h36
-rw-r--r--src/filter/split.h6
-rw-r--r--src/filter/timing.h8
-rwxr-xr-xsrc/gen-makefile.sh130
-rw-r--r--src/gen-manpage.lua5
-rw-r--r--src/input.lua3
-rw-r--r--src/input/fpcap.c13
-rw-r--r--src/input/fpcap.h10
-rw-r--r--src/input/fpcap.hh2
-rw-r--r--src/input/fpcap.lua9
-rw-r--r--src/input/mmpcap.h10
-rw-r--r--src/input/pcap.h10
-rw-r--r--src/input/zero.c75
-rw-r--r--src/input/zero.lua58
-rw-r--r--src/input/zpcap.c582
-rw-r--r--src/input/zpcap.h31
-rw-r--r--src/input/zpcap.hh77
-rw-r--r--src/input/zpcap.lua159
-rw-r--r--src/lib/base64url.h2
-rw-r--r--src/lib/base64url.lua3
-rw-r--r--src/lib/clock.h4
-rw-r--r--src/lib/getopt.lua3
-rw-r--r--src/lib/trie.h2
-rw-r--r--src/output.lua1
-rw-r--r--src/output/dnscli.h14
-rw-r--r--src/output/dnssim.c502
-rw-r--r--src/output/dnssim.hh123
-rw-r--r--src/output/dnssim.lua433
-rw-r--r--src/output/dnssim/CHANGELOG.md16
-rw-r--r--src/output/dnssim/common.c384
-rw-r--r--src/output/dnssim/connection.c471
-rw-r--r--src/output/dnssim/https2.c592
-rw-r--r--src/output/dnssim/internal.h343
-rw-r--r--src/output/dnssim/ll.h83
-rw-r--r--src/output/dnssim/tcp.c356
-rw-r--r--src/output/dnssim/tls.c475
-rw-r--r--src/output/dnssim/udp.c156
-rw-r--r--src/output/null.c87
-rw-r--r--src/output/null.lua63
-rw-r--r--src/output/pcap.c9
-rw-r--r--src/output/pcap.h8
-rw-r--r--src/output/pcap.hh1
-rw-r--r--src/output/pcap.lua14
-rw-r--r--src/output/respdiff.h6
-rw-r--r--src/output/tcpcli.h12
-rw-r--r--src/output/tlscli.h12
-rw-r--r--src/output/udpcli.h12
-rw-r--r--src/test/Makefile.am17
-rw-r--r--src/test/Makefile.in947
-rw-r--r--src/test/dns.pcap.lz4bin0 -> 7560 bytes
-rw-r--r--src/test/dns.pcap.zstbin0 -> 3972 bytes
-rwxr-xr-xsrc/test/test1.sh10
-rw-r--r--src/test/test_compressupport.lua10
-rw-r--r--src/version.h28
95 files changed, 4299 insertions, 4571 deletions
diff --git a/src/output/null.hh b/include/dnsjit/core/object/gre.c
index 3f5cd33..9a467c3 100644
--- a/src/output/null.hh
+++ b/include/dnsjit/core/object/gre.c
@@ -18,20 +18,28 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-//lua:require("dnsjit.core.log")
-//lua:require("dnsjit.core.receiver_h")
-//lua:require("dnsjit.core.producer_h")
+#include "config.h"
-typedef struct output_null {
- core_log_t _log;
- core_producer_t prod;
- void* ctx;
- size_t pkts;
-} output_null_t;
+#include "core/object/gre.h"
+#include "core/assert.h"
-core_log_t* output_null_log();
-void output_null_init(output_null_t* self);
-void output_null_destroy(output_null_t* self);
-void output_null_run(output_null_t* self, int64_t num);
+#include <stdlib.h>
+#include <string.h>
-core_receiver_t output_null_receiver();
+core_object_gre_t* core_object_gre_copy(const core_object_gre_t* self)
+{
+ core_object_gre_t* copy;
+ glassert_self();
+
+ glfatal_oom(copy = malloc(sizeof(core_object_gre_t)));
+ memcpy(copy, self, sizeof(core_object_gre_t));
+ copy->obj_prev = 0;
+
+ return copy;
+}
+
+void core_object_gre_free(core_object_gre_t* self)
+{
+ glassert_self();
+ free(self);
+}
diff --git a/src/input/zero.h b/include/dnsjit/core/producer.c
index 882525a..8a85c93 100644
--- a/src/input/zero.h
+++ b/include/dnsjit/core/producer.c
@@ -18,15 +18,6 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
-
-#ifndef __dnsjit_input_zero_h
-#define __dnsjit_input_zero_h
-
-#include <stdint.h>
+#include "config.h"
-#include "input/zero.hh"
-
-#endif
+#include "core/producer.h"
diff --git a/src/output/dnssim.h b/include/dnsjit/filter/copy.h
index f843000..d65a552 100644
--- a/src/output/dnssim.h
+++ b/include/dnsjit/filter/copy.h
@@ -18,14 +18,13 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/receiver.h>
-#ifndef __dnsjit_output_dnssim_h
-#define __dnsjit_output_dnssim_h
+#ifndef __dnsjit_filter_copy_h
+#define __dnsjit_filter_copy_h
-#include <stdbool.h>
-
-#include "output/dnssim.hh"
+#include <dnsjit/filter/copy.hh>
#endif
diff --git a/src/input/zero.hh b/include/dnsjit/filter/copy.hh
index 9373c90..edf7fc7 100644
--- a/src/input/zero.hh
+++ b/include/dnsjit/filter/copy.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2021, OARC, Inc.
+ * Copyright (c) 2019, CZ.NIC z.s.p.o.
* All rights reserved.
*
* This file is part of dnsjit.
@@ -20,18 +20,21 @@
//lua:require("dnsjit.core.log")
//lua:require("dnsjit.core.receiver_h")
-//lua:require("dnsjit.core.producer_h")
-typedef struct input_zero {
- core_log_t _log;
+typedef struct filter_copy {
+ core_log_t _log;
+
core_receiver_t recv;
- void* ctx;
-} input_zero_t;
+ void* recv_ctx;
+
+ uint64_t copy;
+} filter_copy_t;
-core_log_t* input_zero_log();
+core_log_t* filter_copy_log();
-void input_zero_init(input_zero_t* self);
-void input_zero_destroy(input_zero_t* self);
-void input_zero_run(input_zero_t* self, uint64_t num);
+void filter_copy_init(filter_copy_t* self);
+void filter_copy_destroy(filter_copy_t* self);
+void filter_copy_set(filter_copy_t* self, int32_t obj_type);
+uint64_t filter_copy_get(filter_copy_t* self, int32_t obj_type);
-core_producer_t input_zero_producer();
+core_receiver_t filter_copy_receiver(filter_copy_t* self);
diff --git a/src/output/null.h b/include/dnsjit/output/respdiff.h
index b8ccf70..207e225 100644
--- a/src/output/null.h
+++ b/include/dnsjit/output/respdiff.h
@@ -18,16 +18,14 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
-#ifndef __dnsjit_output_null_h
-#define __dnsjit_output_null_h
+#ifndef __dnsjit_output_respdiff_h
+#define __dnsjit_output_respdiff_h
-#include <stddef.h>
#include <stdint.h>
-#include "output/null.hh"
+#include <dnsjit/output/respdiff.hh>
#endif
diff --git a/src/test/test5.sh b/include/dnsjit/test/test3.sh
index f766e00..b9a0b64 100755
--- a/src/test/test5.sh
+++ b/include/dnsjit/test/test3.sh
@@ -17,8 +17,6 @@
# You should have received a copy of the GNU General Public License
# along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
-../dnsjit "$srcdir/../../examples/test_throughput.lua" -vvvvv -t -s 1000000
-../dnsjit "$srcdir/../../examples/test_pcap_read.lua" -vvvvv dns.pcap-dist
-../dnsjit "$srcdir/../../examples/test_pcap_read.lua" -l -vvvvv dns.pcap-dist
-../dnsjit "$srcdir/../../examples/test_pcap_read.lua" -p -vvvvv dns.pcap-dist
-../dnsjit "$srcdir/../../examples/test_pcap_read.lua" -l -p -vvvvv dns.pcap-dist
+../dnsjit "$srcdir/../../examples/filter_rcode.lua" dns.pcap-dist 0 >test3.out
+../dnsjit "$srcdir/../../examples/filter_rcode.lua" dns.pcap-dist 1 >>test3.out
+diff "$srcdir/test3.gold" test3.out
diff --git a/src/Makefile.am b/src/Makefile.am
index 96f8b31..3090342 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,11 +24,11 @@ SUBDIRS = test
AM_CFLAGS = -Werror=attributes \
-I$(srcdir) \
-I$(top_srcdir) \
+ -I$(top_srcdir)/include \
$(SIMD_FLAGS) $(CPUEXT_FLAGS) \
$(PTHREAD_CFLAGS) \
$(luajit_CFLAGS) \
- $(libuv_CFLAGS) \
- $(libnghttp2_CFLAGS)
+ $(liblz4_CFLAGS) $(libzstd_CFLAGS)
EXTRA_DIST = gen-manpage.lua gen-compat.lua gen-errno.sh dnsjit.1in
@@ -37,23 +37,24 @@ BUILT_SOURCES = core/compat.hh core/log_errstr.c
bin_PROGRAMS = dnsjit
dnsjit_SOURCES = dnsjit.c globals.c
-dist_dnsjit_SOURCES = core.lua lib.lua input.lua filter.lua globals.h \
- output.lua
+dist_dnsjit_SOURCES = core.lua lib.lua input.lua filter.lua output.lua
+dnsjitincludedir = $(includedir)/dnsjit
+nobase_dnsjitinclude_HEADERS = globals.h version.h
lua_hobjects = core/compat.luaho
lua_objects = core.luao lib.luao input.luao filter.luao output.luao
-dnsjit_LDADD = $(PTHREAD_LIBS) $(luajit_LIBS) $(libuv_LIBS) $(libnghttp2_LIBS)
+dnsjit_LDADD = $(PTHREAD_LIBS) $(luajit_LIBS) $(liblz4_LIBS) $(libzstd_LIBS)
# C source and headers
-dnsjit_SOURCES += core/channel.c core/compat.c core/log.c core/object.c core/object/dns.c core/object/ether.c core/object/gre.c core/object/icmp6.c core/object/icmp.c core/object/ieee802.c core/object/ip6.c core/object/ip.c core/object/linuxsll.c core/object/loop.c core/object/null.c core/object/payload.c core/object/pcap.c core/object/tcp.c core/object/udp.c core/producer.c core/receiver.c core/thread.c filter/copy.c filter/ipsplit.c filter/layer.c filter/split.c filter/timing.c input/fpcap.c input/mmpcap.c input/pcap.c input/zero.c lib/base64url.c lib/clock.c lib/trie.c output/dnscli.c output/dnssim.c output/dnssim/common.c output/dnssim/connection.c output/dnssim/https2.c output/dnssim/tcp.c output/dnssim/tls.c output/dnssim/udp.c output/null.c output/pcap.c output/respdiff.c output/tcpcli.c output/tlscli.c output/udpcli.c
-dist_dnsjit_SOURCES += core/assert.h core/channel.h core/compat.h core/log.h core/object/dns.h core/object/ether.h core/object/gre.h core/object.h core/object/icmp6.h core/object/icmp.h core/object/ieee802.h core/object/ip6.h core/object/ip.h core/object/linuxsll.h core/object/loop.h core/object/null.h core/object/payload.h core/object/pcap.h core/object/tcp.h core/object/udp.h core/producer.h core/receiver.h core/thread.h core/timespec.h filter/copy.h filter/ipsplit.h filter/layer.h filter/split.h filter/timing.h input/fpcap.h input/mmpcap.h input/pcap.h input/zero.h lib/base64url.h lib/clock.h lib/trie.h output/dnscli.h output/dnssim.h output/dnssim/internal.h output/dnssim/ll.h output/null.h output/pcap.h output/respdiff.h output/tcpcli.h output/tlscli.h output/udpcli.h
+dnsjit_SOURCES += core/channel.c core/compat.c core/file.c core/log.c core/object.c core/object/dns.c core/object/ether.c core/object/gre.c core/object/icmp6.c core/object/icmp.c core/object/ieee802.c core/object/ip6.c core/object/ip.c core/object/linuxsll.c core/object/loop.c core/object/null.c core/object/payload.c core/object/pcap.c core/object/tcp.c core/object/udp.c core/producer.c core/receiver.c core/thread.c filter/copy.c filter/ipsplit.c filter/layer.c filter/split.c filter/timing.c input/fpcap.c input/mmpcap.c input/pcap.c input/zpcap.c lib/base64url.c lib/clock.c lib/trie.c output/dnscli.c output/pcap.c output/respdiff.c output/tcpcli.c output/tlscli.c output/udpcli.c
+nobase_dnsjitinclude_HEADERS += core/assert.h core/channel.h core/compat.h core/file.h core/log.h core/object/dns.h core/object/ether.h core/object/gre.h core/object.h core/object/icmp6.h core/object/icmp.h core/object/ieee802.h core/object/ip6.h core/object/ip.h core/object/linuxsll.h core/object/loop.h core/object/null.h core/object/payload.h core/object/pcap.h core/object/tcp.h core/object/udp.h core/producer.h core/receiver.h core/thread.h core/timespec.h filter/copy.h filter/ipsplit.h filter/layer.h filter/split.h filter/timing.h input/fpcap.h input/mmpcap.h input/pcap.h input/zpcap.h lib/base64url.h lib/clock.h lib/trie.h output/dnscli.h output/pcap.h output/respdiff.h output/tcpcli.h output/tlscli.h output/udpcli.h
# Lua headers
-dist_dnsjit_SOURCES += core/channel.hh core/log.hh core/object/dns.hh core/object/ether.hh core/object/gre.hh core/object.hh core/object/icmp6.hh core/object/icmp.hh core/object/ieee802.hh core/object/ip6.hh core/object/ip.hh core/object/linuxsll.hh core/object/loop.hh core/object/null.hh core/object/payload.hh core/object/pcap.hh core/object/tcp.hh core/object/udp.hh core/producer.hh core/receiver.hh core/thread.hh core/timespec.hh filter/copy.hh filter/ipsplit.hh filter/layer.hh filter/split.hh filter/timing.hh input/fpcap.hh input/mmpcap.hh input/pcap.hh input/zero.hh lib/base64url.hh lib/clock.hh lib/trie.hh output/dnscli.hh output/dnssim.hh output/null.hh output/pcap.hh output/respdiff.hh output/tcpcli.hh output/tlscli.hh output/udpcli.hh
-lua_hobjects += core/channel.luaho core/log.luaho core/object/dns.luaho core/object/ether.luaho core/object/gre.luaho core/object/icmp6.luaho core/object/icmp.luaho core/object/ieee802.luaho core/object/ip6.luaho core/object/ip.luaho core/object/linuxsll.luaho core/object/loop.luaho core/object.luaho core/object/null.luaho core/object/payload.luaho core/object/pcap.luaho core/object/tcp.luaho core/object/udp.luaho core/producer.luaho core/receiver.luaho core/thread.luaho core/timespec.luaho filter/copy.luaho filter/ipsplit.luaho filter/layer.luaho filter/split.luaho filter/timing.luaho input/fpcap.luaho input/mmpcap.luaho input/pcap.luaho input/zero.luaho lib/base64url.luaho lib/clock.luaho lib/trie.luaho output/dnscli.luaho output/dnssim.luaho output/null.luaho output/pcap.luaho output/respdiff.luaho output/tcpcli.luaho output/tlscli.luaho output/udpcli.luaho
+nobase_dnsjitinclude_HEADERS += core/channel.hh core/file.hh core/log.hh core/object/dns.hh core/object/ether.hh core/object/gre.hh core/object.hh core/object/icmp6.hh core/object/icmp.hh core/object/ieee802.hh core/object/ip6.hh core/object/ip.hh core/object/linuxsll.hh core/object/loop.hh core/object/null.hh core/object/payload.hh core/object/pcap.hh core/object/tcp.hh core/object/udp.hh core/producer.hh core/receiver.hh core/thread.hh core/timespec.hh filter/copy.hh filter/ipsplit.hh filter/layer.hh filter/split.hh filter/timing.hh input/fpcap.hh input/mmpcap.hh input/pcap.hh input/zpcap.hh lib/base64url.hh lib/clock.hh lib/trie.hh output/dnscli.hh output/pcap.hh output/respdiff.hh output/tcpcli.hh output/tlscli.hh output/udpcli.hh
+lua_hobjects += core/channel.luaho core/file.luaho core/log.luaho core/object/dns.luaho core/object/ether.luaho core/object/gre.luaho core/object/icmp6.luaho core/object/icmp.luaho core/object/ieee802.luaho core/object/ip6.luaho core/object/ip.luaho core/object/linuxsll.luaho core/object/loop.luaho core/object.luaho core/object/null.luaho core/object/payload.luaho core/object/pcap.luaho core/object/tcp.luaho core/object/udp.luaho core/producer.luaho core/receiver.luaho core/thread.luaho core/timespec.luaho filter/copy.luaho filter/ipsplit.luaho filter/layer.luaho filter/split.luaho filter/timing.luaho input/fpcap.luaho input/mmpcap.luaho input/pcap.luaho input/zpcap.luaho lib/base64url.luaho lib/clock.luaho lib/trie.luaho output/dnscli.luaho output/pcap.luaho output/respdiff.luaho output/tcpcli.luaho output/tlscli.luaho output/udpcli.luaho
# Lua sources
-dist_dnsjit_SOURCES += core/channel.lua core/compat.lua core/log.lua core/object/dns/label.lua core/object/dns.lua core/object/dns/q.lua core/object/dns/rr.lua core/object/ether.lua core/object/gre.lua core/object/icmp6.lua core/object/icmp.lua core/object/ieee802.lua core/object/ip6.lua core/object/ip.lua core/object/linuxsll.lua core/object/loop.lua core/object.lua core/object/null.lua core/object/payload.lua core/object/pcap.lua core/objects.lua core/object/tcp.lua core/object/udp.lua core/producer.lua core/receiver.lua core/thread.lua core/timespec.lua filter/copy.lua filter/ipsplit.lua filter/layer.lua filter/split.lua filter/timing.lua input/fpcap.lua input/mmpcap.lua input/pcap.lua input/zero.lua lib/base64url.lua lib/clock.lua lib/getopt.lua lib/ip.lua lib/parseconf.lua lib/trie/iter.lua lib/trie.lua lib/trie/node.lua output/dnscli.lua output/dnssim.lua output/null.lua output/pcap.lua output/respdiff.lua output/tcpcli.lua output/tlscli.lua output/udpcli.lua
-lua_objects += core/channel.luao core/compat.luao core/log.luao core/object/dns/label.luao core/object/dns.luao core/object/dns/q.luao core/object/dns/rr.luao core/object/ether.luao core/object/gre.luao core/object/icmp6.luao core/object/icmp.luao core/object/ieee802.luao core/object/ip6.luao core/object/ip.luao core/object/linuxsll.luao core/object/loop.luao core/object.luao core/object/null.luao core/object/payload.luao core/object/pcap.luao core/objects.luao core/object/tcp.luao core/object/udp.luao core/producer.luao core/receiver.luao core/thread.luao core/timespec.luao filter/copy.luao filter/ipsplit.luao filter/layer.luao filter/split.luao filter/timing.luao input/fpcap.luao input/mmpcap.luao input/pcap.luao input/zero.luao lib/base64url.luao lib/clock.luao lib/getopt.luao lib/ip.luao lib/parseconf.luao lib/trie/iter.luao lib/trie.luao lib/trie/node.luao output/dnscli.luao output/dnssim.luao output/null.luao output/pcap.luao output/respdiff.luao output/tcpcli.luao output/tlscli.luao output/udpcli.luao
+dist_dnsjit_SOURCES += core/channel.lua core/compat.lua core/file.lua core/loader.lua core/log.lua core/object/dns/label.lua core/object/dns.lua core/object/dns/q.lua core/object/dns/rr.lua core/object/ether.lua core/object/gre.lua core/object/icmp6.lua core/object/icmp.lua core/object/ieee802.lua core/object/ip6.lua core/object/ip.lua core/object/linuxsll.lua core/object/loop.lua core/object.lua core/object/null.lua core/object/payload.lua core/object/pcap.lua core/objects.lua core/object/tcp.lua core/object/udp.lua core/producer.lua core/receiver.lua core/thread.lua core/timespec.lua filter/copy.lua filter/ipsplit.lua filter/layer.lua filter/split.lua filter/timing.lua input/fpcap.lua input/mmpcap.lua input/pcap.lua input/zero.lua input/zpcap.lua lib/base64url.lua lib/clock.lua lib/getopt.lua lib/ip.lua lib/parseconf.lua lib/trie/iter.lua lib/trie.lua lib/trie/node.lua output/dnscli.lua output/null.lua output/pcap.lua output/respdiff.lua output/tcpcli.lua output/tlscli.lua output/udpcli.lua
+lua_objects += core/channel.luao core/compat.luao core/file.luao core/loader.luao core/log.luao core/object/dns/label.luao core/object/dns.luao core/object/dns/q.luao core/object/dns/rr.luao core/object/ether.luao core/object/gre.luao core/object/icmp6.luao core/object/icmp.luao core/object/ieee802.luao core/object/ip6.luao core/object/ip.luao core/object/linuxsll.luao core/object/loop.luao core/object.luao core/object/null.luao core/object/payload.luao core/object/pcap.luao core/objects.luao core/object/tcp.luao core/object/udp.luao core/producer.luao core/receiver.luao core/thread.luao core/timespec.luao filter/copy.luao filter/ipsplit.luao filter/layer.luao filter/split.luao filter/timing.luao input/fpcap.luao input/mmpcap.luao input/pcap.luao input/zero.luao input/zpcap.luao lib/base64url.luao lib/clock.luao lib/getopt.luao lib/ip.luao lib/parseconf.luao lib/trie/iter.luao lib/trie.luao lib/trie/node.luao output/dnscli.luao output/null.luao output/pcap.luao output/respdiff.luao output/tcpcli.luao output/tlscli.luao output/udpcli.luao
dnsjit_LDFLAGS = -Wl,-E
dnsjit_LDADD += $(lua_hobjects) $(lua_objects)
@@ -63,7 +64,7 @@ man1_MANS = dnsjit.1
CLEANFILES += $(man1_MANS)
man3_MANS = dnsjit.core.3 dnsjit.lib.3 dnsjit.input.3 dnsjit.filter.3 dnsjit.output.3
-man3_MANS += dnsjit.core.channel.3 dnsjit.core.compat.3 dnsjit.core.log.3 dnsjit.core.object.3 dnsjit.core.object.dns.3 dnsjit.core.object.dns.label.3 dnsjit.core.object.dns.q.3 dnsjit.core.object.dns.rr.3 dnsjit.core.object.ether.3 dnsjit.core.object.gre.3 dnsjit.core.object.icmp.3 dnsjit.core.object.icmp6.3 dnsjit.core.object.ieee802.3 dnsjit.core.object.ip.3 dnsjit.core.object.ip6.3 dnsjit.core.object.linuxsll.3 dnsjit.core.object.loop.3 dnsjit.core.object.null.3 dnsjit.core.object.payload.3 dnsjit.core.object.pcap.3 dnsjit.core.objects.3 dnsjit.core.object.tcp.3 dnsjit.core.object.udp.3 dnsjit.core.producer.3 dnsjit.core.receiver.3 dnsjit.core.thread.3 dnsjit.core.timespec.3 dnsjit.filter.copy.3 dnsjit.filter.ipsplit.3 dnsjit.filter.layer.3 dnsjit.filter.split.3 dnsjit.filter.timing.3 dnsjit.input.fpcap.3 dnsjit.input.mmpcap.3 dnsjit.input.pcap.3 dnsjit.input.zero.3 dnsjit.lib.base64url.3 dnsjit.lib.clock.3 dnsjit.lib.getopt.3 dnsjit.lib.ip.3 dnsjit.lib.parseconf.3 dnsjit.lib.trie.3 dnsjit.lib.trie.iter.3 dnsjit.lib.trie.node.3 dnsjit.output.dnscli.3 dnsjit.output.dnssim.3 dnsjit.output.null.3 dnsjit.output.pcap.3 dnsjit.output.respdiff.3 dnsjit.output.tcpcli.3 dnsjit.output.tlscli.3 dnsjit.output.udpcli.3
+man3_MANS += dnsjit.core.channel.3 dnsjit.core.compat.3 dnsjit.core.file.3 dnsjit.core.loader.3 dnsjit.core.log.3 dnsjit.core.object.3 dnsjit.core.object.dns.3 dnsjit.core.object.dns.label.3 dnsjit.core.object.dns.q.3 dnsjit.core.object.dns.rr.3 dnsjit.core.object.ether.3 dnsjit.core.object.gre.3 dnsjit.core.object.icmp.3 dnsjit.core.object.icmp6.3 dnsjit.core.object.ieee802.3 dnsjit.core.object.ip.3 dnsjit.core.object.ip6.3 dnsjit.core.object.linuxsll.3 dnsjit.core.object.loop.3 dnsjit.core.object.null.3 dnsjit.core.object.payload.3 dnsjit.core.object.pcap.3 dnsjit.core.objects.3 dnsjit.core.object.tcp.3 dnsjit.core.object.udp.3 dnsjit.core.producer.3 dnsjit.core.receiver.3 dnsjit.core.thread.3 dnsjit.core.timespec.3 dnsjit.filter.copy.3 dnsjit.filter.ipsplit.3 dnsjit.filter.layer.3 dnsjit.filter.split.3 dnsjit.filter.timing.3 dnsjit.input.fpcap.3 dnsjit.input.mmpcap.3 dnsjit.input.pcap.3 dnsjit.input.zero.3 dnsjit.input.zpcap.3 dnsjit.lib.base64url.3 dnsjit.lib.clock.3 dnsjit.lib.getopt.3 dnsjit.lib.ip.3 dnsjit.lib.parseconf.3 dnsjit.lib.trie.3 dnsjit.lib.trie.iter.3 dnsjit.lib.trie.node.3 dnsjit.output.dnscli.3 dnsjit.output.null.3 dnsjit.output.pcap.3 dnsjit.output.respdiff.3 dnsjit.output.tcpcli.3 dnsjit.output.tlscli.3 dnsjit.output.udpcli.3
CLEANFILES += *.3in $(man3_MANS)
.lua.luao:
@@ -129,6 +130,12 @@ dnsjit.core.channel.3in: core/channel.lua gen-manpage.lua
dnsjit.core.compat.3in: core/compat.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/compat.lua" > "$@"
+dnsjit.core.file.3in: core/file.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/file.lua" > "$@"
+
+dnsjit.core.loader.3in: core/loader.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/loader.lua" > "$@"
+
dnsjit.core.log.3in: core/log.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/log.lua" > "$@"
@@ -231,6 +238,9 @@ dnsjit.input.pcap.3in: input/pcap.lua gen-manpage.lua
dnsjit.input.zero.3in: input/zero.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/zero.lua" > "$@"
+dnsjit.input.zpcap.3in: input/zpcap.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/zpcap.lua" > "$@"
+
dnsjit.lib.base64url.3in: lib/base64url.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/base64url.lua" > "$@"
@@ -258,9 +268,6 @@ dnsjit.lib.trie.node.3in: lib/trie/node.lua gen-manpage.lua
dnsjit.output.dnscli.3in: output/dnscli.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/dnscli.lua" > "$@"
-dnsjit.output.dnssim.3in: output/dnssim.lua gen-manpage.lua
- $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/dnssim.lua" > "$@"
-
dnsjit.output.null.3in: output/null.lua gen-manpage.lua
$(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/null.lua" > "$@"
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..7449ba5
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,1652 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2018-2021, OARC, Inc.
+# All rights reserved.
+#
+# This file is part of dnsjit.
+#
+# dnsjit 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.
+#
+# dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = dnsjit$(EXEEXT)
+subdir = src
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
+ $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+ $(top_srcdir)/m4/ax_compiler_vendor.m4 \
+ $(top_srcdir)/m4/ax_ext.m4 \
+ $(top_srcdir)/m4/ax_gcc_x86_avx_xgetbv.m4 \
+ $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
+ $(top_srcdir)/m4/ax_prepend_flag.m4 \
+ $(top_srcdir)/m4/ax_pthread.m4 \
+ $(top_srcdir)/m4/ax_require_defined.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(nobase_dnsjitinclude_HEADERS) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \
+ "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(dnsjitincludedir)"
+PROGRAMS = $(bin_PROGRAMS)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_dnsjit_OBJECTS = dnsjit.$(OBJEXT) globals.$(OBJEXT) \
+ core/channel.$(OBJEXT) core/compat.$(OBJEXT) \
+ core/file.$(OBJEXT) core/log.$(OBJEXT) core/object.$(OBJEXT) \
+ core/object/dns.$(OBJEXT) core/object/ether.$(OBJEXT) \
+ core/object/gre.$(OBJEXT) core/object/icmp6.$(OBJEXT) \
+ core/object/icmp.$(OBJEXT) core/object/ieee802.$(OBJEXT) \
+ core/object/ip6.$(OBJEXT) core/object/ip.$(OBJEXT) \
+ core/object/linuxsll.$(OBJEXT) core/object/loop.$(OBJEXT) \
+ core/object/null.$(OBJEXT) core/object/payload.$(OBJEXT) \
+ core/object/pcap.$(OBJEXT) core/object/tcp.$(OBJEXT) \
+ core/object/udp.$(OBJEXT) core/producer.$(OBJEXT) \
+ core/receiver.$(OBJEXT) core/thread.$(OBJEXT) \
+ filter/copy.$(OBJEXT) filter/ipsplit.$(OBJEXT) \
+ filter/layer.$(OBJEXT) filter/split.$(OBJEXT) \
+ filter/timing.$(OBJEXT) input/fpcap.$(OBJEXT) \
+ input/mmpcap.$(OBJEXT) input/pcap.$(OBJEXT) \
+ input/zpcap.$(OBJEXT) lib/base64url.$(OBJEXT) \
+ lib/clock.$(OBJEXT) lib/trie.$(OBJEXT) output/dnscli.$(OBJEXT) \
+ output/pcap.$(OBJEXT) output/respdiff.$(OBJEXT) \
+ output/tcpcli.$(OBJEXT) output/tlscli.$(OBJEXT) \
+ output/udpcli.$(OBJEXT)
+dist_dnsjit_OBJECTS =
+dnsjit_OBJECTS = $(am_dnsjit_OBJECTS) $(dist_dnsjit_OBJECTS)
+am__DEPENDENCIES_1 =
+dnsjit_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) $(lua_hobjects) \
+ $(lua_objects)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+dnsjit_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(dnsjit_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/dnsjit.Po ./$(DEPDIR)/globals.Po \
+ core/$(DEPDIR)/channel.Po core/$(DEPDIR)/compat.Po \
+ core/$(DEPDIR)/file.Po core/$(DEPDIR)/log.Po \
+ core/$(DEPDIR)/object.Po core/$(DEPDIR)/producer.Po \
+ core/$(DEPDIR)/receiver.Po core/$(DEPDIR)/thread.Po \
+ core/object/$(DEPDIR)/dns.Po core/object/$(DEPDIR)/ether.Po \
+ core/object/$(DEPDIR)/gre.Po core/object/$(DEPDIR)/icmp.Po \
+ core/object/$(DEPDIR)/icmp6.Po \
+ core/object/$(DEPDIR)/ieee802.Po core/object/$(DEPDIR)/ip.Po \
+ core/object/$(DEPDIR)/ip6.Po core/object/$(DEPDIR)/linuxsll.Po \
+ core/object/$(DEPDIR)/loop.Po core/object/$(DEPDIR)/null.Po \
+ core/object/$(DEPDIR)/payload.Po core/object/$(DEPDIR)/pcap.Po \
+ core/object/$(DEPDIR)/tcp.Po core/object/$(DEPDIR)/udp.Po \
+ filter/$(DEPDIR)/copy.Po filter/$(DEPDIR)/ipsplit.Po \
+ filter/$(DEPDIR)/layer.Po filter/$(DEPDIR)/split.Po \
+ filter/$(DEPDIR)/timing.Po input/$(DEPDIR)/fpcap.Po \
+ input/$(DEPDIR)/mmpcap.Po input/$(DEPDIR)/pcap.Po \
+ input/$(DEPDIR)/zpcap.Po lib/$(DEPDIR)/base64url.Po \
+ lib/$(DEPDIR)/clock.Po lib/$(DEPDIR)/trie.Po \
+ output/$(DEPDIR)/dnscli.Po output/$(DEPDIR)/pcap.Po \
+ output/$(DEPDIR)/respdiff.Po output/$(DEPDIR)/tcpcli.Po \
+ output/$(DEPDIR)/tlscli.Po output/$(DEPDIR)/udpcli.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(dnsjit_SOURCES) $(dist_dnsjit_SOURCES)
+DIST_SOURCES = $(dnsjit_SOURCES) $(dist_dnsjit_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+man1dir = $(mandir)/man1
+man3dir = $(mandir)/man3
+NROFF = nroff
+MANS = $(man1_MANS) $(man3_MANS)
+HEADERS = $(nobase_dnsjitinclude_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir distdir-am
+am__extra_recursive_targets = gcov-recursive
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+ $(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(top_srcdir)/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPUEXT_FLAGS = @CPUEXT_FLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LUAJIT = @LUAJIT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIMD_FLAGS = @SIMD_FLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+ck_CFLAGS = @ck_CFLAGS@
+ck_LIBS = @ck_LIBS@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+liblz4_CFLAGS = @liblz4_CFLAGS@
+liblz4_LIBS = @liblz4_LIBS@
+libzstd_CFLAGS = @libzstd_CFLAGS@
+libzstd_LIBS = @libzstd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+luajit_CFLAGS = @luajit_CFLAGS@
+luajit_LIBS = @luajit_LIBS@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+CLEANFILES = *.gcda *.gcno *.gcov $(lua_hobjects) $(lua_objects) \
+ $(man1_MANS) *.3in $(man3_MANS)
+SUBDIRS = test
+AM_CFLAGS = -Werror=attributes \
+ -I$(srcdir) \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/include \
+ $(SIMD_FLAGS) $(CPUEXT_FLAGS) \
+ $(PTHREAD_CFLAGS) \
+ $(luajit_CFLAGS) \
+ $(liblz4_CFLAGS) $(libzstd_CFLAGS)
+
+EXTRA_DIST = gen-manpage.lua gen-compat.lua gen-errno.sh dnsjit.1in
+BUILT_SOURCES = core/compat.hh core/log_errstr.c
+
+# C source and headers
+dnsjit_SOURCES = dnsjit.c globals.c core/channel.c core/compat.c \
+ core/file.c core/log.c core/object.c core/object/dns.c \
+ core/object/ether.c core/object/gre.c core/object/icmp6.c \
+ core/object/icmp.c core/object/ieee802.c core/object/ip6.c \
+ core/object/ip.c core/object/linuxsll.c core/object/loop.c \
+ core/object/null.c core/object/payload.c core/object/pcap.c \
+ core/object/tcp.c core/object/udp.c core/producer.c \
+ core/receiver.c core/thread.c filter/copy.c filter/ipsplit.c \
+ filter/layer.c filter/split.c filter/timing.c input/fpcap.c \
+ input/mmpcap.c input/pcap.c input/zpcap.c lib/base64url.c \
+ lib/clock.c lib/trie.c output/dnscli.c output/pcap.c \
+ output/respdiff.c output/tcpcli.c output/tlscli.c \
+ output/udpcli.c
+
+# Lua sources
+dist_dnsjit_SOURCES = core.lua lib.lua input.lua filter.lua output.lua \
+ core/channel.lua core/compat.lua core/file.lua core/loader.lua \
+ core/log.lua core/object/dns/label.lua core/object/dns.lua \
+ core/object/dns/q.lua core/object/dns/rr.lua \
+ core/object/ether.lua core/object/gre.lua \
+ core/object/icmp6.lua core/object/icmp.lua \
+ core/object/ieee802.lua core/object/ip6.lua core/object/ip.lua \
+ core/object/linuxsll.lua core/object/loop.lua core/object.lua \
+ core/object/null.lua core/object/payload.lua \
+ core/object/pcap.lua core/objects.lua core/object/tcp.lua \
+ core/object/udp.lua core/producer.lua core/receiver.lua \
+ core/thread.lua core/timespec.lua filter/copy.lua \
+ filter/ipsplit.lua filter/layer.lua filter/split.lua \
+ filter/timing.lua input/fpcap.lua input/mmpcap.lua \
+ input/pcap.lua input/zero.lua input/zpcap.lua \
+ lib/base64url.lua lib/clock.lua lib/getopt.lua lib/ip.lua \
+ lib/parseconf.lua lib/trie/iter.lua lib/trie.lua \
+ lib/trie/node.lua output/dnscli.lua output/null.lua \
+ output/pcap.lua output/respdiff.lua output/tcpcli.lua \
+ output/tlscli.lua output/udpcli.lua
+dnsjitincludedir = $(includedir)/dnsjit
+
+# Lua headers
+nobase_dnsjitinclude_HEADERS = globals.h version.h core/assert.h \
+ core/channel.h core/compat.h core/file.h core/log.h \
+ core/object/dns.h core/object/ether.h core/object/gre.h \
+ core/object.h core/object/icmp6.h core/object/icmp.h \
+ core/object/ieee802.h core/object/ip6.h core/object/ip.h \
+ core/object/linuxsll.h core/object/loop.h core/object/null.h \
+ core/object/payload.h core/object/pcap.h core/object/tcp.h \
+ core/object/udp.h core/producer.h core/receiver.h \
+ core/thread.h core/timespec.h filter/copy.h filter/ipsplit.h \
+ filter/layer.h filter/split.h filter/timing.h input/fpcap.h \
+ input/mmpcap.h input/pcap.h input/zpcap.h lib/base64url.h \
+ lib/clock.h lib/trie.h output/dnscli.h output/pcap.h \
+ output/respdiff.h output/tcpcli.h output/tlscli.h \
+ output/udpcli.h core/channel.hh core/file.hh core/log.hh \
+ core/object/dns.hh core/object/ether.hh core/object/gre.hh \
+ core/object.hh core/object/icmp6.hh core/object/icmp.hh \
+ core/object/ieee802.hh core/object/ip6.hh core/object/ip.hh \
+ core/object/linuxsll.hh core/object/loop.hh \
+ core/object/null.hh core/object/payload.hh core/object/pcap.hh \
+ core/object/tcp.hh core/object/udp.hh core/producer.hh \
+ core/receiver.hh core/thread.hh core/timespec.hh \
+ filter/copy.hh filter/ipsplit.hh filter/layer.hh \
+ filter/split.hh filter/timing.hh input/fpcap.hh \
+ input/mmpcap.hh input/pcap.hh input/zpcap.hh lib/base64url.hh \
+ lib/clock.hh lib/trie.hh output/dnscli.hh output/pcap.hh \
+ output/respdiff.hh output/tcpcli.hh output/tlscli.hh \
+ output/udpcli.hh
+lua_hobjects = core/compat.luaho core/channel.luaho core/file.luaho \
+ core/log.luaho core/object/dns.luaho core/object/ether.luaho \
+ core/object/gre.luaho core/object/icmp6.luaho \
+ core/object/icmp.luaho core/object/ieee802.luaho \
+ core/object/ip6.luaho core/object/ip.luaho \
+ core/object/linuxsll.luaho core/object/loop.luaho \
+ core/object.luaho core/object/null.luaho \
+ core/object/payload.luaho core/object/pcap.luaho \
+ core/object/tcp.luaho core/object/udp.luaho \
+ core/producer.luaho core/receiver.luaho core/thread.luaho \
+ core/timespec.luaho filter/copy.luaho filter/ipsplit.luaho \
+ filter/layer.luaho filter/split.luaho filter/timing.luaho \
+ input/fpcap.luaho input/mmpcap.luaho input/pcap.luaho \
+ input/zpcap.luaho lib/base64url.luaho lib/clock.luaho \
+ lib/trie.luaho output/dnscli.luaho output/pcap.luaho \
+ output/respdiff.luaho output/tcpcli.luaho output/tlscli.luaho \
+ output/udpcli.luaho
+lua_objects = core.luao lib.luao input.luao filter.luao output.luao \
+ core/channel.luao core/compat.luao core/file.luao \
+ core/loader.luao core/log.luao core/object/dns/label.luao \
+ core/object/dns.luao core/object/dns/q.luao \
+ core/object/dns/rr.luao core/object/ether.luao \
+ core/object/gre.luao core/object/icmp6.luao \
+ core/object/icmp.luao core/object/ieee802.luao \
+ core/object/ip6.luao core/object/ip.luao \
+ core/object/linuxsll.luao core/object/loop.luao \
+ core/object.luao core/object/null.luao \
+ core/object/payload.luao core/object/pcap.luao \
+ core/objects.luao core/object/tcp.luao core/object/udp.luao \
+ core/producer.luao core/receiver.luao core/thread.luao \
+ core/timespec.luao filter/copy.luao filter/ipsplit.luao \
+ filter/layer.luao filter/split.luao filter/timing.luao \
+ input/fpcap.luao input/mmpcap.luao input/pcap.luao \
+ input/zero.luao input/zpcap.luao lib/base64url.luao \
+ lib/clock.luao lib/getopt.luao lib/ip.luao lib/parseconf.luao \
+ lib/trie/iter.luao lib/trie.luao lib/trie/node.luao \
+ output/dnscli.luao output/null.luao output/pcap.luao \
+ output/respdiff.luao output/tcpcli.luao output/tlscli.luao \
+ output/udpcli.luao
+dnsjit_LDADD = $(PTHREAD_LIBS) $(luajit_LIBS) $(liblz4_LIBS) \
+ $(libzstd_LIBS) $(lua_hobjects) $(lua_objects)
+dnsjit_LDFLAGS = -Wl,-E
+man1_MANS = dnsjit.1
+man3_MANS = dnsjit.core.3 dnsjit.lib.3 dnsjit.input.3 dnsjit.filter.3 \
+ dnsjit.output.3 dnsjit.core.channel.3 dnsjit.core.compat.3 \
+ dnsjit.core.file.3 dnsjit.core.loader.3 dnsjit.core.log.3 \
+ dnsjit.core.object.3 dnsjit.core.object.dns.3 \
+ dnsjit.core.object.dns.label.3 dnsjit.core.object.dns.q.3 \
+ dnsjit.core.object.dns.rr.3 dnsjit.core.object.ether.3 \
+ dnsjit.core.object.gre.3 dnsjit.core.object.icmp.3 \
+ dnsjit.core.object.icmp6.3 dnsjit.core.object.ieee802.3 \
+ dnsjit.core.object.ip.3 dnsjit.core.object.ip6.3 \
+ dnsjit.core.object.linuxsll.3 dnsjit.core.object.loop.3 \
+ dnsjit.core.object.null.3 dnsjit.core.object.payload.3 \
+ dnsjit.core.object.pcap.3 dnsjit.core.objects.3 \
+ dnsjit.core.object.tcp.3 dnsjit.core.object.udp.3 \
+ dnsjit.core.producer.3 dnsjit.core.receiver.3 \
+ dnsjit.core.thread.3 dnsjit.core.timespec.3 \
+ dnsjit.filter.copy.3 dnsjit.filter.ipsplit.3 \
+ dnsjit.filter.layer.3 dnsjit.filter.split.3 \
+ dnsjit.filter.timing.3 dnsjit.input.fpcap.3 \
+ dnsjit.input.mmpcap.3 dnsjit.input.pcap.3 dnsjit.input.zero.3 \
+ dnsjit.input.zpcap.3 dnsjit.lib.base64url.3 dnsjit.lib.clock.3 \
+ dnsjit.lib.getopt.3 dnsjit.lib.ip.3 dnsjit.lib.parseconf.3 \
+ dnsjit.lib.trie.3 dnsjit.lib.trie.iter.3 \
+ dnsjit.lib.trie.node.3 dnsjit.output.dnscli.3 \
+ dnsjit.output.null.3 dnsjit.output.pcap.3 \
+ dnsjit.output.respdiff.3 dnsjit.output.tcpcli.3 \
+ dnsjit.output.tlscli.3 dnsjit.output.udpcli.3
+all: $(BUILT_SOURCES) config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .1 .1in .3 .3in .c .hh .lo .lua .luah .luaho .luao .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @test -f $@ || rm -f stamp-h1
+ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status src/config.h
+$(srcdir)/config.h.in: $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+core/$(am__dirstamp):
+ @$(MKDIR_P) core
+ @: > core/$(am__dirstamp)
+core/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) core/$(DEPDIR)
+ @: > core/$(DEPDIR)/$(am__dirstamp)
+core/channel.$(OBJEXT): core/$(am__dirstamp) \
+ core/$(DEPDIR)/$(am__dirstamp)
+core/compat.$(OBJEXT): core/$(am__dirstamp) \
+ core/$(DEPDIR)/$(am__dirstamp)
+core/file.$(OBJEXT): core/$(am__dirstamp) \
+ core/$(DEPDIR)/$(am__dirstamp)
+core/log.$(OBJEXT): core/$(am__dirstamp) \
+ core/$(DEPDIR)/$(am__dirstamp)
+core/object.$(OBJEXT): core/$(am__dirstamp) \
+ core/$(DEPDIR)/$(am__dirstamp)
+core/object/$(am__dirstamp):
+ @$(MKDIR_P) core/object
+ @: > core/object/$(am__dirstamp)
+core/object/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) core/object/$(DEPDIR)
+ @: > core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/dns.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/ether.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/gre.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/icmp6.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/icmp.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/ieee802.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/ip6.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/ip.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/linuxsll.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/loop.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/null.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/payload.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/pcap.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/tcp.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/object/udp.$(OBJEXT): core/object/$(am__dirstamp) \
+ core/object/$(DEPDIR)/$(am__dirstamp)
+core/producer.$(OBJEXT): core/$(am__dirstamp) \
+ core/$(DEPDIR)/$(am__dirstamp)
+core/receiver.$(OBJEXT): core/$(am__dirstamp) \
+ core/$(DEPDIR)/$(am__dirstamp)
+core/thread.$(OBJEXT): core/$(am__dirstamp) \
+ core/$(DEPDIR)/$(am__dirstamp)
+filter/$(am__dirstamp):
+ @$(MKDIR_P) filter
+ @: > filter/$(am__dirstamp)
+filter/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) filter/$(DEPDIR)
+ @: > filter/$(DEPDIR)/$(am__dirstamp)
+filter/copy.$(OBJEXT): filter/$(am__dirstamp) \
+ filter/$(DEPDIR)/$(am__dirstamp)
+filter/ipsplit.$(OBJEXT): filter/$(am__dirstamp) \
+ filter/$(DEPDIR)/$(am__dirstamp)
+filter/layer.$(OBJEXT): filter/$(am__dirstamp) \
+ filter/$(DEPDIR)/$(am__dirstamp)
+filter/split.$(OBJEXT): filter/$(am__dirstamp) \
+ filter/$(DEPDIR)/$(am__dirstamp)
+filter/timing.$(OBJEXT): filter/$(am__dirstamp) \
+ filter/$(DEPDIR)/$(am__dirstamp)
+input/$(am__dirstamp):
+ @$(MKDIR_P) input
+ @: > input/$(am__dirstamp)
+input/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) input/$(DEPDIR)
+ @: > input/$(DEPDIR)/$(am__dirstamp)
+input/fpcap.$(OBJEXT): input/$(am__dirstamp) \
+ input/$(DEPDIR)/$(am__dirstamp)
+input/mmpcap.$(OBJEXT): input/$(am__dirstamp) \
+ input/$(DEPDIR)/$(am__dirstamp)
+input/pcap.$(OBJEXT): input/$(am__dirstamp) \
+ input/$(DEPDIR)/$(am__dirstamp)
+input/zpcap.$(OBJEXT): input/$(am__dirstamp) \
+ input/$(DEPDIR)/$(am__dirstamp)
+lib/$(am__dirstamp):
+ @$(MKDIR_P) lib
+ @: > lib/$(am__dirstamp)
+lib/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) lib/$(DEPDIR)
+ @: > lib/$(DEPDIR)/$(am__dirstamp)
+lib/base64url.$(OBJEXT): lib/$(am__dirstamp) \
+ lib/$(DEPDIR)/$(am__dirstamp)
+lib/clock.$(OBJEXT): lib/$(am__dirstamp) lib/$(DEPDIR)/$(am__dirstamp)
+lib/trie.$(OBJEXT): lib/$(am__dirstamp) lib/$(DEPDIR)/$(am__dirstamp)
+output/$(am__dirstamp):
+ @$(MKDIR_P) output
+ @: > output/$(am__dirstamp)
+output/$(DEPDIR)/$(am__dirstamp):
+ @$(MKDIR_P) output/$(DEPDIR)
+ @: > output/$(DEPDIR)/$(am__dirstamp)
+output/dnscli.$(OBJEXT): output/$(am__dirstamp) \
+ output/$(DEPDIR)/$(am__dirstamp)
+output/pcap.$(OBJEXT): output/$(am__dirstamp) \
+ output/$(DEPDIR)/$(am__dirstamp)
+output/respdiff.$(OBJEXT): output/$(am__dirstamp) \
+ output/$(DEPDIR)/$(am__dirstamp)
+output/tcpcli.$(OBJEXT): output/$(am__dirstamp) \
+ output/$(DEPDIR)/$(am__dirstamp)
+output/tlscli.$(OBJEXT): output/$(am__dirstamp) \
+ output/$(DEPDIR)/$(am__dirstamp)
+output/udpcli.$(OBJEXT): output/$(am__dirstamp) \
+ output/$(DEPDIR)/$(am__dirstamp)
+
+dnsjit$(EXEEXT): $(dnsjit_OBJECTS) $(dnsjit_DEPENDENCIES) $(EXTRA_dnsjit_DEPENDENCIES)
+ @rm -f dnsjit$(EXEEXT)
+ $(AM_V_CCLD)$(dnsjit_LINK) $(dnsjit_OBJECTS) $(dnsjit_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+ -rm -f core/*.$(OBJEXT)
+ -rm -f core/object/*.$(OBJEXT)
+ -rm -f filter/*.$(OBJEXT)
+ -rm -f input/*.$(OBJEXT)
+ -rm -f lib/*.$(OBJEXT)
+ -rm -f output/*.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dnsjit.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globals.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/$(DEPDIR)/channel.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/$(DEPDIR)/compat.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/$(DEPDIR)/file.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/$(DEPDIR)/log.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/$(DEPDIR)/object.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/$(DEPDIR)/producer.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/$(DEPDIR)/receiver.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/$(DEPDIR)/thread.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/dns.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/ether.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/gre.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/icmp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/icmp6.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/ieee802.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/ip.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/ip6.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/linuxsll.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/loop.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/null.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/payload.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/pcap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/tcp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@core/object/$(DEPDIR)/udp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@filter/$(DEPDIR)/copy.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@filter/$(DEPDIR)/ipsplit.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@filter/$(DEPDIR)/layer.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@filter/$(DEPDIR)/split.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@filter/$(DEPDIR)/timing.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@input/$(DEPDIR)/fpcap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@input/$(DEPDIR)/mmpcap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@input/$(DEPDIR)/pcap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@input/$(DEPDIR)/zpcap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/base64url.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/clock.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/trie.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@output/$(DEPDIR)/dnscli.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@output/$(DEPDIR)/pcap.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@output/$(DEPDIR)/respdiff.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@output/$(DEPDIR)/tcpcli.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@output/$(DEPDIR)/tlscli.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@output/$(DEPDIR)/udpcli.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man1: $(man1_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(man1_MANS)'; \
+ list2=''; \
+ test -n "$(man1dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.1[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man1_MANS)'; test -n "$(man1dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
+install-man3: $(man3_MANS)
+ @$(NORMAL_INSTALL)
+ @list1='$(man3_MANS)'; \
+ list2=''; \
+ test -n "$(man3dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.3[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man3:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man3_MANS)'; test -n "$(man3dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir)
+install-nobase_dnsjitincludeHEADERS: $(nobase_dnsjitinclude_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(nobase_dnsjitinclude_HEADERS)'; test -n "$(dnsjitincludedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(dnsjitincludedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(dnsjitincludedir)" || exit 1; \
+ fi; \
+ $(am__nobase_list) | while read dir files; do \
+ xfiles=; for file in $$files; do \
+ if test -f "$$file"; then xfiles="$$xfiles $$file"; \
+ else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
+ test -z "$$xfiles" || { \
+ test "x$$dir" = x. || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(dnsjitincludedir)/$$dir'"; \
+ $(MKDIR_P) "$(DESTDIR)$(dnsjitincludedir)/$$dir"; }; \
+ echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(dnsjitincludedir)/$$dir'"; \
+ $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(dnsjitincludedir)/$$dir" || exit $$?; }; \
+ done
+
+uninstall-nobase_dnsjitincludeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nobase_dnsjitinclude_HEADERS)'; test -n "$(dnsjitincludedir)" || list=; \
+ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+ dir='$(DESTDIR)$(dnsjitincludedir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+gcov-local:
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(PROGRAMS) $(MANS) $(HEADERS) config.h
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(dnsjitincludedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -rm -f core/$(DEPDIR)/$(am__dirstamp)
+ -rm -f core/$(am__dirstamp)
+ -rm -f core/object/$(DEPDIR)/$(am__dirstamp)
+ -rm -f core/object/$(am__dirstamp)
+ -rm -f filter/$(DEPDIR)/$(am__dirstamp)
+ -rm -f filter/$(am__dirstamp)
+ -rm -f input/$(DEPDIR)/$(am__dirstamp)
+ -rm -f input/$(am__dirstamp)
+ -rm -f lib/$(DEPDIR)/$(am__dirstamp)
+ -rm -f lib/$(am__dirstamp)
+ -rm -f output/$(DEPDIR)/$(am__dirstamp)
+ -rm -f output/$(am__dirstamp)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+@ENABLE_GCOV_FALSE@gcov-local:
+clean: clean-recursive
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f ./$(DEPDIR)/dnsjit.Po
+ -rm -f ./$(DEPDIR)/globals.Po
+ -rm -f core/$(DEPDIR)/channel.Po
+ -rm -f core/$(DEPDIR)/compat.Po
+ -rm -f core/$(DEPDIR)/file.Po
+ -rm -f core/$(DEPDIR)/log.Po
+ -rm -f core/$(DEPDIR)/object.Po
+ -rm -f core/$(DEPDIR)/producer.Po
+ -rm -f core/$(DEPDIR)/receiver.Po
+ -rm -f core/$(DEPDIR)/thread.Po
+ -rm -f core/object/$(DEPDIR)/dns.Po
+ -rm -f core/object/$(DEPDIR)/ether.Po
+ -rm -f core/object/$(DEPDIR)/gre.Po
+ -rm -f core/object/$(DEPDIR)/icmp.Po
+ -rm -f core/object/$(DEPDIR)/icmp6.Po
+ -rm -f core/object/$(DEPDIR)/ieee802.Po
+ -rm -f core/object/$(DEPDIR)/ip.Po
+ -rm -f core/object/$(DEPDIR)/ip6.Po
+ -rm -f core/object/$(DEPDIR)/linuxsll.Po
+ -rm -f core/object/$(DEPDIR)/loop.Po
+ -rm -f core/object/$(DEPDIR)/null.Po
+ -rm -f core/object/$(DEPDIR)/payload.Po
+ -rm -f core/object/$(DEPDIR)/pcap.Po
+ -rm -f core/object/$(DEPDIR)/tcp.Po
+ -rm -f core/object/$(DEPDIR)/udp.Po
+ -rm -f filter/$(DEPDIR)/copy.Po
+ -rm -f filter/$(DEPDIR)/ipsplit.Po
+ -rm -f filter/$(DEPDIR)/layer.Po
+ -rm -f filter/$(DEPDIR)/split.Po
+ -rm -f filter/$(DEPDIR)/timing.Po
+ -rm -f input/$(DEPDIR)/fpcap.Po
+ -rm -f input/$(DEPDIR)/mmpcap.Po
+ -rm -f input/$(DEPDIR)/pcap.Po
+ -rm -f input/$(DEPDIR)/zpcap.Po
+ -rm -f lib/$(DEPDIR)/base64url.Po
+ -rm -f lib/$(DEPDIR)/clock.Po
+ -rm -f lib/$(DEPDIR)/trie.Po
+ -rm -f output/$(DEPDIR)/dnscli.Po
+ -rm -f output/$(DEPDIR)/pcap.Po
+ -rm -f output/$(DEPDIR)/respdiff.Po
+ -rm -f output/$(DEPDIR)/tcpcli.Po
+ -rm -f output/$(DEPDIR)/tlscli.Po
+ -rm -f output/$(DEPDIR)/udpcli.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-hdr distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+gcov: gcov-recursive
+
+gcov-am: gcov-local
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-man install-nobase_dnsjitincludeHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man: install-man1 install-man3
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f ./$(DEPDIR)/dnsjit.Po
+ -rm -f ./$(DEPDIR)/globals.Po
+ -rm -f core/$(DEPDIR)/channel.Po
+ -rm -f core/$(DEPDIR)/compat.Po
+ -rm -f core/$(DEPDIR)/file.Po
+ -rm -f core/$(DEPDIR)/log.Po
+ -rm -f core/$(DEPDIR)/object.Po
+ -rm -f core/$(DEPDIR)/producer.Po
+ -rm -f core/$(DEPDIR)/receiver.Po
+ -rm -f core/$(DEPDIR)/thread.Po
+ -rm -f core/object/$(DEPDIR)/dns.Po
+ -rm -f core/object/$(DEPDIR)/ether.Po
+ -rm -f core/object/$(DEPDIR)/gre.Po
+ -rm -f core/object/$(DEPDIR)/icmp.Po
+ -rm -f core/object/$(DEPDIR)/icmp6.Po
+ -rm -f core/object/$(DEPDIR)/ieee802.Po
+ -rm -f core/object/$(DEPDIR)/ip.Po
+ -rm -f core/object/$(DEPDIR)/ip6.Po
+ -rm -f core/object/$(DEPDIR)/linuxsll.Po
+ -rm -f core/object/$(DEPDIR)/loop.Po
+ -rm -f core/object/$(DEPDIR)/null.Po
+ -rm -f core/object/$(DEPDIR)/payload.Po
+ -rm -f core/object/$(DEPDIR)/pcap.Po
+ -rm -f core/object/$(DEPDIR)/tcp.Po
+ -rm -f core/object/$(DEPDIR)/udp.Po
+ -rm -f filter/$(DEPDIR)/copy.Po
+ -rm -f filter/$(DEPDIR)/ipsplit.Po
+ -rm -f filter/$(DEPDIR)/layer.Po
+ -rm -f filter/$(DEPDIR)/split.Po
+ -rm -f filter/$(DEPDIR)/timing.Po
+ -rm -f input/$(DEPDIR)/fpcap.Po
+ -rm -f input/$(DEPDIR)/mmpcap.Po
+ -rm -f input/$(DEPDIR)/pcap.Po
+ -rm -f input/$(DEPDIR)/zpcap.Po
+ -rm -f lib/$(DEPDIR)/base64url.Po
+ -rm -f lib/$(DEPDIR)/clock.Po
+ -rm -f lib/$(DEPDIR)/trie.Po
+ -rm -f output/$(DEPDIR)/dnscli.Po
+ -rm -f output/$(DEPDIR)/pcap.Po
+ -rm -f output/$(DEPDIR)/respdiff.Po
+ -rm -f output/$(DEPDIR)/tcpcli.Po
+ -rm -f output/$(DEPDIR)/tlscli.Po
+ -rm -f output/$(DEPDIR)/udpcli.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-man \
+ uninstall-nobase_dnsjitincludeHEADERS
+
+uninstall-man: uninstall-man1 uninstall-man3
+
+.MAKE: $(am__recursive_targets) all check install install-am \
+ install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+ am--depfiles check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags distdir dvi dvi-am gcov-am \
+ gcov-local html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-man1 install-man3 install-nobase_dnsjitincludeHEADERS \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am uninstall-binPROGRAMS uninstall-man \
+ uninstall-man1 uninstall-man3 \
+ uninstall-nobase_dnsjitincludeHEADERS
+
+.PRECIOUS: Makefile
+
+
+.lua.luao:
+ @mkdir -p `dirname "$@"`
+ $(LUAJIT) -bg -n "dnsjit.`echo \"$@\" | sed 's%\..*%%' | sed 's%/%.%g'`" -t o "$<" "$@"
+
+.luah.luaho:
+ @mkdir -p `dirname "$@"`
+ $(LUAJIT) -bg -n "dnsjit.`echo \"$@\" | sed 's%\..*%%' | sed 's%/%.%g'`_h" -t o "$<" "$@"
+
+.hh.luah:
+ @mkdir -p `dirname "$@"`
+ @echo 'module(...,package.seeall);' > "$@"
+ @cat "$<" | grep '^//lua:' | sed 's%^//lua:%%' >> "$@"
+ @echo 'require("ffi").cdef[[' >> "$@"
+ @cat "$<" | grep -v '^#' >> "$@"
+ @echo ']]' >> "$@"
+
+.1in.1:
+ sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
+ -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
+ -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
+ < "$<" > "$@"
+
+.3in.3:
+ sed -e 's,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g' \
+ -e 's,[@]PACKAGE_URL[@],$(PACKAGE_URL),g' \
+ -e 's,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g' \
+ < "$<" > "$@"
+
+@ENABLE_GCOV_TRUE@gcov-local:
+@ENABLE_GCOV_TRUE@ for src in $(dnsjit_SOURCES); do \
+@ENABLE_GCOV_TRUE@ gcov -x -l -r -s "$(srcdir)" "$$src"; \
+@ENABLE_GCOV_TRUE@ done
+
+core/compat.hh: gen-compat.lua
+ $(LUAJIT) "$(srcdir)/gen-compat.lua" > "$@"
+
+core/log_errstr.c: gen-errno.sh
+ "$(srcdir)/gen-errno.sh" > "$@"
+
+dnsjit.core.3in: core.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core.lua" > "$@"
+
+dnsjit.lib.3in: lib.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib.lua" > "$@"
+
+dnsjit.input.3in: input.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input.lua" > "$@"
+
+dnsjit.filter.3in: filter.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter.lua" > "$@"
+
+dnsjit.output.3in: output.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output.lua" > "$@"
+
+dnsjit.core.channel.3in: core/channel.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/channel.lua" > "$@"
+
+dnsjit.core.compat.3in: core/compat.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/compat.lua" > "$@"
+
+dnsjit.core.file.3in: core/file.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/file.lua" > "$@"
+
+dnsjit.core.loader.3in: core/loader.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/loader.lua" > "$@"
+
+dnsjit.core.log.3in: core/log.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/log.lua" > "$@"
+
+dnsjit.core.object.dns.label.3in: core/object/dns/label.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/dns/label.lua" > "$@"
+
+dnsjit.core.object.dns.3in: core/object/dns.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/dns.lua" > "$@"
+
+dnsjit.core.object.dns.q.3in: core/object/dns/q.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/dns/q.lua" > "$@"
+
+dnsjit.core.object.dns.rr.3in: core/object/dns/rr.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/dns/rr.lua" > "$@"
+
+dnsjit.core.object.ether.3in: core/object/ether.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/ether.lua" > "$@"
+
+dnsjit.core.object.gre.3in: core/object/gre.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/gre.lua" > "$@"
+
+dnsjit.core.object.icmp6.3in: core/object/icmp6.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/icmp6.lua" > "$@"
+
+dnsjit.core.object.icmp.3in: core/object/icmp.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/icmp.lua" > "$@"
+
+dnsjit.core.object.ieee802.3in: core/object/ieee802.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/ieee802.lua" > "$@"
+
+dnsjit.core.object.ip6.3in: core/object/ip6.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/ip6.lua" > "$@"
+
+dnsjit.core.object.ip.3in: core/object/ip.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/ip.lua" > "$@"
+
+dnsjit.core.object.linuxsll.3in: core/object/linuxsll.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/linuxsll.lua" > "$@"
+
+dnsjit.core.object.loop.3in: core/object/loop.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/loop.lua" > "$@"
+
+dnsjit.core.object.3in: core/object.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object.lua" > "$@"
+
+dnsjit.core.object.null.3in: core/object/null.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/null.lua" > "$@"
+
+dnsjit.core.object.payload.3in: core/object/payload.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/payload.lua" > "$@"
+
+dnsjit.core.object.pcap.3in: core/object/pcap.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/pcap.lua" > "$@"
+
+dnsjit.core.objects.3in: core/objects.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/objects.lua" > "$@"
+
+dnsjit.core.object.tcp.3in: core/object/tcp.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/tcp.lua" > "$@"
+
+dnsjit.core.object.udp.3in: core/object/udp.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/object/udp.lua" > "$@"
+
+dnsjit.core.producer.3in: core/producer.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/producer.lua" > "$@"
+
+dnsjit.core.receiver.3in: core/receiver.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/receiver.lua" > "$@"
+
+dnsjit.core.thread.3in: core/thread.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/thread.lua" > "$@"
+
+dnsjit.core.timespec.3in: core/timespec.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/core/timespec.lua" > "$@"
+
+dnsjit.filter.copy.3in: filter/copy.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/copy.lua" > "$@"
+
+dnsjit.filter.ipsplit.3in: filter/ipsplit.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/ipsplit.lua" > "$@"
+
+dnsjit.filter.layer.3in: filter/layer.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/layer.lua" > "$@"
+
+dnsjit.filter.split.3in: filter/split.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/split.lua" > "$@"
+
+dnsjit.filter.timing.3in: filter/timing.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/filter/timing.lua" > "$@"
+
+dnsjit.input.fpcap.3in: input/fpcap.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/fpcap.lua" > "$@"
+
+dnsjit.input.mmpcap.3in: input/mmpcap.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/mmpcap.lua" > "$@"
+
+dnsjit.input.pcap.3in: input/pcap.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/pcap.lua" > "$@"
+
+dnsjit.input.zero.3in: input/zero.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/zero.lua" > "$@"
+
+dnsjit.input.zpcap.3in: input/zpcap.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/input/zpcap.lua" > "$@"
+
+dnsjit.lib.base64url.3in: lib/base64url.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/base64url.lua" > "$@"
+
+dnsjit.lib.clock.3in: lib/clock.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/clock.lua" > "$@"
+
+dnsjit.lib.getopt.3in: lib/getopt.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/getopt.lua" > "$@"
+
+dnsjit.lib.ip.3in: lib/ip.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/ip.lua" > "$@"
+
+dnsjit.lib.parseconf.3in: lib/parseconf.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/parseconf.lua" > "$@"
+
+dnsjit.lib.trie.iter.3in: lib/trie/iter.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/trie/iter.lua" > "$@"
+
+dnsjit.lib.trie.3in: lib/trie.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/trie.lua" > "$@"
+
+dnsjit.lib.trie.node.3in: lib/trie/node.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/lib/trie/node.lua" > "$@"
+
+dnsjit.output.dnscli.3in: output/dnscli.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/dnscli.lua" > "$@"
+
+dnsjit.output.null.3in: output/null.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/null.lua" > "$@"
+
+dnsjit.output.pcap.3in: output/pcap.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/pcap.lua" > "$@"
+
+dnsjit.output.respdiff.3in: output/respdiff.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/respdiff.lua" > "$@"
+
+dnsjit.output.tcpcli.3in: output/tcpcli.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/tcpcli.lua" > "$@"
+
+dnsjit.output.tlscli.3in: output/tlscli.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/tlscli.lua" > "$@"
+
+dnsjit.output.udpcli.3in: output/udpcli.lua gen-manpage.lua
+ $(LUAJIT) "$(srcdir)/gen-manpage.lua" "$(srcdir)/output/udpcli.lua" > "$@"
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644
index 0000000..c156fa2
--- /dev/null
+++ b/src/config.h.in
@@ -0,0 +1,295 @@
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 to support Advanced Bit Manipulation */
+#undef HAVE_ABM
+
+/* Define to 1 to support Multi-Precision Add-Carry Instruction Extensions */
+#undef HAVE_ADX
+
+/* Define to 1 to support Advanced Encryption Standard New Instruction Set
+ (AES-NI) */
+#undef HAVE_AES
+
+/* Support Altivec instructions */
+#undef HAVE_ALTIVEC
+
+/* Define to 1 to support Advanced Vector Extensions */
+#undef HAVE_AVX
+
+/* Define to 1 to support Advanced Vector Extensions 2 */
+#undef HAVE_AVX2
+
+/* Define to 1 to support AVX-512 Byte and Word Instructions */
+#undef HAVE_AVX512_BW
+
+/* Define to 1 to support AVX-512 Conflict Detection Instructions */
+#undef HAVE_AVX512_CD
+
+/* Define to 1 to support AVX-512 Doubleword and Quadword Instructions */
+#undef HAVE_AVX512_DQ
+
+/* Define to 1 to support AVX-512 Exponential & Reciprocal Instructions */
+#undef HAVE_AVX512_ER
+
+/* Define to 1 to support AVX-512 Foundation Extensions */
+#undef HAVE_AVX512_F
+
+/* Define to 1 to support AVX-512 Integer Fused Multiply Add Instructions */
+#undef HAVE_AVX512_IFMA
+
+/* Define to 1 to support AVX-512 Conflict Prefetch Instructions */
+#undef HAVE_AVX512_PF
+
+/* Define to 1 to support AVX-512 Vector Byte Manipulation Instructions */
+#undef HAVE_AVX512_VBMI
+
+/* Define to 1 to support AVX-512 Vector Length Extensions */
+#undef HAVE_AVX512_VL
+
+/* Define to 1 to support Bit Manipulation Instruction Set 1 */
+#undef HAVE_BMI1
+
+/* Define to 1 to support Bit Manipulation Instruction Set 2 */
+#undef HAVE_BMI2
+
+/* Define to 1 if you have the <byteswap.h> header file. */
+#undef HAVE_BYTESWAP_H
+
+/* Define to 1 if you have the <ck_pr.h> header file. */
+#undef HAVE_CK_PR_H
+
+/* Define to 1 if you have the <ck_ring.h> header file. */
+#undef HAVE_CK_RING_H
+
+/* Define to 1 if you have the `clock_nanosleep' function. */
+#undef HAVE_CLOCK_NANOSLEEP
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <endian.h> header file. */
+#undef HAVE_ENDIAN_H
+
+/* Define to 1 to support Fused Multiply-Add Extensions 3 */
+#undef HAVE_FMA3
+
+/* Define to 1 to support Fused Multiply-Add Extensions 4 */
+#undef HAVE_FMA4
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `ck' library (-lck). */
+#undef HAVE_LIBCK
+
+/* Define to 1 if you have the `gnutls' library (-lgnutls). */
+#undef HAVE_LIBGNUTLS
+
+/* Define to 1 if you have the `lmdb' library (-llmdb). */
+#undef HAVE_LIBLMDB
+
+/* Define to 1 if you have the `pcap' library (-lpcap). */
+#undef HAVE_LIBPCAP
+
+/* Define to 1 if you have the <lmdb.h> header file. */
+#undef HAVE_LMDB_H
+
+/* Use liblz4 */
+#undef HAVE_LZ4
+
+/* Define to 1 if you have the <machine/endian.h> header file. */
+#undef HAVE_MACHINE_ENDIAN_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 to support Multimedia Extensions */
+#undef HAVE_MMX
+
+/* Define to 1 to support Memory Protection Extensions */
+#undef HAVE_MPX
+
+/* Define to 1 if you have the `nanosleep' function. */
+#undef HAVE_NANOSLEEP
+
+/* Define to 1 if you have the <net/ethernet.h> header file. */
+#undef HAVE_NET_ETHERNET_H
+
+/* Define to 1 if you have the <net/ethertypes.h> header file. */
+#undef HAVE_NET_ETHERTYPES_H
+
+/* Define to 1 if you have the `pcap_activate' function. */
+#undef HAVE_PCAP_ACTIVATE
+
+/* Define to 1 if you have the `pcap_create' function. */
+#undef HAVE_PCAP_CREATE
+
+/* Define to 1 if the system has the type `pcap_direction_t'. */
+#undef HAVE_PCAP_DIRECTION_T
+
+/* Define to 1 if you have the `pcap_open_offline_with_tstamp_precision'
+ function. */
+#undef HAVE_PCAP_OPEN_OFFLINE_WITH_TSTAMP_PRECISION
+
+/* Define to 1 if you have the `pcap_setdirection' function. */
+#undef HAVE_PCAP_SETDIRECTION
+
+/* Define to 1 if you have the `pcap_set_immediate_mode' function. */
+#undef HAVE_PCAP_SET_IMMEDIATE_MODE
+
+/* Define to 1 if you have the `pcap_set_tstamp_precision' function. */
+#undef HAVE_PCAP_SET_TSTAMP_PRECISION
+
+/* Define to 1 if you have the `pcap_set_tstamp_type' function. */
+#undef HAVE_PCAP_SET_TSTAMP_TYPE
+
+/* Define to 1 to support Prefetch Vector Data Into Caches WT1 */
+#undef HAVE_PREFETCHWT1
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
+/* Define to 1 to support Digital Random Number Generator */
+#undef HAVE_RDRND
+
+/* Define to 1 if you have the `sched_yield' function. */
+#undef HAVE_SCHED_YIELD
+
+/* Define to 1 to support Secure Hash Algorithm Extension */
+#undef HAVE_SHA
+
+/* Define to 1 to support Streaming SIMD Extensions */
+#undef HAVE_SSE
+
+/* Define to 1 to support Streaming SIMD Extensions */
+#undef HAVE_SSE2
+
+/* Define to 1 to support Streaming SIMD Extensions 3 */
+#undef HAVE_SSE3
+
+/* Define to 1 to support Streaming SIMD Extensions 4.1 */
+#undef HAVE_SSE4_1
+
+/* Define to 1 to support Streaming SIMD Extensions 4.2 */
+#undef HAVE_SSE4_2
+
+/* Define to 1 to support AMD Streaming SIMD Extensions 4a */
+#undef HAVE_SSE4a
+
+/* Define to 1 to support Supplemental Streaming SIMD Extensions 3 */
+#undef HAVE_SSSE3
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/endian.h> header file. */
+#undef HAVE_SYS_ENDIAN_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Support VSX instructions */
+#undef HAVE_VSX
+
+/* Define to 1 to support eXtended Operations Extensions */
+#undef HAVE_XOP
+
+/* Use libzstd */
+#undef HAVE_ZSTD
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the major version of this package. */
+#undef PACKAGE_MAJOR_VERSION
+
+/* Define to the minor version of this package. */
+#undef PACKAGE_MINOR_VERSION
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the patch version of this package. */
+#undef PACKAGE_PATCH_VERSION
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* The size of `ck_ring_buffer_t', as computed by sizeof. */
+#undef SIZEOF_CK_RING_BUFFER_T
+
+/* The size of `ck_ring_t', as computed by sizeof. */
+#undef SIZEOF_CK_RING_T
+
+/* The size of `gnutls_certificate_credentials_t', as computed by sizeof. */
+#undef SIZEOF_GNUTLS_CERTIFICATE_CREDENTIALS_T
+
+/* The size of `gnutls_session_t', as computed by sizeof. */
+#undef SIZEOF_GNUTLS_SESSION_T
+
+/* The size of `pthread_cond_t', as computed by sizeof. */
+#undef SIZEOF_PTHREAD_COND_T
+
+/* The size of `pthread_mutex_t', as computed by sizeof. */
+#undef SIZEOF_PTHREAD_MUTEX_T
+
+/* The size of `pthread_t', as computed by sizeof. */
+#undef SIZEOF_PTHREAD_T
+
+/* The size of `struct pollfd', as computed by sizeof. */
+#undef SIZEOF_STRUCT_POLLFD
+
+/* The size of `struct sockaddr_storage', as computed by sizeof. */
+#undef SIZEOF_STRUCT_SOCKADDR_STORAGE
+
+/* The size of `void*', as computed by sizeof. */
+#undef SIZEOF_VOIDP
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
diff --git a/src/core/assert.h b/src/core/assert.h
index 3f2f503..1cdc6e6 100644
--- a/src/core/assert.h
+++ b/src/core/assert.h
@@ -21,7 +21,7 @@
#ifndef __dnsjit_core_assert_h
#define __dnsjit_core_assert_h
-#include "core/log.h"
+#include <dnsjit/core/log.h>
#define mlassert_self() \
if (!self) \
diff --git a/src/core/channel.h b/src/core/channel.h
index 75e84ac..b0e90ae 100644
--- a/src/core/channel.h
+++ b/src/core/channel.h
@@ -18,8 +18,8 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
#ifndef __dnsjit_core_channel_h
#define __dnsjit_core_channel_h
@@ -36,6 +36,6 @@
#include <ck_pr.h>
#include <stdbool.h>
-#include "core/channel.hh"
+#include <dnsjit/core/channel.hh>
#endif
diff --git a/src/core/file.c b/src/core/file.c
new file mode 100644
index 0000000..d632a73
--- /dev/null
+++ b/src/core/file.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "core/file.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+int core_file_exists(const char* filename)
+{
+ struct stat s;
+
+ if (stat(filename, &s)) {
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/core/file.h b/src/core/file.h
new file mode 100644
index 0000000..ad5a174
--- /dev/null
+++ b/src/core/file.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __dnsjit_core_file_h
+#define __dnsjit_core_file_h
+
+#include <dnsjit/core/file.hh>
+
+#endif
diff --git a/src/core/file.hh b/src/core/file.hh
new file mode 100644
index 0000000..70b1bc9
--- /dev/null
+++ b/src/core/file.hh
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+int core_file_exists(const char*);
diff --git a/src/core/file.lua b/src/core/file.lua
new file mode 100644
index 0000000..5ce52d7
--- /dev/null
+++ b/src/core/file.lua
@@ -0,0 +1,37 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.file
+-- OS file operations
+-- require("dnsjit.core.file")
+-- local ffi = require("ffi")
+-- if ffi.C.core_file_exists("path/file") == 0 then
+-- ...
+-- end
+--
+-- Module that exposes some file operations that are missing from Lua.
+-- .SS C functions
+-- .TP
+-- core_file_exists(path/filename)
+-- Function that takes a string and uses
+-- .B stat()
+-- to check if that path/filename exists.
+-- Returns zero if it exists.
+module(...,package.seeall)
+
+require("dnsjit.core.file_h")
diff --git a/src/core/loader.lua b/src/core/loader.lua
new file mode 100644
index 0000000..b56a390
--- /dev/null
+++ b/src/core/loader.lua
@@ -0,0 +1,68 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.core.loader
+-- Dynamic library loader
+-- local loader = require("dnsjit.core.loader")
+-- loader.load("example-input-zero/zero")
+--
+-- Module for loading dynamic libraries (.so) in more ways then LuaJIT can.
+-- This is mainly used in external modules.
+module(...,package.seeall)
+
+require("dnsjit.core.file")
+local ffi = require("ffi")
+local C = ffi.C
+
+local Loader = {}
+
+-- Search
+-- .B package.cpath
+-- for the given name and load the first found.
+-- If
+-- .B global
+-- is true (default true if not given) then the loaded symbols will also
+-- be available globally.
+-- Returns the loaded C library as per
+-- .BR ffi.load() .
+-- .br
+-- The
+-- .B ?
+-- in each path of
+-- .B package.cpath
+-- will be replace by the given name, so usually the ".so" part of the
+-- library does not need to be given.
+-- See
+-- .I package.cpath
+-- and
+-- .I package.loaders
+-- in Lua 5.1 for more information.
+function Loader.load(name, global)
+ if global ~= false then
+ global = true
+ end
+ for path in string.gmatch(package.cpath, "[^;]+") do
+ path = path:gsub("?", name)
+ if C.core_file_exists(path) == 0 then
+ return ffi.load(path, global)
+ end
+ end
+ return ffi.load(name)
+end
+
+return Loader
diff --git a/src/core/log.h b/src/core/log.h
index d17c733..05b3db9 100644
--- a/src/core/log.h
+++ b/src/core/log.h
@@ -38,7 +38,7 @@
name, 1, LOG_SETTINGS_T_INIT, &_log.settings \
}
-#include "core/log.hh"
+#include <dnsjit/core/log.hh>
#ifdef DNSJIT_NO_LOGGING
#define ldebug(msg...)
diff --git a/src/core/object.h b/src/core/object.h
index c2eebb0..8729cde 100644
--- a/src/core/object.h
+++ b/src/core/object.h
@@ -44,7 +44,7 @@
#define CORE_OBJECT_DNS 50
#include <stdint.h>
-#include "core/object.hh"
+#include <dnsjit/core/object.hh>
#define CORE_OBJECT_INIT(type, prev) (core_object_t*)prev, type
diff --git a/src/core/object/dns.h b/src/core/object/dns.h
index 5fbaf53..68a2dc9 100644
--- a/src/core/object/dns.h
+++ b/src/core/object/dns.h
@@ -18,8 +18,8 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/object.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/object.h>
#ifndef __dnsjit_core_object_dns_h
#define __dnsjit_core_object_dns_h
@@ -27,7 +27,7 @@
#include <netinet/in.h>
#include <sys/types.h>
-#include "core/object/dns.hh"
+#include <dnsjit/core/object/dns.hh>
#define CORE_OBJECT_DNS_INIT(prev) \
{ \
diff --git a/src/core/object/ether.h b/src/core/object/ether.h
index e35ecb2..0fc9e35 100644
--- a/src/core/object/ether.h
+++ b/src/core/object/ether.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_ether_h
#define __dnsjit_core_object_ether_h
#include <stddef.h>
-#include "core/object/ether.hh"
+#include <dnsjit/core/object/ether.hh>
#define CORE_OBJECT_ETHER_INIT(prev) \
{ \
diff --git a/src/core/object/gre.h b/src/core/object/gre.h
index 8efa93c..a716787 100644
--- a/src/core/object/gre.h
+++ b/src/core/object/gre.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_gre_h
#define __dnsjit_core_object_gre_h
#include <stddef.h>
-#include "core/object/gre.hh"
+#include <dnsjit/core/object/gre.hh>
#define CORE_OBJECT_GRE_INIT(prev) \
{ \
diff --git a/src/core/object/icmp.h b/src/core/object/icmp.h
index 346a3ea..65ffa7d 100644
--- a/src/core/object/icmp.h
+++ b/src/core/object/icmp.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_icmp_h
#define __dnsjit_core_object_icmp_h
#include <stddef.h>
-#include "core/object/icmp.hh"
+#include <dnsjit/core/object/icmp.hh>
#define CORE_OBJECT_ICMP_INIT(prev) \
{ \
diff --git a/src/core/object/icmp6.h b/src/core/object/icmp6.h
index 569bf7f..4586d33 100644
--- a/src/core/object/icmp6.h
+++ b/src/core/object/icmp6.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_icmp6_h
#define __dnsjit_core_object_icmp6_h
#include <stddef.h>
-#include "core/object/icmp6.hh"
+#include <dnsjit/core/object/icmp6.hh>
#define CORE_OBJECT_ICMP6_INIT(prev) \
{ \
diff --git a/src/core/object/ieee802.h b/src/core/object/ieee802.h
index ca4847c..388430d 100644
--- a/src/core/object/ieee802.h
+++ b/src/core/object/ieee802.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_ieee802_h
#define __dnsjit_core_object_ieee802_h
#include <stddef.h>
-#include "core/object/ieee802.hh"
+#include <dnsjit/core/object/ieee802.hh>
#define CORE_OBJECT_IEEE802_INIT(prev) \
{ \
diff --git a/src/core/object/ip.h b/src/core/object/ip.h
index c2b9312..00e927b 100644
--- a/src/core/object/ip.h
+++ b/src/core/object/ip.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_ip_h
#define __dnsjit_core_object_ip_h
#include <stddef.h>
-#include "core/object/ip.hh"
+#include <dnsjit/core/object/ip.hh>
#define CORE_OBJECT_IP_INIT(prev) \
{ \
diff --git a/src/core/object/ip6.h b/src/core/object/ip6.h
index 711f1a5..660b9e9 100644
--- a/src/core/object/ip6.h
+++ b/src/core/object/ip6.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_ip6_h
#define __dnsjit_core_object_ip6_h
#include <stddef.h>
-#include "core/object/ip6.hh"
+#include <dnsjit/core/object/ip6.hh>
#define CORE_OBJECT_IP6_INIT(prev) \
{ \
diff --git a/src/core/object/linuxsll.h b/src/core/object/linuxsll.h
index 9484c0d..668581e 100644
--- a/src/core/object/linuxsll.h
+++ b/src/core/object/linuxsll.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_linuxsll_h
#define __dnsjit_core_object_linuxsll_h
#include <stddef.h>
-#include "core/object/linuxsll.hh"
+#include <dnsjit/core/object/linuxsll.hh>
#define CORE_OBJECT_LINUXSLL_INIT(prev) \
{ \
diff --git a/src/core/object/loop.h b/src/core/object/loop.h
index 1d8670f..0cdb8e0 100644
--- a/src/core/object/loop.h
+++ b/src/core/object/loop.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_loop_h
#define __dnsjit_core_object_loop_h
#include <stddef.h>
-#include "core/object/loop.hh"
+#include <dnsjit/core/object/loop.hh>
#define CORE_OBJECT_LOOP_INIT(prev) \
{ \
diff --git a/src/core/object/null.h b/src/core/object/null.h
index 0317fce..5127951 100644
--- a/src/core/object/null.h
+++ b/src/core/object/null.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_null_h
#define __dnsjit_core_object_null_h
#include <stddef.h>
-#include "core/object/null.hh"
+#include <dnsjit/core/object/null.hh>
#define CORE_OBJECT_NULL_INIT(prev) \
{ \
diff --git a/src/core/object/payload.h b/src/core/object/payload.h
index 4b42a7c..07391aa 100644
--- a/src/core/object/payload.h
+++ b/src/core/object/payload.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_payload_h
#define __dnsjit_core_object_payload_h
#include <stddef.h>
-#include "core/object/payload.hh"
+#include <dnsjit/core/object/payload.hh>
#define CORE_OBJECT_PAYLOAD_INIT(prev) \
{ \
diff --git a/src/core/object/pcap.h b/src/core/object/pcap.h
index 093549b..afcccf3 100644
--- a/src/core/object/pcap.h
+++ b/src/core/object/pcap.h
@@ -18,13 +18,13 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_pcap_h
#define __dnsjit_core_object_pcap_h
-#include "core/object/pcap.hh"
+#include <dnsjit/core/object/pcap.hh>
#define CORE_OBJECT_PCAP_INIT(prev) \
{ \
diff --git a/src/core/object/tcp.h b/src/core/object/tcp.h
index e62ad42..e851a8a 100644
--- a/src/core/object/tcp.h
+++ b/src/core/object/tcp.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_tcp_h
#define __dnsjit_core_object_tcp_h
#include <stddef.h>
-#include "core/object/tcp.hh"
+#include <dnsjit/core/object/tcp.hh>
#define CORE_OBJECT_TCP_INIT(prev) \
{ \
diff --git a/src/core/object/udp.h b/src/core/object/udp.h
index 147e80b..e85208b 100644
--- a/src/core/object/udp.h
+++ b/src/core/object/udp.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
-#include "core/timespec.h"
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_core_object_udp_h
#define __dnsjit_core_object_udp_h
#include <stddef.h>
-#include "core/object/udp.hh"
+#include <dnsjit/core/object/udp.hh>
#define CORE_OBJECT_UDP_INIT(prev) \
{ \
diff --git a/src/core/producer.h b/src/core/producer.h
index e78d48b..da63c17 100644
--- a/src/core/producer.h
+++ b/src/core/producer.h
@@ -18,11 +18,11 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
+#include <dnsjit/core/object.h>
#ifndef __dnsjit_core_producer_h
#define __dnsjit_core_producer_h
-#include "core/producer.hh"
+#include <dnsjit/core/producer.hh>
#endif
diff --git a/src/core/receiver.h b/src/core/receiver.h
index f592c0c..5530b6a 100644
--- a/src/core/receiver.h
+++ b/src/core/receiver.h
@@ -18,11 +18,11 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/object.h"
+#include <dnsjit/core/object.h>
#ifndef __dnsjit_core_receiver_h
#define __dnsjit_core_receiver_h
-#include "core/receiver.hh"
+#include <dnsjit/core/receiver.hh>
#endif
diff --git a/src/core/thread.h b/src/core/thread.h
index fc047d4..6b7ede6 100644
--- a/src/core/thread.h
+++ b/src/core/thread.h
@@ -18,7 +18,7 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
+#include <dnsjit/core/log.h>
#ifndef __dnsjit_core_thread_h
#define __dnsjit_core_thread_h
@@ -26,6 +26,6 @@
#include <pthread.h>
#include <unistd.h>
-#include "core/thread.hh"
+#include <dnsjit/core/thread.hh>
#endif
diff --git a/src/core/timespec.h b/src/core/timespec.h
index e0aefce..2110c6d 100644
--- a/src/core/timespec.h
+++ b/src/core/timespec.h
@@ -23,7 +23,7 @@
#include <stdint.h>
-#include "core/timespec.hh"
+#include <dnsjit/core/timespec.hh>
#define CORE_TIMESPEC_INIT \
{ \
diff --git a/src/core/timespec.lua b/src/core/timespec.lua
index 0db4dd3..05c600f 100644
--- a/src/core/timespec.lua
+++ b/src/core/timespec.lua
@@ -19,14 +19,36 @@
-- dnsjit.core.receiver
-- Non-system depended time specification structure definition
-- typedef struct core_timespec {
--- uint64_t sec;
--- uint64_t nsec;
+-- int64_t sec;
+-- int64_t nsec;
-- } core_timespec_t;
-- .SS C
-- #include "core/timespec.h"
-- .SS Lua
-- require("dnsjit.core.timespec_h")
+-- .SS Lua functions
+-- local ts = require("dnsjit.core.timespec"):max_init()
--
-- Mainly used in C modules for a system independent time specification
-- structure that can be passed to Lua.
module(...,package.seeall)
+
+require("dnsjit.core.timespec_h")
+
+local ffi = require("ffi")
+
+local Timespec = {}
+
+-- Return a new structure with both
+-- .I sec
+-- and
+-- .I nsec
+-- set to 2LL ^ 62, the maximum positive values according to Lua.
+function Timespec:max_init()
+ local ts = ffi.new("core_timespec_t")
+ ts.sec = 2LL ^ 62
+ ts.nsec = 2LL ^ 62
+ return ts
+end
+
+return Timespec
diff --git a/src/dnsjit.c b/src/dnsjit.c
index 0caa202..1024c4e 100644
--- a/src/dnsjit.c
+++ b/src/dnsjit.c
@@ -52,17 +52,6 @@ int main(int argc, char* argv[])
sigset_t set;
pthread_t sighthr;
-#ifdef PACKAGE_NAME
- fprintf(stderr, "<< " PACKAGE_NAME
-#ifdef PACKAGE_VERSION
- " v" PACKAGE_VERSION
-#endif
-#ifdef PACKAGE_URL
- " " PACKAGE_URL
-#endif
- " >>\n");
-#endif
-
if (argc < 2) {
fprintf(stderr, "usage: %s <file.lua> ...\n", argv[0]);
exit(1);
diff --git a/src/filter/copy.h b/src/filter/copy.h
index 96c8db0..d65a552 100644
--- a/src/filter/copy.h
+++ b/src/filter/copy.h
@@ -18,13 +18,13 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/object.h"
-#include "core/receiver.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/object.h>
+#include <dnsjit/core/receiver.h>
#ifndef __dnsjit_filter_copy_h
#define __dnsjit_filter_copy_h
-#include "filter/copy.hh"
+#include <dnsjit/filter/copy.hh>
#endif
diff --git a/src/filter/ipsplit.h b/src/filter/ipsplit.h
index 16c932e..aa64878 100644
--- a/src/filter/ipsplit.h
+++ b/src/filter/ipsplit.h
@@ -18,12 +18,12 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
#ifndef __dnsjit_filter_ipsplit_h
#define __dnsjit_filter_ipsplit_h
-#include "filter/ipsplit.hh"
+#include <dnsjit/filter/ipsplit.hh>
#endif
diff --git a/src/filter/layer.h b/src/filter/layer.h
index da8671c..d7dde4a 100644
--- a/src/filter/layer.h
+++ b/src/filter/layer.h
@@ -18,27 +18,27 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
-#include "core/object/pcap.h"
-#include "core/object/null.h"
-#include "core/object/ether.h"
-#include "core/object/loop.h"
-#include "core/object/linuxsll.h"
-#include "core/object/ieee802.h"
-#include "core/object/ip.h"
-#include "core/object/ip6.h"
-#include "core/object/gre.h"
-#include "core/object/icmp.h"
-#include "core/object/icmp6.h"
-#include "core/object/udp.h"
-#include "core/object/tcp.h"
-#include "core/object/payload.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
+#include <dnsjit/core/object/pcap.h>
+#include <dnsjit/core/object/null.h>
+#include <dnsjit/core/object/ether.h>
+#include <dnsjit/core/object/loop.h>
+#include <dnsjit/core/object/linuxsll.h>
+#include <dnsjit/core/object/ieee802.h>
+#include <dnsjit/core/object/ip.h>
+#include <dnsjit/core/object/ip6.h>
+#include <dnsjit/core/object/gre.h>
+#include <dnsjit/core/object/icmp.h>
+#include <dnsjit/core/object/icmp6.h>
+#include <dnsjit/core/object/udp.h>
+#include <dnsjit/core/object/tcp.h>
+#include <dnsjit/core/object/payload.h>
#ifndef __dnsjit_filter_layer_h
#define __dnsjit_filter_layer_h
-#include "filter/layer.hh"
+#include <dnsjit/filter/layer.hh>
#endif
diff --git a/src/filter/split.h b/src/filter/split.h
index 921b649..2b0be09 100644
--- a/src/filter/split.h
+++ b/src/filter/split.h
@@ -18,12 +18,12 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
#ifndef __dnsjit_filter_split_h
#define __dnsjit_filter_split_h
-#include "filter/split.hh"
+#include <dnsjit/filter/split.hh>
#endif
diff --git a/src/filter/timing.h b/src/filter/timing.h
index c00c43d..283155c 100644
--- a/src/filter/timing.h
+++ b/src/filter/timing.h
@@ -18,13 +18,13 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
#ifndef __dnsjit_filter_timing_h
#define __dnsjit_filter_timing_h
-#include "filter/timing.hh"
+#include <dnsjit/filter/timing.hh>
#endif
diff --git a/src/gen-makefile.sh b/src/gen-makefile.sh
deleted file mode 100755
index 18e48cb..0000000
--- a/src/gen-makefile.sh
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/bin/sh
-
-echo '# Copyright (c) 2018-2021, OARC, Inc.
-# All rights reserved.
-#
-# This file is part of dnsjit.
-#
-# dnsjit 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.
-#
-# dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
-CLEANFILES = *.gcda *.gcno *.gcov
-
-SUBDIRS = test
-
-AM_CFLAGS = -Werror=attributes \
- -I$(srcdir) \
- -I$(top_srcdir) \
- $(SIMD_FLAGS) $(CPUEXT_FLAGS) \
- $(PTHREAD_CFLAGS) \
- $(luajit_CFLAGS) \
- $(libuv_CFLAGS) \
- $(libnghttp2_CFLAGS)
-
-EXTRA_DIST = gen-manpage.lua gen-compat.lua gen-errno.sh dnsjit.1in
-
-BUILT_SOURCES = core/compat.hh core/log_errstr.c
-
-bin_PROGRAMS = dnsjit
-
-dnsjit_SOURCES = dnsjit.c globals.c
-dist_dnsjit_SOURCES = core.lua lib.lua input.lua filter.lua globals.h \
- output.lua
-lua_hobjects = core/compat.luaho
-lua_objects = core.luao lib.luao input.luao filter.luao output.luao
-dnsjit_LDADD = $(PTHREAD_LIBS) $(luajit_LIBS) $(libuv_LIBS) $(libnghttp2_LIBS)
-
-# C source and headers';
-
-echo "dnsjit_SOURCES +=`find core lib input filter output -type f -name '*.c' | sort | while read line; do echo -n " $line"; done`"
-echo "dist_dnsjit_SOURCES +=`find core lib input filter output -type f -name '*.h' | sort | while read line; do echo -n " $line"; done`"
-
-echo '
-# Lua headers'
-echo "dist_dnsjit_SOURCES +=`find core lib input filter output -type f -name '*.hh' | sort | while read line; do echo -n " $line"; done`"
-echo "lua_hobjects +=`find core lib input filter output -type f -name '*.hh' | sed -e 's%.hh%.luaho%g' | sort | while read line; do echo -n " $line"; done`"
-
-echo '
-# Lua sources'
-echo "dist_dnsjit_SOURCES +=`find core lib input filter output -type f -name '*.lua' | sort | while read line; do echo -n " $line"; done`"
-echo "lua_objects +=`find core lib input filter output -type f -name '*.lua' | sed -e 's%.lua%.luao%g' | sort | while read line; do echo -n " $line"; done`"
-
-echo '
-dnsjit_LDFLAGS = -Wl,-E
-dnsjit_LDADD += $(lua_hobjects) $(lua_objects)
-CLEANFILES += $(lua_hobjects) $(lua_objects)
-
-man1_MANS = dnsjit.1
-CLEANFILES += $(man1_MANS)
-
-man3_MANS = dnsjit.core.3 dnsjit.lib.3 dnsjit.input.3 dnsjit.filter.3 dnsjit.output.3';
-echo "man3_MANS +=`find core lib input filter output -type f -name '*.lua' | sed -e 's%.lua%.3%g' | sed -e 's%/%.%g' | sort | while read line; do echo -n " dnsjit.$line"; done`"
-
-echo 'CLEANFILES += *.3in $(man3_MANS)
-
-.lua.luao:
- @mkdir -p `dirname "$@"`
- $(LUAJIT) -bg -n "dnsjit.`echo \"$@\" | sed '"'"'s%\..*%%'"'"' | sed '"'"'s%/%.%g'"'"'`" -t o "$<" "$@"
-
-.luah.luaho:
- @mkdir -p `dirname "$@"`
- $(LUAJIT) -bg -n "dnsjit.`echo \"$@\" | sed '"'"'s%\..*%%'"'"' | sed '"'"'s%/%.%g'"'"'`_h" -t o "$<" "$@"
-
-.hh.luah:
- @mkdir -p `dirname "$@"`
- @echo '"'"'module(...,package.seeall);'"'"' > "$@"
- @cat "$<" | grep '"'"'^//lua:'"'"' | sed '"'"'s%^//lua:%%'"'"' >> "$@"
- @echo '"'"'require("ffi").cdef[['"'"' >> "$@"
- @cat "$<" | grep -v '"'"'^#'"'"' >> "$@"
- @echo '"'"']]'"'"' >> "$@"
-
-.1in.1:
- sed -e '"'"'s,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g'"'"' \
- -e '"'"'s,[@]PACKAGE_URL[@],$(PACKAGE_URL),g'"'"' \
- -e '"'"'s,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g'"'"' \
- < "$<" > "$@"
-
-.3in.3:
- sed -e '"'"'s,[@]PACKAGE_VERSION[@],$(PACKAGE_VERSION),g'"'"' \
- -e '"'"'s,[@]PACKAGE_URL[@],$(PACKAGE_URL),g'"'"' \
- -e '"'"'s,[@]PACKAGE_BUGREPORT[@],$(PACKAGE_BUGREPORT),g'"'"' \
- < "$<" > "$@"
-
-if ENABLE_GCOV
-gcov-local:
- for src in $(dnsjit_SOURCES); do \
- gcov -x -l -r -s "$(srcdir)" "$$src"; \
- done
-endif
-
-core/compat.hh: gen-compat.lua
- $(LUAJIT) "$(srcdir)/gen-compat.lua" > "$@"
-
-core/log_errstr.c: gen-errno.sh
- "$(srcdir)/gen-errno.sh" > "$@"
-';
-
-for file in core.lua lib.lua input.lua filter.lua output.lua; do
- man=`echo "$file"|sed -e 's%.lua%.3%g'|sed -e 's%/%.%g'`
-echo "
-dnsjit.${man}in: $file gen-manpage.lua
- \$(LUAJIT) \"\$(srcdir)/gen-manpage.lua\" \"\$(srcdir)/$file\" > \"\$@\"";
-done
-
-find core lib input filter output -type f -name '*.lua' | sort | while read file; do
- man=`echo "$file"|sed -e 's%.lua%.3%g'|sed -e 's%/%.%g'`
-echo "
-dnsjit.${man}in: $file gen-manpage.lua
- \$(LUAJIT) \"\$(srcdir)/gen-manpage.lua\" \"\$(srcdir)/$file\" > \"\$@\"";
-done
diff --git a/src/gen-manpage.lua b/src/gen-manpage.lua
index d4d63c4..e285b1f 100644
--- a/src/gen-manpage.lua
+++ b/src/gen-manpage.lua
@@ -100,9 +100,10 @@ for line in io.lines(arg[1]) do
end
print[[
-.SH AUTHORS
+.SH AUTHORS and CONTRIBUTORS
Jerry Lundström (DNS-OARC),
-Tomáš Křížek (CZ.NIC)
+Tomáš Křížek (CZ.NIC),
+Petr Špaček (ISC)
.LP
Maintained by DNS-OARC
.LP
diff --git a/src/input.lua b/src/input.lua
index 719f624..f791f17 100644
--- a/src/input.lua
+++ b/src/input.lua
@@ -25,5 +25,6 @@ module(...,package.seeall)
-- dnsjit.input.fpcap (3),
-- dnsjit.input.mmpcap (3),
-- dnsjit.input.pcap (3),
--- dnsjit.input.zero (3)
+-- dnsjit.input.zero (3),
+-- dnsjit.input.zpcap (3)
return
diff --git a/src/input/fpcap.c b/src/input/fpcap.c
index de054ec..6804608 100644
--- a/src/input/fpcap.c
+++ b/src/input/fpcap.c
@@ -24,6 +24,7 @@
#include "core/assert.h"
#include "core/object/pcap.h"
+#include <fcntl.h>
#include <stdio.h>
#ifdef HAVE_ENDIAN_H
#include <endian.h>
@@ -60,7 +61,7 @@ static input_fpcap_t _defaults = {
0, 0,
0, 0, 0,
CORE_OBJECT_PCAP_INIT(0),
- 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0,
0
};
@@ -91,6 +92,16 @@ static int _open(input_fpcap_t* self)
{
mlassert_self();
+#if _POSIX_C_SOURCE >= 200112L || defined(__FreeBSD__)
+ if (self->use_fadvise) {
+ int err = posix_fadvise(fileno((FILE*)self->file), 0, 0, POSIX_FADV_SEQUENTIAL);
+ if (err) {
+ lcritical("posix_fadvise() failed: %s", core_log_errstr(err));
+ return -2;
+ }
+ }
+#endif
+
if (fread(&self->magic_number, 1, 4, self->file) != 4
|| fread(&self->version_major, 1, 2, self->file) != 2
|| fread(&self->version_minor, 1, 2, self->file) != 2
diff --git a/src/input/fpcap.h b/src/input/fpcap.h
index da3596c..4e1e5ee 100644
--- a/src/input/fpcap.h
+++ b/src/input/fpcap.h
@@ -18,14 +18,14 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
-#include "core/object/pcap.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
+#include <dnsjit/core/object/pcap.h>
#ifndef __dnsjit_input_fpcap_h
#define __dnsjit_input_fpcap_h
-#include "input/fpcap.hh"
+#include <dnsjit/input/fpcap.hh>
#endif
diff --git a/src/input/fpcap.hh b/src/input/fpcap.hh
index 0ced83c..ab06a71 100644
--- a/src/input/fpcap.hh
+++ b/src/input/fpcap.hh
@@ -35,7 +35,7 @@ typedef struct input_fpcap {
core_object_pcap_t prod_pkt;
void* file;
- int extern_file;
+ int extern_file, use_fadvise;
size_t pkts;
uint8_t* buf;
size_t buf_size;
diff --git a/src/input/fpcap.lua b/src/input/fpcap.lua
index 2fc2906..b50fc11 100644
--- a/src/input/fpcap.lua
+++ b/src/input/fpcap.lua
@@ -100,6 +100,15 @@ function Fpcap:produce()
return C.input_fpcap_producer(self.obj), self.obj
end
+-- Use
+-- .B posix_fadvise()
+-- to indicate sequential reading (if supported), may increase performance.
+-- MUST be called before
+-- .BR open() .
+function Fpcap:fadvise_sequential()
+ self.obj.use_fadvise = 1
+end
+
-- Open a PCAP file for processing and read the PCAP header.
-- Returns 0 on success.
function Fpcap:open(file)
diff --git a/src/input/mmpcap.h b/src/input/mmpcap.h
index 0873858..b4ae09a 100644
--- a/src/input/mmpcap.h
+++ b/src/input/mmpcap.h
@@ -18,14 +18,14 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
-#include "core/object/pcap.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
+#include <dnsjit/core/object/pcap.h>
#ifndef __dnsjit_input_mmpcap_h
#define __dnsjit_input_mmpcap_h
-#include "input/mmpcap.hh"
+#include <dnsjit/input/mmpcap.hh>
#endif
diff --git a/src/input/pcap.h b/src/input/pcap.h
index 0a53de5..cba5227 100644
--- a/src/input/pcap.h
+++ b/src/input/pcap.h
@@ -18,16 +18,16 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
-#include "core/object/pcap.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
+#include <dnsjit/core/object/pcap.h>
#ifndef __dnsjit_input_pcap_h
#define __dnsjit_input_pcap_h
#include <pcap/pcap.h>
-#include "input/pcap.hh"
+#include <dnsjit/input/pcap.hh>
#endif
diff --git a/src/input/zero.c b/src/input/zero.c
deleted file mode 100644
index 8bb1cf6..0000000
--- a/src/input/zero.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2018-2021, OARC, Inc.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "input/zero.h"
-#include "core/assert.h"
-#include "core/object/null.h"
-
-#include <time.h>
-
-static core_log_t _log = LOG_T_INIT("input.zero");
-static input_zero_t _defaults = {
- LOG_T_INIT_OBJ("input.zero"),
- 0,
- 0,
-};
-
-static core_object_null_t _null = CORE_OBJECT_NULL_INIT(0);
-
-core_log_t* input_zero_log()
-{
- return &_log;
-}
-
-void input_zero_init(input_zero_t* self)
-{
- mlassert_self();
-
- *self = _defaults;
-}
-
-void input_zero_destroy(input_zero_t* self)
-{
- mlassert_self();
-}
-
-void input_zero_run(input_zero_t* self, uint64_t num)
-{
- mlassert_self();
- if (!self->recv) {
- lfatal("no receiver set");
- }
-
- while (num--) {
- self->recv(self->ctx, (core_object_t*)&_null);
- }
-}
-
-static const core_object_t* _produce(void* ctx)
-{
- return (core_object_t*)&_null;
-}
-
-core_producer_t input_zero_producer()
-{
- return _produce;
-}
diff --git a/src/input/zero.lua b/src/input/zero.lua
index 1907dce..c6bf5a4 100644
--- a/src/input/zero.lua
+++ b/src/input/zero.lua
@@ -17,59 +17,15 @@
-- along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.input.zero
--- Generate empty objects (/dev/zero)
--- local input = require("dnsjit.input.zero").new()
--- input:receiver(filter_or_output)
--- input:run(1e6)
+-- Dummy layer to example.input.zero
--
--- Input module for generating empty
--- .I core.object.null
--- objects, mostly used for testing.
+-- This module has moved to example.input.zero, see examples/modules/input-example in
+-- dnsjit source repository.
module(...,package.seeall)
-require("dnsjit.input.zero_h")
-local ffi = require("ffi")
-local C = ffi.C
-
-local t_name = "input_zero_t"
-local input_zero_t = ffi.typeof(t_name)
-local Zero = {}
-
--- Create a new Zero input.
-function Zero.new()
- local self = {
- _receiver = nil,
- obj = input_zero_t(),
- }
- C.input_zero_init(self.obj)
- ffi.gc(self.obj, C.input_zero_destroy)
- return setmetatable(self, { __index = Zero })
-end
-
--- Return the Log object to control logging of this instance or module.
-function Zero:log()
- if self == nil then
- return C.input_zero_log()
- end
- return self.obj._log
-end
-
--- Set the receiver to pass objects to.
-function Zero:receiver(o)
- self.obj.recv, self.obj.ctx = o:receive()
- self._receiver = o
-end
-
--- Return the C functions and context for producing objects.
-function Zero:produce()
- return C.input_zero_producer(), self.obj
-end
-
--- Generate
--- .I num
--- empty objects and send them to the receiver.
-function Zero:run(num)
- C.input_zero_run(self.obj, num)
+ok, cls = pcall(require, "example.input.zero")
+if not ok then
+ error("You need to install the example module input-example\n" .. cls)
end
-return Zero
+return cls
diff --git a/src/input/zpcap.c b/src/input/zpcap.c
new file mode 100644
index 0000000..11eab9a
--- /dev/null
+++ b/src/input/zpcap.c
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "input/zpcap.h"
+#include "core/assert.h"
+#include "core/object/pcap.h"
+
+#include <fcntl.h>
+#include <stdio.h>
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#else
+#ifdef HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#else
+#ifdef HAVE_MACHINE_ENDIAN_H
+#include <machine/endian.h>
+#endif
+#endif
+#endif
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#endif
+#ifndef bswap_16
+#ifndef bswap16
+#define bswap_16(x) swap16(x)
+#define bswap_32(x) swap32(x)
+#define bswap_64(x) swap64(x)
+#else
+#define bswap_16(x) bswap16(x)
+#define bswap_32(x) bswap32(x)
+#define bswap_64(x) bswap64(x)
+#endif
+#endif
+#include <pcap/pcap.h>
+#include <string.h>
+
+#ifdef HAVE_LZ4
+#include <lz4frame.h>
+struct _lz4_ctx {
+ LZ4F_dctx* ctx;
+ LZ4F_decompressOptions_t opts;
+};
+#define lz4 ((struct _lz4_ctx*)self->comp_ctx)
+#endif
+#ifdef HAVE_ZSTD
+#include <zstd.h>
+struct _zstd_ctx {
+ ZSTD_DCtx* ctx;
+ ZSTD_inBuffer in;
+ ZSTD_outBuffer out;
+};
+#define zstd ((struct _zstd_ctx*)self->comp_ctx)
+#endif
+
+#define MAX_SNAPLEN 0x40000
+
+static core_log_t _log = LOG_T_INIT("input.zpcap");
+static input_zpcap_t _defaults = {
+ LOG_T_INIT_OBJ("input.zpcap"),
+ 0, 0,
+ 0, 0, 0,
+ CORE_OBJECT_PCAP_INIT(0),
+ input_zpcap_type_none, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0
+};
+
+core_log_t* input_zpcap_log()
+{
+ return &_log;
+}
+
+void input_zpcap_init(input_zpcap_t* self)
+{
+ mlassert_self();
+
+ *self = _defaults;
+}
+
+void input_zpcap_destroy(input_zpcap_t* self)
+{
+ mlassert_self();
+
+ switch (self->compression) {
+#ifdef HAVE_LZ4
+ case input_zpcap_type_lz4: {
+ LZ4F_errorCode_t code;
+
+ if (lz4) {
+ if (lz4->ctx && (code = LZ4F_freeDecompressionContext(lz4->ctx))) {
+ lfatal("LZ4F_freeDecompressionContext() failed: %s", LZ4F_getErrorName(code));
+ }
+ }
+ free(lz4);
+ free(self->in);
+ free(self->out);
+ break;
+ }
+#endif
+#ifdef HAVE_ZSTD
+ case input_zpcap_type_zstd:
+ if (zstd) {
+ if (zstd->ctx) {
+ ZSTD_freeDCtx(zstd->ctx);
+ }
+ }
+ free(zstd);
+ free(self->in);
+ free(self->out);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ if (!self->extern_file && self->file) {
+ fclose(self->file);
+ }
+ free(self->buf);
+}
+
+static ssize_t _read(input_zpcap_t* self, void* dst, size_t len, void** dstp)
+{
+ switch (self->compression) {
+#ifdef HAVE_LZ4
+ case input_zpcap_type_lz4: {
+ size_t need = len;
+
+ if (dstp && self->out_have > need) {
+ *dstp = self->out + self->out_at;
+ self->out_have -= need;
+ self->out_at += need;
+ return len;
+ }
+
+ for (;;) {
+ if (self->out_have > need) {
+ memcpy(dst, self->out + self->out_at, need);
+ self->out_have -= need;
+ self->out_at += need;
+ return len;
+ }
+
+ memcpy(dst, self->out + self->out_at, self->out_have);
+ need -= self->out_have;
+ dst += self->out_have;
+
+ ssize_t n = fread(self->in + self->in_at, 1, self->in_size - self->in_have, self->file);
+ if (n < 0) {
+ return n;
+ }
+ self->in_at += n;
+ self->in_have += n;
+ if (!self->in_have) {
+ return 0;
+ }
+
+ size_t dst_size = self->out_size, src_size = self->in_have;
+ size_t code = LZ4F_decompress(lz4->ctx, self->out, &dst_size, self->in, &src_size, &lz4->opts);
+ if (LZ4F_isError(code)) {
+ lfatal("LZ4F_decompress() failed: %s", LZ4F_getErrorName(code));
+ }
+
+ if (src_size < self->in_have) {
+ self->in_have -= src_size;
+ memmove(self->in, self->in + src_size, self->in_have);
+ self->in_at = self->in_have;
+ } else {
+ self->in_at = 0;
+ self->in_have = 0;
+ }
+
+ self->out_at = 0;
+ self->out_have = dst_size;
+ }
+ }
+#endif
+#ifdef HAVE_ZSTD
+ case input_zpcap_type_zstd: {
+ size_t need = len;
+
+ if (dstp && self->out_have > need) {
+ *dstp = self->out + self->out_at;
+ self->out_have -= need;
+ self->out_at += need;
+ return len;
+ }
+
+ for (;;) {
+ if (self->out_have > need) {
+ memcpy(dst, self->out + self->out_at, need);
+ self->out_have -= need;
+ self->out_at += need;
+ return len;
+ }
+
+ memcpy(dst, self->out + self->out_at, self->out_have);
+ need -= self->out_have;
+ dst += self->out_have;
+
+ if (zstd->in.pos >= zstd->in.size) {
+ ssize_t n = fread(self->in, 1, self->in_size, self->file);
+ if (n < 1) {
+ return n;
+ }
+ zstd->in.size = n;
+ zstd->in.pos = 0;
+ }
+
+ zstd->out.size = self->out_size;
+ zstd->out.pos = 0;
+ size_t code = ZSTD_decompressStream(zstd->ctx, &zstd->out, &zstd->in);
+ if (ZSTD_isError(code)) {
+ lfatal("ZSTD_decompressStream() failed: %s", ZSTD_getErrorName(code));
+ }
+
+ self->out_have = zstd->out.pos;
+ self->out_at = 0;
+ }
+ }
+#endif
+ default:
+ return 0;
+ }
+}
+
+static int _open(input_zpcap_t* self)
+{
+ mlassert_self();
+
+#if _POSIX_C_SOURCE >= 200112L || defined(__FreeBSD__)
+ if (self->use_fadvise) {
+ int err = posix_fadvise(fileno((FILE*)self->file), 0, 0, POSIX_FADV_SEQUENTIAL);
+ if (err) {
+ lcritical("posix_fadvise() failed: %s", core_log_errstr(err));
+ return -2;
+ }
+ }
+#endif
+
+ switch (self->compression) {
+#ifdef HAVE_LZ4
+ case input_zpcap_type_lz4: {
+ LZ4F_errorCode_t code;
+
+ if (lz4) {
+ if (lz4->ctx && (code = LZ4F_freeDecompressionContext(lz4->ctx))) {
+ lfatal("LZ4F_freeDecompressionContext() failed: %s", LZ4F_getErrorName(code));
+ }
+ }
+ free(lz4);
+ free(self->in);
+ free(self->out);
+
+ lfatal_oom(self->comp_ctx = calloc(1, sizeof(struct _lz4_ctx)));
+ if ((code = LZ4F_createDecompressionContext(&lz4->ctx, LZ4F_VERSION))) {
+ lfatal("LZ4F_createDecompressionContext() failed: %s", LZ4F_getErrorName(code));
+ }
+ lz4->opts.stableDst = 1;
+
+ self->in_size = 256 * 1024;
+ lfatal_oom(self->in = malloc(self->in_size));
+ self->out_size = 256 * 1024;
+ lfatal_oom(self->out = malloc(self->out_size));
+
+ break;
+ }
+#endif
+#ifdef HAVE_ZSTD
+ case input_zpcap_type_zstd:
+ if (zstd) {
+ if (zstd->ctx) {
+ ZSTD_freeDCtx(zstd->ctx);
+ }
+ }
+ free(zstd);
+ free(self->in);
+ free(self->out);
+
+ lfatal_oom(self->comp_ctx = calloc(1, sizeof(struct _zstd_ctx)));
+ lfatal_oom(zstd->ctx = ZSTD_createDCtx());
+ self->in_size = ZSTD_DStreamInSize();
+ lfatal_oom(self->in = malloc(self->in_size));
+ self->out_size = ZSTD_DStreamOutSize();
+ lfatal_oom(self->out = malloc(self->out_size));
+
+ zstd->in.src = self->in;
+ zstd->out.dst = self->out;
+ zstd->out.size = self->out_size;
+ break;
+#endif
+ default:
+ lcritical("no support for selected compression");
+ return -2;
+ }
+
+ if (_read(self, &self->magic_number, 4, 0) != 4
+ || _read(self, &self->version_major, 2, 0) != 2
+ || _read(self, &self->version_minor, 2, 0) != 2
+ || _read(self, &self->thiszone, 4, 0) != 4
+ || _read(self, &self->sigfigs, 4, 0) != 4
+ || _read(self, &self->snaplen, 4, 0) != 4
+ || _read(self, &self->network, 4, 0) != 4) {
+ lcritical("could not read full PCAP header");
+ return -2;
+ }
+ switch (self->magic_number) {
+ case 0x4d3cb2a1:
+ self->is_nanosec = 1;
+ case 0xd4c3b2a1:
+ self->is_swapped = 1;
+ self->version_major = bswap_16(self->version_major);
+ self->version_minor = bswap_16(self->version_minor);
+ self->thiszone = (int32_t)bswap_32((uint32_t)self->thiszone);
+ self->sigfigs = bswap_32(self->sigfigs);
+ self->snaplen = bswap_32(self->snaplen);
+ self->network = bswap_32(self->network);
+ break;
+ case 0xa1b2c3d4:
+ case 0xa1b23c4d:
+ break;
+ default:
+ lcritical("invalid PCAP header");
+ return -2;
+ }
+
+ if (self->snaplen > MAX_SNAPLEN) {
+ lcritical("too large snaplen (%u)", self->snaplen);
+ return -2;
+ }
+
+ if (self->version_major != 2 || self->version_minor != 4) {
+ lcritical("unsupported PCAP version v%u.%u", self->version_major, self->version_minor);
+ return -2;
+ }
+
+ /*
+ * Translation taken from https://github.com/the-tcpdump-group/libpcap/blob/90543970fd5fbed261d3637f5ec4811d7dde4e49/pcap-common.c#L1212 .
+ */
+ switch (self->network) {
+ case 101:
+ self->linktype = DLT_RAW;
+ break;
+#ifdef DLT_FR
+ case 107: /* LINKTYPE_FRELAY */
+ self->linktype = DLT_FR;
+ break;
+#endif
+ case 100: /* LINKTYPE_ATM_RFC1483 */
+ self->linktype = DLT_ATM_RFC1483;
+ break;
+ case 102: /* LINKTYPE_SLIP_BSDOS */
+ self->linktype = DLT_SLIP_BSDOS;
+ break;
+ case 103: /* LINKTYPE_PPP_BSDOS */
+ self->linktype = DLT_PPP_BSDOS;
+ break;
+ case 104: /* LINKTYPE_C_HDLC */
+ self->linktype = DLT_C_HDLC;
+ break;
+ case 106: /* LINKTYPE_ATM_CLIP */
+ self->linktype = DLT_ATM_CLIP;
+ break;
+ case 50: /* LINKTYPE_PPP_HDLC */
+ self->linktype = DLT_PPP_SERIAL;
+ break;
+ case 51: /* LINKTYPE_PPP_ETHER */
+ self->linktype = DLT_PPP_ETHER;
+ break;
+ default:
+ self->linktype = self->network;
+ }
+
+ lfatal_oom(self->buf = malloc(self->snaplen));
+ self->prod_pkt.snaplen = self->snaplen;
+ self->prod_pkt.linktype = self->linktype;
+ self->prod_pkt.is_swapped = self->is_swapped;
+
+ ldebug("pcap v%u.%u snaplen:%lu %s", self->version_major, self->version_minor, self->snaplen, self->is_swapped ? " swapped" : "");
+
+ return 0;
+}
+
+int input_zpcap_open(input_zpcap_t* self, const char* file)
+{
+ mlassert_self();
+ lassert(file, "file is nil");
+
+ if (self->file) {
+ lfatal("already opened");
+ }
+
+ if (!(self->file = fopen(file, "rb"))) {
+ lcritical("fopen(%s) error: %s", file, core_log_errstr(errno));
+ return -1;
+ }
+
+ return _open(self);
+}
+
+int input_zpcap_openfp(input_zpcap_t* self, void* fp)
+{
+ mlassert_self();
+
+ if (self->file) {
+ lfatal("already opened");
+ }
+
+ self->file = fp;
+ self->extern_file = 1;
+
+ return _open(self);
+}
+
+int input_zpcap_run(input_zpcap_t* self)
+{
+ struct {
+ uint32_t ts_sec;
+ uint32_t ts_usec;
+ uint32_t incl_len;
+ uint32_t orig_len;
+ } hdr;
+ core_object_pcap_t pkt = CORE_OBJECT_PCAP_INIT(0);
+ int ret;
+ mlassert_self();
+
+ if (!self->file) {
+ lfatal("no PCAP opened");
+ }
+ if (!self->recv) {
+ lfatal("no receiver set");
+ }
+
+ pkt.snaplen = self->snaplen;
+ pkt.linktype = self->linktype;
+ pkt.is_swapped = self->is_swapped;
+
+ while ((ret = _read(self, &hdr, 16, 0)) == 16) {
+ if (self->is_swapped) {
+ hdr.ts_sec = bswap_32(hdr.ts_sec);
+ hdr.ts_usec = bswap_32(hdr.ts_usec);
+ hdr.incl_len = bswap_32(hdr.incl_len);
+ hdr.orig_len = bswap_32(hdr.orig_len);
+ }
+ if (hdr.incl_len > self->snaplen) {
+ lwarning("invalid packet length, larger then snaplen");
+ return -1;
+ }
+ pkt.bytes = (unsigned char*)self->buf;
+ if (_read(self, self->buf, hdr.incl_len, (void**)&pkt.bytes) != hdr.incl_len) {
+ lwarning("could not read all of packet, aborting");
+ return -1;
+ }
+
+ self->pkts++;
+
+ pkt.ts.sec = hdr.ts_sec;
+ if (self->is_nanosec) {
+ pkt.ts.nsec = hdr.ts_usec;
+ } else {
+ pkt.ts.nsec = hdr.ts_usec * 1000;
+ }
+ pkt.caplen = hdr.incl_len;
+ pkt.len = hdr.orig_len;
+
+ self->recv(self->ctx, (core_object_t*)&pkt);
+ }
+ if (ret) {
+ lwarning("could not read next PCAP header, aborting");
+ return -1;
+ }
+
+ return 0;
+}
+
+int input_zpcap_have_support(input_zpcap_t* self)
+{
+ mlassert_self();
+
+ switch (self->compression) {
+#ifdef HAVE_LZ4
+ case input_zpcap_type_lz4:
+ return 1;
+#endif
+#ifdef HAVE_ZSTD
+ case input_zpcap_type_zstd:
+ return 1;
+#endif
+ default:
+ break;
+ }
+ return 0;
+}
+
+static const core_object_t* _produce(input_zpcap_t* self)
+{
+ struct {
+ uint32_t ts_sec;
+ uint32_t ts_usec;
+ uint32_t incl_len;
+ uint32_t orig_len;
+ } hdr;
+ int ret;
+ mlassert_self();
+
+ if (self->is_broken) {
+ lwarning("PCAP is broken, will not read next packet");
+ return 0;
+ }
+
+ if ((ret = _read(self, &hdr, 16, 0)) != 16) {
+ if (ret) {
+ lwarning("could not read next PCAP header, aborting");
+ self->is_broken = 1;
+ }
+ return 0;
+ }
+
+ if (self->is_swapped) {
+ hdr.ts_sec = bswap_32(hdr.ts_sec);
+ hdr.ts_usec = bswap_32(hdr.ts_usec);
+ hdr.incl_len = bswap_32(hdr.incl_len);
+ hdr.orig_len = bswap_32(hdr.orig_len);
+ }
+ if (hdr.incl_len > self->snaplen) {
+ lwarning("invalid packet length, larger then snaplen");
+ self->is_broken = 1;
+ return 0;
+ }
+ self->prod_pkt.bytes = (unsigned char*)self->buf;
+ if (_read(self, self->buf, hdr.incl_len, (void**)&self->prod_pkt.bytes) != hdr.incl_len) {
+ lwarning("could not read all of packet, aborting");
+ self->is_broken = 1;
+ return 0;
+ }
+
+ self->pkts++;
+
+ self->prod_pkt.ts.sec = hdr.ts_sec;
+ if (self->is_nanosec) {
+ self->prod_pkt.ts.nsec = hdr.ts_usec;
+ } else {
+ self->prod_pkt.ts.nsec = hdr.ts_usec * 1000;
+ }
+ self->prod_pkt.caplen = hdr.incl_len;
+ self->prod_pkt.len = hdr.orig_len;
+
+ return (core_object_t*)&self->prod_pkt;
+}
+
+core_producer_t input_zpcap_producer(input_zpcap_t* self)
+{
+ mlassert_self();
+
+ if (!self->file) {
+ lfatal("no PCAP opened");
+ }
+
+ return (core_producer_t)_produce;
+}
diff --git a/src/input/zpcap.h b/src/input/zpcap.h
new file mode 100644
index 0000000..7f6f304
--- /dev/null
+++ b/src/input/zpcap.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
+#include <dnsjit/core/object/pcap.h>
+
+#ifndef __dnsjit_input_zpcap_h
+#define __dnsjit_input_zpcap_h
+
+#include <dnsjit/input/zpcap.hh>
+
+#endif
diff --git a/src/input/zpcap.hh b/src/input/zpcap.hh
new file mode 100644
index 0000000..bc013fa
--- /dev/null
+++ b/src/input/zpcap.hh
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//lua:require("dnsjit.core.log")
+//lua:require("dnsjit.core.receiver_h")
+//lua:require("dnsjit.core.producer_h")
+//lua:require("dnsjit.core.object.pcap_h")
+
+typedef enum input_zpcap_type {
+ input_zpcap_type_none,
+ input_zpcap_type_lz4,
+ input_zpcap_type_zstd
+} input_zpcap_type_t;
+
+typedef struct input_zpcap {
+ core_log_t _log;
+ core_receiver_t recv;
+ void* ctx;
+
+ uint8_t is_swapped;
+ uint8_t is_nanosec;
+ uint8_t is_broken;
+
+ core_object_pcap_t prod_pkt;
+
+ input_zpcap_type_t compression;
+ void* comp_ctx;
+
+ void * in, *out;
+ size_t in_size, out_size;
+ size_t in_have, out_have;
+ size_t in_at, out_at;
+
+ void* file;
+ int extern_file, use_fadvise;
+ size_t pkts;
+ uint8_t* buf;
+ size_t buf_size;
+
+ uint32_t magic_number;
+ uint16_t version_major;
+ uint16_t version_minor;
+ int32_t thiszone;
+ uint32_t sigfigs;
+ uint32_t snaplen;
+ uint32_t network;
+
+ uint32_t linktype;
+} input_zpcap_t;
+
+core_log_t* input_zpcap_log();
+
+void input_zpcap_init(input_zpcap_t* self);
+void input_zpcap_destroy(input_zpcap_t* self);
+int input_zpcap_open(input_zpcap_t* self, const char* file);
+int input_zpcap_openfp(input_zpcap_t* self, void* fp);
+int input_zpcap_run(input_zpcap_t* self);
+int input_zpcap_have_support(input_zpcap_t* self);
+
+core_producer_t input_zpcap_producer(input_zpcap_t* self);
diff --git a/src/input/zpcap.lua b/src/input/zpcap.lua
new file mode 100644
index 0000000..9a0230f
--- /dev/null
+++ b/src/input/zpcap.lua
@@ -0,0 +1,159 @@
+-- Copyright (c) 2018-2021, OARC, Inc.
+-- All rights reserved.
+--
+-- This file is part of dnsjit.
+--
+-- dnsjit 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.
+--
+-- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+
+-- dnsjit.input.zpcap
+-- Read input from a PCAP file that is compressed
+-- local input = require("dnsjit.input.zpcap").new()
+-- input:zstd()
+-- input:open("file.pcap.zst")
+-- input:receiver(filter_or_output)
+-- input:run()
+--
+-- Read input from a PCAP file that is compressed and parse the PCAP without
+-- libpcap.
+-- After opening a file and reading the PCAP header, the attributes are
+-- populated.
+-- .SS Attributes
+-- .TP
+-- is_swapped
+-- Indicate if the byte order in the PCAP is in reverse order of the host.
+-- .TP
+-- is_nanosec
+-- Indicate if the time stamps are in nanoseconds or not.
+-- .TP
+-- magic_number
+-- Magic number.
+-- .TP
+-- version_major
+-- Major version number.
+-- .TP
+-- version_minor
+-- Minor version number.
+-- .TP
+-- thiszone
+-- GMT to local correction.
+-- .TP
+-- sigfigs
+-- Accuracy of timestamps.
+-- .TP
+-- snaplen
+-- Max length of captured packets, in octets.
+-- .TP
+-- network
+-- The link type found in the PCAP header, see https://www.tcpdump.org/linktypes.html .
+-- .TP
+-- linktype
+-- The data link type, mapped from
+-- .IR network .
+module(...,package.seeall)
+
+require("dnsjit.input.zpcap_h")
+local ffi = require("ffi")
+local C = ffi.C
+
+local t_name = "input_zpcap_t"
+local input_zpcap_t = ffi.typeof(t_name)
+local Zpcap = {}
+
+-- Create a new Zpcap input.
+function Zpcap.new()
+ local self = {
+ _receiver = nil,
+ obj = input_zpcap_t(),
+ }
+ C.input_zpcap_init(self.obj)
+ ffi.gc(self.obj, C.input_zpcap_destroy)
+ return setmetatable(self, { __index = Zpcap })
+end
+
+-- Return the Log object to control logging of this instance or module.
+function Zpcap:log()
+ if self == nil then
+ return C.input_zpcap_log()
+ end
+ return self.obj._log
+end
+
+-- Set the receiver to pass objects to.
+function Zpcap:receiver(o)
+ self.obj.recv, self.obj.ctx = o:receive()
+ self._receiver = o
+end
+
+-- Return the C functions and context for producing objects.
+function Zpcap:produce()
+ return C.input_zpcap_producer(self.obj), self.obj
+end
+
+-- Use
+-- .B posix_fadvise()
+-- to indicate sequential reading (if supported), may increase performance.
+-- MUST be called before
+-- .BR open() .
+function Zpcap:fadvise_sequential()
+ self.obj.use_fadvise = 1
+end
+
+-- Use liblz4 to decompress the input file/data.
+function Zpcap:lz4()
+ self.obj.compression = "input_zpcap_type_lz4"
+end
+
+-- Use libzstd to decompress the input file/data.
+function Zpcap:zstd()
+ self.obj.compression = "input_zpcap_type_zstd"
+end
+
+-- Return true if support for selected compression library is built in.
+function Zpcap:have_support()
+ if C.input_zpcap_have_support(self.obj) == 1 then
+ return true
+ end
+ return false
+end
+
+-- Open a PCAP file for processing and read the PCAP header.
+-- Returns 0 on success.
+function Zpcap:open(file)
+ return C.input_zpcap_open(self.obj, file)
+end
+
+-- Open a PCAP file for processing and read the PCAP header using a
+-- file descriptor, for example
+-- .B io.stdin
+-- or with
+-- .BR io.open() .
+-- Will not take ownership of the file descriptor.
+-- Returns 0 on success.
+function Zpcap:openfp(fp)
+ return C.input_zpcap_openfp(self.obj, fp)
+end
+
+-- Start processing packets and send each packet read to the receiver.
+-- Returns 0 if all packets was read successfully.
+function Zpcap:run()
+ return C.input_zpcap_run(self.obj)
+end
+
+-- Return the number of packets seen.
+function Zpcap:packets()
+ return tonumber(self.obj.pkts)
+end
+
+-- dnsjit.input.fpcap (3)
+return Zpcap
diff --git a/src/lib/base64url.h b/src/lib/base64url.h
index d355598..f2f5808 100644
--- a/src/lib/base64url.h
+++ b/src/lib/base64url.h
@@ -23,6 +23,6 @@
#ifndef __dnsjit_lib_base64url_h
#define __dnsjit_lib_base64url_h
-#include "lib/base64url.hh"
+#include <dnsjit/lib/base64url.hh>
#endif
diff --git a/src/lib/base64url.lua b/src/lib/base64url.lua
index e9966d5..8a408f5 100644
--- a/src/lib/base64url.lua
+++ b/src/lib/base64url.lua
@@ -93,6 +93,5 @@ function Base64Url.decode(data)
return ffi.string(buf, out_len)
end
--- dnsjit.core.object.payload(3)
--- dnsjit.output.dnssim (3)
+-- dnsjit.core.object.payload (3)
return Base64Url
diff --git a/src/lib/clock.h b/src/lib/clock.h
index 0dc0faa..48d16ac 100644
--- a/src/lib/clock.h
+++ b/src/lib/clock.h
@@ -18,11 +18,11 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/timespec.h"
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_lib_clock_h
#define __dnsjit_lib_clock_h
-#include "lib/clock.hh"
+#include <dnsjit/lib/clock.hh>
#endif
diff --git a/src/lib/getopt.lua b/src/lib/getopt.lua
index 91ce6cd..ede3e12 100644
--- a/src/lib/getopt.lua
+++ b/src/lib/getopt.lua
@@ -122,6 +122,9 @@ function Getopt:add(short, long, default, help, extensions)
elseif name == "" then
error("name (long|short) needs to be set")
end
+ if short and (type(short) ~= "string" or #short ~= 1) then
+ error("short needs to be a string of length 1")
+ end
if self._opt[name] then
error("option "..name.." alredy exists")
diff --git a/src/lib/trie.h b/src/lib/trie.h
index 3ce881c..b8b8b78 100644
--- a/src/lib/trie.h
+++ b/src/lib/trie.h
@@ -22,7 +22,7 @@
#ifndef __dnsjit_contrib_trie_h
#define __dnsjit_contrib_trie_h
-#include "lib/trie.hh"
+#include <dnsjit/lib/trie.hh>
#ifndef likely
/*! \brief Optimize for x to be true value. */
diff --git a/src/output.lua b/src/output.lua
index 26663a2..43f90c3 100644
--- a/src/output.lua
+++ b/src/output.lua
@@ -24,7 +24,6 @@
module(...,package.seeall)
-- dnsjit.output.dnscli (3),
--- dnsjit.output.dnssim (3),
-- dnsjit.output.null (3),
-- dnsjit.output.pcap (3),
-- dnsjit.output.respdiff (3),
diff --git a/src/output/dnscli.h b/src/output/dnscli.h
index 27f2207..9927bd4 100644
--- a/src/output/dnscli.h
+++ b/src/output/dnscli.h
@@ -18,12 +18,12 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
-#include "core/object/payload.h"
-#include "core/timespec.h"
-#include "core/compat.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
+#include <dnsjit/core/object/payload.h>
+#include <dnsjit/core/timespec.h>
+#include <dnsjit/core/compat.h>
#ifndef __dnsjit_output_dnscli_h
#define __dnsjit_output_dnscli_h
@@ -33,6 +33,6 @@
#include <gnutls/gnutls.h>
#include <poll.h>
-#include "output/dnscli.hh"
+#include <dnsjit/output/dnscli.hh>
#endif
diff --git a/src/output/dnssim.c b/src/output/dnssim.c
deleted file mode 100644
index acd0a05..0000000
--- a/src/output/dnssim.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Copyright (c) 2019-2020, CZ.NIC, z.s.p.o.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "output/dnssim.h"
-#include "output/dnssim/internal.h"
-#include "output/dnssim/ll.h"
-#include "core/assert.h"
-#include "core/object/ip.h"
-#include "core/object/ip6.h"
-
-#include <gnutls/gnutls.h>
-#include <string.h>
-
-static core_log_t _log = LOG_T_INIT("output.dnssim");
-static output_dnssim_t _defaults = { LOG_T_INIT_OBJ("output.dnssim") };
-
-static uint64_t _now_ms()
-{
-#if HAVE_CLOCK_NANOSLEEP
- struct timespec ts;
- uint64_t now_ms;
- if (clock_gettime(CLOCK_REALTIME, &ts)) {
- mlfatal("clock_gettime()");
- }
- now_ms = ts.tv_sec * 1000;
- now_ms += ts.tv_nsec / 1000000;
- return now_ms;
-#else
- mlfatal("clock_gettime() not available");
- return 0;
-#endif
-}
-
-core_log_t* output_dnssim_log()
-{
- return &_log;
-}
-
-output_dnssim_t* output_dnssim_new(size_t max_clients)
-{
- output_dnssim_t* self;
- int ret, i;
-
- mlfatal_oom(self = calloc(1, sizeof(_output_dnssim_t)));
- *self = _defaults;
- self->handshake_timeout_ms = 5000;
- self->idle_timeout_ms = 10000;
- output_dnssim_timeout_ms(self, 2000);
-
- _self->source = NULL;
- _self->transport = OUTPUT_DNSSIM_TRANSPORT_UDP_ONLY;
- _self->h2_zero_out_msgid = false;
-
- self->max_clients = max_clients;
- lfatal_oom(_self->client_arr = calloc(max_clients, sizeof(_output_dnssim_client_t)));
-
- for (i = 0; i < max_clients; ++i) {
- _self->client_arr[i].dnssim = self;
- }
-
- ret = gnutls_certificate_allocate_credentials(&_self->tls_cred);
- if (ret < 0)
- lfatal("failed to allocated TLS credentials (%s)", gnutls_strerror(ret));
-
- ret = uv_loop_init(&_self->loop);
- if (ret < 0)
- lfatal("failed to initialize uv_loop (%s)", uv_strerror(ret));
- ldebug("initialized uv_loop");
-
- return self;
-}
-
-void output_dnssim_free(output_dnssim_t* self)
-{
- mlassert_self();
- int ret, i;
- _output_dnssim_source_t* source;
- _output_dnssim_source_t* first = _self->source;
- output_dnssim_stats_t* stats_prev;
-
- free(self->stats_sum->latency);
- free(self->stats_sum);
- do {
- stats_prev = self->stats_current->prev;
- free(self->stats_current->latency);
- free(self->stats_current);
- self->stats_current = stats_prev;
- } while (self->stats_current != NULL);
-
- if (_self->source != NULL) {
- // free cilcular linked list
- do {
- source = _self->source->next;
- free(_self->source);
- _self->source = source;
- } while (_self->source != first);
- }
-
- for (i = 0; i < self->max_clients; ++i) {
- if (_self->client_arr[i].tls_ticket.size != 0) {
- gnutls_free(_self->client_arr[i].tls_ticket.data);
- }
- }
- free(_self->client_arr);
-
- ret = uv_loop_close(&_self->loop);
- if (ret < 0) {
- lcritical("failed to close uv_loop (%s)", uv_strerror(ret));
- } else {
- ldebug("closed uv_loop");
- }
-
- gnutls_certificate_free_credentials(_self->tls_cred);
- if (_self->tls_priority != NULL) {
- gnutls_priority_deinit(*_self->tls_priority);
- free(_self->tls_priority);
- }
-
- free(self);
-}
-
-void output_dnssim_log_name(output_dnssim_t* self, const char* name)
-{
- mlassert_self();
- lassert(name, "name is nil");
-
- strncpy(self->_log.name, name, sizeof(self->_log.name) - 1);
- self->_log.name[sizeof(self->_log.name) - 1] = 0;
- self->_log.is_obj = false;
-}
-
-static uint32_t _extract_client(const core_object_t* obj)
-{
- uint32_t client;
- uint8_t* ip;
-
- switch (obj->obj_type) {
- case CORE_OBJECT_IP:
- ip = ((core_object_ip_t*)obj)->dst;
- break;
- case CORE_OBJECT_IP6:
- ip = ((core_object_ip6_t*)obj)->dst;
- break;
- default:
- return -1;
- }
-
- memcpy(&client, ip, sizeof(client));
- return client;
-}
-
-static void _receive(output_dnssim_t* self, const core_object_t* obj)
-{
- mlassert_self();
- core_object_t* current = (core_object_t*)obj;
- core_object_payload_t* payload;
- uint32_t client;
-
- self->processed++;
-
- /* get payload from packet */
- for (;;) {
- if (current->obj_type == CORE_OBJECT_PAYLOAD) {
- payload = (core_object_payload_t*)current;
- break;
- }
- if (current->obj_prev == NULL) {
- self->discarded++;
- lwarning("packet discarded (missing payload object)");
- return;
- }
- current = (core_object_t*)current->obj_prev;
- }
-
- /* extract client information from IP/IP6 layer */
- for (;;) {
- if (current->obj_type == CORE_OBJECT_IP || current->obj_type == CORE_OBJECT_IP6) {
- client = _extract_client(current);
- break;
- }
- if (current->obj_prev == NULL) {
- self->discarded++;
- lwarning("packet discarded (missing ip/ip6 object)");
- return;
- }
- current = (core_object_t*)current->obj_prev;
- }
-
- if (self->free_after_use) {
- /* free all objects except payload */
- current = (core_object_t*)obj;
- core_object_t* parent = current;
- while (current != NULL) {
- parent = current;
- current = (core_object_t*)current->obj_prev;
- if (parent->obj_type != CORE_OBJECT_PAYLOAD) {
- core_object_free(parent);
- }
- }
- }
-
- if (_self->h2_zero_out_msgid) {
- lassert(_self->transport == OUTPUT_DNSSIM_TRANSPORT_HTTPS2, "must use HTTP/2 to zero-out msgid");
- if (payload->len < 2) {
- self->discarded++;
- lwarning("packet discarded (payload len < 2)");
- return;
- }
- uint8_t* data = (uint8_t*)payload->payload;
- data[0] = 0x00;
- data[1] = 0x00;
- }
-
- if (client >= self->max_clients) {
- self->discarded++;
- lwarning("packet discarded (client exceeded max_clients)");
- return;
- }
-
- ldebug("client(c): %d", client);
- _output_dnssim_create_request(self, &_self->client_arr[client], payload);
-}
-
-core_receiver_t output_dnssim_receiver()
-{
- return (core_receiver_t)_receive;
-}
-
-void output_dnssim_set_transport(output_dnssim_t* self, output_dnssim_transport_t tr)
-{
- mlassert_self();
-
- switch (tr) {
- case OUTPUT_DNSSIM_TRANSPORT_UDP_ONLY:
- lnotice("transport set to UDP (no TCP fallback)");
- break;
- case OUTPUT_DNSSIM_TRANSPORT_TCP:
- lnotice("transport set to TCP");
- break;
- case OUTPUT_DNSSIM_TRANSPORT_TLS:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- lnotice("transport set to TLS");
-#else
- lfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- case OUTPUT_DNSSIM_TRANSPORT_HTTPS2:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- lnotice("transport set to HTTP/2 over TLS");
- if (&_self->h2_uri_authority[0])
- lnotice("set uri authority to: %s", _self->h2_uri_authority);
-#else
- lfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- case OUTPUT_DNSSIM_TRANSPORT_UDP:
- lfatal("UDP transport with TCP fallback is not supported yet.");
- break;
- default:
- lfatal("unknown or unsupported transport");
- break;
- }
-
- _self->transport = tr;
-}
-
-int output_dnssim_target(output_dnssim_t* self, const char* ip, uint16_t port)
-{
- int ret;
- mlassert_self();
- lassert(ip, "ip is nil");
- lassert(port, "port is nil");
-
- ret = uv_ip6_addr(ip, port, (struct sockaddr_in6*)&_self->target);
- if (ret != 0) {
- ret = uv_ip4_addr(ip, port, (struct sockaddr_in*)&_self->target);
- if (ret != 0) {
- lfatal("failed to parse IPv4 or IPv6 from \"%s\"", ip);
- } else {
- ret = snprintf(_self->h2_uri_authority, _MAX_URI_LEN, "%s:%d", ip, port);
- }
- } else {
- ret = snprintf(_self->h2_uri_authority, _MAX_URI_LEN, "[%s]:%d", ip, port);
- }
-
- if (ret > 0) {
- if (_self->transport == OUTPUT_DNSSIM_TRANSPORT_HTTPS2)
- lnotice("set uri authority to: %s", _self->h2_uri_authority);
- } else {
- _self->h2_uri_authority[0] = '\0';
- if (_self->transport == OUTPUT_DNSSIM_TRANSPORT_HTTPS2)
- lfatal("failed to set authority");
- }
-
- lnotice("set target to %s port %d", ip, port);
- return 0;
-}
-
-int output_dnssim_bind(output_dnssim_t* self, const char* ip)
-{
- int ret;
- mlassert_self();
- lassert(ip, "ip is nil");
-
- _output_dnssim_source_t* source;
- lfatal_oom(source = malloc(sizeof(_output_dnssim_source_t)));
-
- ret = uv_ip6_addr(ip, 0, (struct sockaddr_in6*)&source->addr);
- if (ret != 0) {
- ret = uv_ip4_addr(ip, 0, (struct sockaddr_in*)&source->addr);
- if (ret != 0) {
- lfatal("failed to parse IPv4 or IPv6 from \"%s\"", ip);
- }
- }
-
- if (_self->source == NULL) {
- source->next = source;
- _self->source = source;
- } else {
- source->next = _self->source->next;
- _self->source->next = source;
- }
-
- lnotice("bind to source address %s", ip);
- return 0;
-}
-
-int output_dnssim_tls_priority(output_dnssim_t* self, const char* priority)
-{
- mlassert_self();
- lassert(priority, "priority is nil");
-
- if (_self->tls_priority != NULL) {
- gnutls_priority_deinit(*_self->tls_priority);
- free(_self->tls_priority);
- }
- lfatal_oom(_self->tls_priority = malloc(sizeof(gnutls_priority_t)));
-
- int ret = gnutls_priority_init(_self->tls_priority, priority, NULL);
- if (ret < 0) {
- lfatal("failed to initialize TLS priority cache: %s", gnutls_strerror(ret));
- } else {
- lnotice("GnuTLS priority set: %s", priority);
- }
-
- return 0;
-}
-
-int output_dnssim_run_nowait(output_dnssim_t* self)
-{
- mlassert_self();
-
- return uv_run(&_self->loop, UV_RUN_NOWAIT);
-}
-
-void output_dnssim_timeout_ms(output_dnssim_t* self, uint64_t timeout_ms)
-{
- mlassert_self();
- lassert(timeout_ms > 0, "timeout must be greater than 0");
-
- if (self->stats_sum != NULL) {
- free(self->stats_sum->latency);
- free(self->stats_sum);
- self->stats_sum = 0;
- }
- if (self->stats_current != NULL) {
- output_dnssim_stats_t* stats_prev;
- do {
- stats_prev = self->stats_current->prev;
- free(self->stats_current->latency);
- free(self->stats_current);
- self->stats_current = stats_prev;
- } while (self->stats_current != NULL);
- }
-
- self->timeout_ms = timeout_ms;
-
- lfatal_oom(self->stats_sum = calloc(1, sizeof(output_dnssim_stats_t)));
- lfatal_oom(self->stats_sum->latency = calloc(self->timeout_ms + 1, sizeof(uint64_t)));
-
- lfatal_oom(self->stats_current = calloc(1, sizeof(output_dnssim_stats_t)));
- lfatal_oom(self->stats_current->latency = calloc(self->timeout_ms + 1, sizeof(uint64_t)));
-
- self->stats_first = self->stats_current;
-}
-
-void output_dnssim_h2_uri_path(output_dnssim_t* self, const char* uri_path)
-{
- mlassert_self();
- lassert(uri_path, "uri_path is nil");
- lassert(strlen(uri_path) < _MAX_URI_LEN, "uri_path too long");
-
- strncpy(_self->h2_uri_path, uri_path, _MAX_URI_LEN - 1);
- _self->h2_uri_path[_MAX_URI_LEN - 1] = 0;
- lnotice("http2: set uri path to: %s", _self->h2_uri_path);
-}
-
-void output_dnssim_h2_method(output_dnssim_t* self, const char* method)
-{
- mlassert_self();
- lassert(method, "method is nil");
-
- if (strcmp("GET", method) == 0) {
- _self->h2_method = OUTPUT_DNSSIM_H2_GET;
- } else if (strcmp("POST", method) == 0) {
- _self->h2_method = OUTPUT_DNSSIM_H2_POST;
- } else {
- lfatal("http2: unsupported method: \"%s\"", method);
- }
-
- lnotice("http2: set method to %s", method);
-}
-
-void output_dnssim_h2_zero_out_msgid(output_dnssim_t* self, bool zero_out_msgid)
-{
- mlassert_self();
-
- if (zero_out_msgid) {
- lassert(_self->transport == OUTPUT_DNSSIM_TRANSPORT_HTTPS2, "transport must be set to HTTP/2 to set zero_out_msgid");
- _self->h2_zero_out_msgid = zero_out_msgid;
- }
-}
-
-static void _on_stats_timer_tick(uv_timer_t* handle)
-{
- uint64_t now_ms = _now_ms();
- output_dnssim_t* self;
- mlassert(handle, "handle is nil");
- self = (output_dnssim_t*)handle->data;
- mlassert_self();
- lassert(self->stats_sum, "stats_sum is nil");
- lassert(self->stats_current, "stats_current is nil");
-
- lnotice("total processed:%10ld; answers:%10ld; discarded:%10ld; ongoing:%10ld",
- self->processed, self->stats_sum->answers, self->discarded, self->ongoing);
-
- output_dnssim_stats_t* stats_next;
- lfatal_oom(stats_next = calloc(1, sizeof(output_dnssim_stats_t)));
- lfatal_oom(stats_next->latency = calloc(self->timeout_ms + 1, sizeof(uint64_t)));
-
- self->stats_current->until_ms = now_ms;
- stats_next->since_ms = now_ms;
- stats_next->conn_active = self->stats_current->conn_active;
-
- stats_next->ongoing = self->ongoing;
- stats_next->prev = self->stats_current;
- self->stats_current->next = stats_next;
- self->stats_current = stats_next;
-}
-
-void output_dnssim_stats_collect(output_dnssim_t* self, uint64_t interval_ms)
-{
- uint64_t now_ms = _now_ms();
- mlassert_self();
- lassert(self->stats_sum, "stats_sum is nil");
- lassert(self->stats_current, "stats_current is nil");
-
- if (self->stats_interval_ms != 0) {
- lfatal("statistics collection has already started!");
- }
- self->stats_interval_ms = interval_ms;
-
- self->stats_sum->since_ms = now_ms;
- self->stats_current->since_ms = now_ms;
-
- _self->stats_timer.data = (void*)self;
- uv_timer_init(&_self->loop, &_self->stats_timer);
- uv_timer_start(&_self->stats_timer, _on_stats_timer_tick, interval_ms, interval_ms);
-}
-
-void output_dnssim_stats_finish(output_dnssim_t* self)
-{
- uint64_t now_ms = _now_ms();
- mlassert_self();
- lassert(self->stats_sum, "stats_sum is nil");
- lassert(self->stats_current, "stats_current is nil");
-
- self->stats_sum->until_ms = now_ms;
- self->stats_current->until_ms = now_ms;
-
- uv_timer_stop(&_self->stats_timer);
- uv_close((uv_handle_t*)&_self->stats_timer, NULL);
-}
diff --git a/src/output/dnssim.hh b/src/output/dnssim.hh
deleted file mode 100644
index a17125d..0000000
--- a/src/output/dnssim.hh
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2018-2020, CZ.NIC, z.s.p.o.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-//lua:require("dnsjit.core.log")
-//lua:require("dnsjit.core.receiver_h")
-
-typedef enum output_dnssim_transport {
- OUTPUT_DNSSIM_TRANSPORT_UDP_ONLY,
- OUTPUT_DNSSIM_TRANSPORT_UDP,
- OUTPUT_DNSSIM_TRANSPORT_TCP,
- OUTPUT_DNSSIM_TRANSPORT_TLS,
- OUTPUT_DNSSIM_TRANSPORT_HTTPS2
-} output_dnssim_transport_t;
-
-typedef enum output_dnssim_h2_method {
- OUTPUT_DNSSIM_H2_GET,
- OUTPUT_DNSSIM_H2_POST
-} output_dnssim_h2_method_t;
-
-typedef struct output_dnssim_stats output_dnssim_stats_t;
-struct output_dnssim_stats {
- output_dnssim_stats_t* prev;
- output_dnssim_stats_t* next;
-
- uint64_t* latency;
-
- uint64_t since_ms;
- uint64_t until_ms;
-
- uint64_t requests;
- uint64_t ongoing;
- uint64_t answers;
-
- /* Number of connections that are open at the end of the stats interval. */
- uint64_t conn_active;
-
- /* Number of connection handshake attempts during the stats interval. */
- uint64_t conn_handshakes;
-
- /* Number of connection that have been resumed with TLS session resumption. */
- uint64_t conn_resumed;
-
- /* Number of timed out connection handshakes during the stats interval. */
- uint64_t conn_handshakes_failed;
-
- uint64_t rcode_noerror;
- uint64_t rcode_formerr;
- uint64_t rcode_servfail;
- uint64_t rcode_nxdomain;
- uint64_t rcode_notimp;
- uint64_t rcode_refused;
- uint64_t rcode_yxdomain;
- uint64_t rcode_yxrrset;
- uint64_t rcode_nxrrset;
- uint64_t rcode_notauth;
- uint64_t rcode_notzone;
- uint64_t rcode_badvers;
- uint64_t rcode_badkey;
- uint64_t rcode_badtime;
- uint64_t rcode_badmode;
- uint64_t rcode_badname;
- uint64_t rcode_badalg;
- uint64_t rcode_badtrunc;
- uint64_t rcode_badcookie;
- uint64_t rcode_other;
-};
-
-typedef struct output_dnssim {
- core_log_t _log;
-
- uint64_t processed;
- uint64_t discarded;
- uint64_t ongoing;
-
- output_dnssim_stats_t* stats_sum;
- output_dnssim_stats_t* stats_current;
- output_dnssim_stats_t* stats_first;
-
- size_t max_clients;
- bool free_after_use;
-
- uint64_t timeout_ms;
- uint64_t idle_timeout_ms;
- uint64_t handshake_timeout_ms;
- uint64_t stats_interval_ms;
-} output_dnssim_t;
-
-core_log_t* output_dnssim_log();
-
-output_dnssim_t* output_dnssim_new(size_t max_clients);
-void output_dnssim_free(output_dnssim_t* self);
-
-void output_dnssim_log_name(output_dnssim_t* self, const char* name);
-void output_dnssim_set_transport(output_dnssim_t* self, output_dnssim_transport_t tr);
-int output_dnssim_target(output_dnssim_t* self, const char* ip, uint16_t port);
-int output_dnssim_bind(output_dnssim_t* self, const char* ip);
-int output_dnssim_tls_priority(output_dnssim_t* self, const char* priority);
-int output_dnssim_run_nowait(output_dnssim_t* self);
-void output_dnssim_timeout_ms(output_dnssim_t* self, uint64_t timeout_ms);
-void output_dnssim_h2_uri_path(output_dnssim_t* self, const char* uri_path);
-void output_dnssim_h2_method(output_dnssim_t* self, const char* method);
-void output_dnssim_h2_zero_out_msgid(output_dnssim_t* self, bool zero_out_msgid);
-void output_dnssim_stats_collect(output_dnssim_t* self, uint64_t interval_ms);
-void output_dnssim_stats_finish(output_dnssim_t* self);
-
-core_receiver_t output_dnssim_receiver();
diff --git a/src/output/dnssim.lua b/src/output/dnssim.lua
deleted file mode 100644
index 25193c4..0000000
--- a/src/output/dnssim.lua
+++ /dev/null
@@ -1,433 +0,0 @@
--- Copyright (c) 2018-2021, CZ.NIC, z.s.p.o.
--- All rights reserved.
---
--- This file is part of dnsjit.
---
--- dnsjit 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.
---
--- dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
-
--- dnsjit.output.dnssim
--- Simulate independent DNS clients over various transports
--- output = require("dnsjit.output.dnssim").new()
--- .SS Usage
--- output:udp()
--- output:target("::1", 53)
--- recv, rctx = output:receive()
--- -- pass in objects using recv(rctx, obj)
--- -- repeatedly call output:run_nowait() until it returns 0
--- .SS DNS-over-TLS example configuration
--- output:tls("NORMAL:-VERS-ALL:+VERS-TLS1.3") -- enforce TLS 1.3
--- .SS DNS-over-HTTPS/2 example configuration
--- output:https2({ method = "POST", uri_path = "/doh" })
---
--- Output module for simulating traffic from huge number of independent,
--- individual DNS clients.
--- Uses libuv for asynchronous communication.
--- There may only be a single DnsSim in a thread.
--- Use
--- .I dnsjit.core.thread
--- to have multiple DnsSim instances.
--- .P
--- With proper use of this component, it is possible to simulate hundreds of
--- thousands of clients when using a high-performance server.
--- This also applies for state-full transports.
--- The complete set-up is quite complex and requires other components.
--- See DNS Shotgun
--- .RI ( https://gitlab.nic.cz/knot/shotgun )
--- for dnsjit scripts ready for use for high-performance
--- benchmarking.
-module(...,package.seeall)
-
-require("dnsjit.output.dnssim_h")
-local bit = require("bit")
-local object = require("dnsjit.core.objects")
-local ffi = require("ffi")
-local C = ffi.C
-
-local DnsSim = {}
-
-local _DNSSIM_VERSION = 20210129
-local _DNSSIM_JSON_VERSION = 20200527
-
--- Create a new DnsSim output for up to max_clients.
-function DnsSim.new(max_clients)
- local self = {
- obj = C.output_dnssim_new(max_clients),
- max_clients = max_clients,
- }
- ffi.gc(self.obj, C.output_dnssim_free)
- return setmetatable(self, { __index = DnsSim })
-end
-
-local function _check_version(version, req_version)
- if req_version == nil then
- return version
- end
- local min_version = tonumber(req_version)
- if min_version == nil then
- C.output_dnssim_log():fatal("invalid version number: "..req_version)
- return nil
- end
- if version >= min_version then
- return version
- end
- return nil
-end
-
--- Check that version of dnssim is at minimum the one passed as
--- .B req_version
--- and return the actual version number.
--- Return nil if the condition is not met.
---
--- If no
--- .B req_version
--- is specified no check is done and only the version number is returned.
-function DnsSim.check_version(req_version)
- return _check_version(_DNSSIM_VERSION, req_version)
-end
-
--- Check that version of dnssim's JSON data format is at minimum the one passed as
--- .B req_version
--- and return the actual version number.
--- Return nil if the condition is not met.
---
--- If no
--- .B req_version
--- is specified no check is done and only the version number is returned.
-function DnsSim.check_json_version(req_version)
- return _check_version(_DNSSIM_JSON_VERSION, req_version)
-end
-
--- Return the Log object to control logging of this instance or module.
--- Optionally, set the instance's log name.
--- Unique name should be used for each instance.
-function DnsSim:log(name)
- if self == nil then
- return C.output_dnssim_log()
- end
- if name ~= nil then
- C.output_dnssim_log_name(self.obj, name)
- end
- return self.obj._log
-end
-
--- Set the target IPv4/IPv6 address where queries will be sent to.
-function DnsSim:target(ip, port)
- local nport = tonumber(port)
- if nport == nil then
- self.obj._log:fatal("invalid port: "..port)
- return -1
- end
- if nport <= 0 or nport > 65535 then
- self.obj._log:fatal("invalid port number: "..nport)
- return -1
- end
- return C.output_dnssim_target(self.obj, ip, nport)
-end
-
--- Specify source IPv4/IPv6 address for sending queries.
--- Can be set multiple times.
--- Addresses are selected round-robin when sending.
-function DnsSim:bind(ip)
- return C.output_dnssim_bind(self.obj, ip)
-end
-
--- Set the preferred transport to UDP.
---
--- When the optional argument
--- .B tcp_fallback
--- is set to true, individual queries are re-tried over TCP when TC bit is set in the answer.
--- Defaults to
--- .B false
--- (aka only UDP is used).
-function DnsSim:udp(tcp_fallback)
- if tcp_fallback == true then
- C.output_dnssim_set_transport(self.obj, C.OUTPUT_DNSSIM_TRANSPORT_UDP)
- else
- C.output_dnssim_set_transport(self.obj, C.OUTPUT_DNSSIM_TRANSPORT_UDP_ONLY)
- end
-end
-
--- Set the transport to TCP.
-function DnsSim:tcp()
- C.output_dnssim_set_transport(self.obj, C.OUTPUT_DNSSIM_TRANSPORT_TCP)
-end
-
--- Set the transport to TLS.
---
--- The optional argument
--- .B tls_priority
--- is a GnuTLS priority string, which can be used to select TLS versions, cipher suites etc.
--- For example:
---
--- .RB "- """ NORMAL:%NO_TICKETS """"
--- will use defaults without TLS session resumption.
---
--- .RB "- """ SECURE128:-VERS-ALL:+VERS-TLS1.3 """"
--- will use only TLS 1.3 with 128-bit secure ciphers.
---
--- Refer to:
--- .I https://gnutls.org/manual/html_node/Priority-Strings.html
-function DnsSim:tls(tls_priority)
- if tls_priority ~= nil then
- C.output_dnssim_tls_priority(self.obj, tls_priority)
- end
- C.output_dnssim_set_transport(self.obj, C.OUTPUT_DNSSIM_TRANSPORT_TLS)
-end
-
--- Set the transport to HTTP/2 over TLS.
---
--- .B http2_options
--- is a lua table which supports the following keys:
---
--- .B method:
--- .B GET
--- (default)
--- or
--- .B POST
---
--- .B uri_path:
--- where queries will be sent.
--- Defaults to
--- .B /dns-query
---
--- .B zero_out_msgid:
--- when
--- .B true
--- (default), query ID is always set to 0
---
--- See tls() method for
--- .B tls_priority
--- documentation.
-function DnsSim:https2(http2_options, tls_priority)
- if tls_priority ~= nil then
- C.output_dnssim_tls_priority(self.obj, tls_priority)
- end
-
- uri_path = "/dns-query"
- zero_out_msgid = true
- method = "GET"
-
- if http2_options ~= nil then
- if type(http2_options) ~= "table" then
- self.obj._log:fatal("http2_options must be a table")
- else
- if http2_options["uri_path"] ~= nil then
- uri_path = http2_options["uri_path"]
- end
- if http2_options["zero_out_msgid"] ~= nil and http2_options["zero_out_msgid"] ~= true then
- zero_out_msgid = false
- end
- if http2_options["method"] ~= nil then
- method = http2_options["method"]
- end
- end
- end
-
- C.output_dnssim_set_transport(self.obj, C.OUTPUT_DNSSIM_TRANSPORT_HTTPS2)
- C.output_dnssim_h2_uri_path(self.obj, uri_path)
- C.output_dnssim_h2_method(self.obj, method)
- C.output_dnssim_h2_zero_out_msgid(self.obj, zero_out_msgid)
-end
-
--- Set timeout for the individual requests in seconds (default 2s).
---
--- .BR Beware :
--- increasing this value while the target resolver isn't very responsive
--- (cold cache, heavy load) may degrade DnsSim's performance and skew
--- the results.
-function DnsSim:timeout(seconds)
- if seconds == nil then
- seconds = 2
- end
- timeout_ms = math.floor(seconds * 1000)
- C.output_dnssim_timeout_ms(self.obj, timeout_ms)
-end
-
--- Set TCP connection idle timeout for connection reuse according to RFC7766,
--- Section 6.2.3 (defaults to 10s).
--- When set to zero, connections are closed immediately after there are no
--- more pending queries.
-function DnsSim:idle_timeout(seconds)
- if seconds == nil then
- seconds = 10
- end
- self.obj.idle_timeout_ms = math.floor(seconds * 1000)
-end
-
--- Set TCP connection handshake timeout (defaults to 5s).
--- During heavy load, the server may no longer accept new connections.
--- This parameter ensures such connection attempts are aborted after the
--- timeout expires.
-function DnsSim:handshake_timeout(seconds)
- if seconds == nil then
- seconds = 5
- end
- self.obj.handshake_timeout_ms = math.floor(seconds * 1000)
-end
-
--- Run the libuv loop once without blocking when there is no I/O.
--- This should be called repeatedly until 0 is returned and no more data
--- is expected to be received by DnsSim.
-function DnsSim:run_nowait()
- return C.output_dnssim_run_nowait(self.obj)
-end
-
--- Set this to true if DnsSim should free the memory of passed-in objects
--- (useful when using
--- .I dnsjit.filter.copy
--- to pass objects from different thread).
-function DnsSim:free_after_use(free_after_use)
- self.obj.free_after_use = free_after_use
-end
-
--- Number of input packets discarded due to various reasons.
--- To investigate causes, run with increased logging level.
-function DnsSim:discarded()
- return tonumber(self.obj.discarded)
-end
-
--- Number of valid requests (input packets) processed.
-function DnsSim:requests()
- return tonumber(self.obj.stats_sum.requests)
-end
-
--- Number of requests that received an answer
-function DnsSim:answers()
- return tonumber(self.obj.stats_sum.answers)
-end
-
--- Number of requests that received a NOERROR response
-function DnsSim:noerror()
- return tonumber(self.obj.stats_sum.rcode_noerror)
-end
-
--- Configure statistics to be collected every N seconds.
-function DnsSim:stats_collect(seconds)
- if seconds == nil then
- self.obj._log:fatal("number of seconds must be set for stats_collect()")
- end
- interval_ms = math.floor(seconds * 1000)
- C.output_dnssim_stats_collect(self.obj, interval_ms)
-end
-
--- Stop the collection of statistics.
-function DnsSim:stats_finish()
- C.output_dnssim_stats_finish(self.obj)
-end
-
--- Export the results to a JSON file.
-function DnsSim:export(filename)
- local file = io.open(filename, "w")
- if file == nil then
- self.obj._log:fatal("export failed: no filename")
- return
- end
-
- local function write_stats(file, stats)
- file:write(
- "{ ",
- '"since_ms":', tonumber(stats.since_ms), ',',
- '"until_ms":', tonumber(stats.until_ms), ',',
- '"requests":', tonumber(stats.requests), ',',
- '"ongoing":', tonumber(stats.ongoing), ',',
- '"answers":', tonumber(stats.answers), ',',
- '"conn_active":', tonumber(stats.conn_active), ',',
- '"conn_handshakes":', tonumber(stats.conn_handshakes), ',',
- '"conn_resumed":', tonumber(stats.conn_resumed), ',',
- '"conn_handshakes_failed":', tonumber(stats.conn_handshakes_failed), ',',
- '"rcode_noerror":', tonumber(stats.rcode_noerror), ',',
- '"rcode_formerr":', tonumber(stats.rcode_formerr), ',',
- '"rcode_servfail":', tonumber(stats.rcode_servfail), ',',
- '"rcode_nxdomain":', tonumber(stats.rcode_nxdomain), ',',
- '"rcode_notimp":', tonumber(stats.rcode_notimp), ',',
- '"rcode_refused":', tonumber(stats.rcode_refused), ',',
- '"rcode_yxdomain":', tonumber(stats.rcode_yxdomain), ',',
- '"rcode_yxrrset":', tonumber(stats.rcode_yxrrset), ',',
- '"rcode_nxrrset":', tonumber(stats.rcode_nxrrset), ',',
- '"rcode_notauth":', tonumber(stats.rcode_notauth), ',',
- '"rcode_notzone":', tonumber(stats.rcode_notzone), ',',
- '"rcode_badvers":', tonumber(stats.rcode_badvers), ',',
- '"rcode_badkey":', tonumber(stats.rcode_badkey), ',',
- '"rcode_badtime":', tonumber(stats.rcode_badtime), ',',
- '"rcode_badmode":', tonumber(stats.rcode_badmode), ',',
- '"rcode_badname":', tonumber(stats.rcode_badname), ',',
- '"rcode_badalg":', tonumber(stats.rcode_badalg), ',',
- '"rcode_badtrunc":', tonumber(stats.rcode_badtrunc), ',',
- '"rcode_badcookie":', tonumber(stats.rcode_badcookie), ',',
- '"rcode_other":', tonumber(stats.rcode_other), ',',
- '"latency":[')
- file:write(tonumber(stats.latency[0]))
- for i=1,tonumber(self.obj.timeout_ms) do
- file:write(',', tonumber(stats.latency[i]))
- end
- file:write("]}")
- end
-
- file:write(
- "{ ",
- '"version":', _DNSSIM_JSON_VERSION, ',',
- '"merged":false,',
- '"stats_interval_ms":', tonumber(self.obj.stats_interval_ms), ',',
- '"timeout_ms":', tonumber(self.obj.timeout_ms), ',',
- '"idle_timeout_ms":', tonumber(self.obj.idle_timeout_ms), ',',
- '"handshake_timeout_ms":', tonumber(self.obj.handshake_timeout_ms), ',',
- '"discarded":', self:discarded(), ',',
- '"stats_sum":')
- write_stats(file, self.obj.stats_sum)
- file:write(
- ',',
- '"stats_periodic":[')
-
- local stats = self.obj.stats_first
- write_stats(file, stats)
-
- while (stats.next ~= nil) do
- stats = stats.next
- file:write(',')
- write_stats(file, stats)
- end
-
- file:write(']}')
- file:close()
- self.obj._log:notice("results exported to "..filename)
-end
-
--- Return the C function and context for receiving objects.
--- Only
--- .I dnsjit.filter.core.object.ip
--- or
--- .I dnsjit.filter.core.object.ip6
--- objects are supported.
--- The component expects a 32bit integer (in host order) ranging from 0
--- to max_clients written to first 4 bytes of destination IP.
--- See
--- .IR dnsjit.filter.ipsplit .
-function DnsSim:receive()
- local receive = C.output_dnssim_receiver()
- return receive, self.obj
-end
-
--- Deprecated: use udp() instead.
---
--- Set the transport to UDP (without any TCP fallback).
-function DnsSim:udp_only()
- C.output_dnssim_set_transport(self.obj, C.OUTPUT_DNSSIM_TRANSPORT_UDP_ONLY)
-end
-
--- dnsjit.filter.copy (3),
--- dnsjit.filter.ipsplit (3),
--- dnsjit.filter.core.object.ip (3),
--- dnsjit.filter.core.object.ip6 (3),
--- https://gitlab.nic.cz/knot/shotgun
-return DnsSim
diff --git a/src/output/dnssim/CHANGELOG.md b/src/output/dnssim/CHANGELOG.md
deleted file mode 100644
index 9cbfa55..0000000
--- a/src/output/dnssim/CHANGELOG.md
+++ /dev/null
@@ -1,16 +0,0 @@
-dnssim v20210129
-================
-
-- Added DNS-over-HTTPS support with https2()
-- Added IPv4 support
-- Abort operation on insufficient file descriptors
-- Match QUESTION section of received responses
-- Improvements in connection state handling
-- Deprecate udp_only() in favor of udp()
-- Allow setting logger name with log(name)
-- Added check_version() and check_json_version()
-
-dnssim v20200723
-================
-
-- First released dnssim version with UDP, TCP and DoT support
diff --git a/src/output/dnssim/common.c b/src/output/dnssim/common.c
deleted file mode 100644
index e170aec..0000000
--- a/src/output/dnssim/common.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (c) 2019-2020, CZ.NIC, z.s.p.o.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "output/dnssim.h"
-#include "output/dnssim/internal.h"
-#include "output/dnssim/ll.h"
-#include "core/assert.h"
-
-#include <string.h>
-
-#define MAX_LABELS 127
-
-static core_log_t _log = LOG_T_INIT("output.dnssim");
-
-static void _close_request(_output_dnssim_request_t* req);
-
-static void _on_request_timeout(uv_timer_t* handle)
-{
- _close_request((_output_dnssim_request_t*)handle->data);
-}
-
-static ssize_t parse_qsection(core_object_dns_t* dns)
-{
- core_object_dns_q_t q;
- static core_object_dns_label_t labels[MAX_LABELS];
- const uint8_t* start;
- int i;
- int ret;
-
- if (!dns || !dns->have_qdcount)
- return -1;
-
- start = dns->at;
-
- for (i = 0; i < dns->qdcount; i++) {
- ret = core_object_dns_parse_q(dns, &q, labels, MAX_LABELS);
- if (ret < 0)
- return -1;
- }
-
- return (dns->at - start);
-}
-
-int _output_dnssim_answers_request(_output_dnssim_request_t* req, core_object_dns_t* response)
-{
- const uint8_t* question;
- ssize_t len;
-
- if (!response->have_id || !response->have_qdcount)
- return _ERR_MALFORMED;
-
- if (req->dns_q->id != response->id)
- return _ERR_MSGID;
-
- if (req->dns_q->qdcount != response->qdcount)
- return _ERR_QUESTION;
-
- question = response->at;
- len = parse_qsection(response);
-
- if (req->question_len != len)
- return _ERR_QUESTION;
-
- if (memcmp(req->question, question, len) != 0)
- return _ERR_QUESTION;
-
- return 0;
-}
-
-void _output_dnssim_create_request(output_dnssim_t* self, _output_dnssim_client_t* client, core_object_payload_t* payload)
-{
- int ret;
- _output_dnssim_request_t* req;
- mlassert_self();
- lassert(client, "client is nil");
- lassert(payload, "payload is nil");
-
- lfatal_oom(req = calloc(1, sizeof(_output_dnssim_request_t)));
- req->dnssim = self;
- req->client = client;
- req->payload = payload;
- req->dns_q = core_object_dns_new();
- req->dns_q->obj_prev = (core_object_t*)req->payload;
- req->dnssim->ongoing++;
- req->state = _OUTPUT_DNSSIM_REQ_ONGOING;
- req->stats = self->stats_current;
-
- ret = core_object_dns_parse_header(req->dns_q);
- if (ret != 0) {
- ldebug("discarded malformed dns query: couldn't parse header");
- goto failure;
- }
-
- req->question = req->dns_q->at;
- req->question_len = parse_qsection(req->dns_q);
- if (req->question_len < 0) {
- ldebug("discarded malformed dns query: invalid question");
- goto failure;
- }
-
- req->dnssim->stats_sum->requests++;
- req->stats->requests++;
-
- switch (_self->transport) {
- case OUTPUT_DNSSIM_TRANSPORT_UDP_ONLY:
- case OUTPUT_DNSSIM_TRANSPORT_UDP:
- ret = _output_dnssim_create_query_udp(self, req);
- break;
- case OUTPUT_DNSSIM_TRANSPORT_TCP:
- ret = _output_dnssim_create_query_tcp(self, req);
- break;
- case OUTPUT_DNSSIM_TRANSPORT_TLS:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- ret = _output_dnssim_create_query_tls(self, req);
-#else
- lfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- case OUTPUT_DNSSIM_TRANSPORT_HTTPS2:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- ret = _output_dnssim_create_query_https2(self, req);
-#else
- lfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- default:
- lfatal("unsupported dnssim transport");
- break;
- }
- if (ret < 0) {
- goto failure;
- }
-
- req->created_at = uv_now(&_self->loop);
- req->ended_at = req->created_at + self->timeout_ms;
- lfatal_oom(req->timer = malloc(sizeof(uv_timer_t)));
- uv_timer_init(&_self->loop, req->timer);
- req->timer->data = req;
- uv_timer_start(req->timer, _on_request_timeout, self->timeout_ms, 0);
-
- return;
-failure:
- self->discarded++;
- _close_request(req);
- return;
-}
-
-/* Bind before connect to be able to send from different source IPs. */
-int _output_dnssim_bind_before_connect(output_dnssim_t* self, uv_handle_t* handle)
-{
- mlassert_self();
- lassert(handle, "handle is nil");
-
- if (_self->source != NULL) {
- struct sockaddr* addr = (struct sockaddr*)&_self->source->addr;
- struct sockaddr* dest = (struct sockaddr*)&_self->target;
- int ret = -1;
- if (addr->sa_family != dest->sa_family) {
- lfatal("failed to bind: source/desitnation address family mismatch");
- }
- switch (handle->type) {
- case UV_UDP:
- ret = uv_udp_bind((uv_udp_t*)handle, addr, 0);
- break;
- case UV_TCP:
- ret = uv_tcp_bind((uv_tcp_t*)handle, addr, 0);
- break;
- default:
- lfatal("failed to bind: unsupported handle type");
- break;
- }
- if (ret < 0) {
- /* This typically happens when we run out of file descriptors.
- * Quit to prevent skewed results or unexpected behaviour. */
- lfatal("failed to bind: %s", uv_strerror(ret));
- return ret;
- }
- _self->source = _self->source->next;
- }
- return 0;
-}
-
-void _output_dnssim_maybe_free_request(_output_dnssim_request_t* req)
-{
- mlassert(req, "req is nil");
-
- if (req->qry == NULL && req->timer == NULL) {
- if (req->dnssim->free_after_use) {
- core_object_payload_free(req->payload);
- }
- core_object_dns_free(req->dns_q);
- free(req);
- }
-}
-
-static void _close_query(_output_dnssim_query_t* qry)
-{
- mlassert(qry, "qry is nil");
-
- switch (qry->transport) {
- case OUTPUT_DNSSIM_TRANSPORT_UDP:
- _output_dnssim_close_query_udp((_output_dnssim_query_udp_t*)qry);
- break;
- case OUTPUT_DNSSIM_TRANSPORT_TCP:
- _output_dnssim_close_query_tcp((_output_dnssim_query_tcp_t*)qry);
- break;
- case OUTPUT_DNSSIM_TRANSPORT_TLS:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- _output_dnssim_close_query_tls((_output_dnssim_query_tcp_t*)qry);
-#else
- mlfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- case OUTPUT_DNSSIM_TRANSPORT_HTTPS2:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- _output_dnssim_close_query_https2((_output_dnssim_query_tcp_t*)qry);
-#else
- mlfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- default:
- mlfatal("invalid query transport");
- break;
- }
-}
-
-static void _on_request_timer_closed(uv_handle_t* handle)
-{
- _output_dnssim_request_t* req = (_output_dnssim_request_t*)handle->data;
- mlassert(req, "req is nil");
- free(handle);
- req->timer = NULL;
- _output_dnssim_maybe_free_request(req);
-}
-
-static void _close_request(_output_dnssim_request_t* req)
-{
- if (req == NULL || req->state == _OUTPUT_DNSSIM_REQ_CLOSING)
- return;
- mlassert(req->state == _OUTPUT_DNSSIM_REQ_ONGOING, "request to be closed must be ongoing");
- req->state = _OUTPUT_DNSSIM_REQ_CLOSING;
- req->dnssim->ongoing--;
-
- /* Calculate latency. */
- uint64_t latency;
- req->ended_at = uv_now(&((_output_dnssim_t*)req->dnssim)->loop);
- latency = req->ended_at - req->created_at;
- if (latency > req->dnssim->timeout_ms) {
- req->ended_at = req->created_at + req->dnssim->timeout_ms;
- latency = req->dnssim->timeout_ms;
- }
- req->stats->latency[latency]++;
- req->dnssim->stats_sum->latency[latency]++;
-
- if (req->timer != NULL) {
- uv_timer_stop(req->timer);
- uv_close((uv_handle_t*)req->timer, _on_request_timer_closed);
- }
-
- /* Finish any queries in flight. */
- _output_dnssim_query_t* qry = req->qry;
- if (qry != NULL)
- _close_query(qry);
-
- _output_dnssim_maybe_free_request(req);
-}
-
-void _output_dnssim_request_answered(_output_dnssim_request_t* req, core_object_dns_t* msg)
-{
- mlassert(req, "req is nil");
- mlassert(msg, "msg is nil");
-
- req->dnssim->stats_sum->answers++;
- req->stats->answers++;
-
- switch (msg->rcode) {
- case CORE_OBJECT_DNS_RCODE_NOERROR:
- req->dnssim->stats_sum->rcode_noerror++;
- req->stats->rcode_noerror++;
- break;
- case CORE_OBJECT_DNS_RCODE_FORMERR:
- req->dnssim->stats_sum->rcode_formerr++;
- req->stats->rcode_formerr++;
- break;
- case CORE_OBJECT_DNS_RCODE_SERVFAIL:
- req->dnssim->stats_sum->rcode_servfail++;
- req->stats->rcode_servfail++;
- break;
- case CORE_OBJECT_DNS_RCODE_NXDOMAIN:
- req->dnssim->stats_sum->rcode_nxdomain++;
- req->stats->rcode_nxdomain++;
- break;
- case CORE_OBJECT_DNS_RCODE_NOTIMP:
- req->dnssim->stats_sum->rcode_notimp++;
- req->stats->rcode_notimp++;
- break;
- case CORE_OBJECT_DNS_RCODE_REFUSED:
- req->dnssim->stats_sum->rcode_refused++;
- req->stats->rcode_refused++;
- break;
- case CORE_OBJECT_DNS_RCODE_YXDOMAIN:
- req->dnssim->stats_sum->rcode_yxdomain++;
- req->stats->rcode_yxdomain++;
- break;
- case CORE_OBJECT_DNS_RCODE_YXRRSET:
- req->dnssim->stats_sum->rcode_yxrrset++;
- req->stats->rcode_yxrrset++;
- break;
- case CORE_OBJECT_DNS_RCODE_NXRRSET:
- req->dnssim->stats_sum->rcode_nxrrset++;
- req->stats->rcode_nxrrset++;
- break;
- case CORE_OBJECT_DNS_RCODE_NOTAUTH:
- req->dnssim->stats_sum->rcode_notauth++;
- req->stats->rcode_notauth++;
- break;
- case CORE_OBJECT_DNS_RCODE_NOTZONE:
- req->dnssim->stats_sum->rcode_notzone++;
- req->stats->rcode_notzone++;
- break;
- case CORE_OBJECT_DNS_RCODE_BADVERS:
- req->dnssim->stats_sum->rcode_badvers++;
- req->stats->rcode_badvers++;
- break;
- case CORE_OBJECT_DNS_RCODE_BADKEY:
- req->dnssim->stats_sum->rcode_badkey++;
- req->stats->rcode_badkey++;
- break;
- case CORE_OBJECT_DNS_RCODE_BADTIME:
- req->dnssim->stats_sum->rcode_badtime++;
- req->stats->rcode_badtime++;
- break;
- case CORE_OBJECT_DNS_RCODE_BADMODE:
- req->dnssim->stats_sum->rcode_badmode++;
- req->stats->rcode_badmode++;
- break;
- case CORE_OBJECT_DNS_RCODE_BADNAME:
- req->dnssim->stats_sum->rcode_badname++;
- req->stats->rcode_badname++;
- break;
- case CORE_OBJECT_DNS_RCODE_BADALG:
- req->dnssim->stats_sum->rcode_badalg++;
- req->stats->rcode_badalg++;
- break;
- case CORE_OBJECT_DNS_RCODE_BADTRUNC:
- req->dnssim->stats_sum->rcode_badtrunc++;
- req->stats->rcode_badtrunc++;
- break;
- case CORE_OBJECT_DNS_RCODE_BADCOOKIE:
- req->dnssim->stats_sum->rcode_badcookie++;
- req->stats->rcode_badcookie++;
- break;
- default:
- req->dnssim->stats_sum->rcode_other++;
- req->stats->rcode_other++;
- }
-
- _close_request(req);
-}
-
-void _output_dnssim_on_uv_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
-{
- mlfatal_oom(buf->base = malloc(suggested_size));
- buf->len = suggested_size;
-}
diff --git a/src/output/dnssim/connection.c b/src/output/dnssim/connection.c
deleted file mode 100644
index eeb1ce8..0000000
--- a/src/output/dnssim/connection.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * Copyright (c) 2020, CZ.NIC, z.s.p.o.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "output/dnssim.h"
-#include "output/dnssim/internal.h"
-#include "output/dnssim/ll.h"
-#include "core/assert.h"
-
-#include <string.h>
-
-static core_log_t _log = LOG_T_INIT("output.dnssim");
-
-static bool _conn_is_connecting(_output_dnssim_connection_t* conn)
-{
- return (conn->state >= _OUTPUT_DNSSIM_CONN_TCP_HANDSHAKE && conn->state <= _OUTPUT_DNSSIM_CONN_ACTIVE);
-}
-
-void _output_dnssim_conn_maybe_free(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn can't be nil");
- mlassert(conn->client, "conn must belong to a client");
- if (conn->handle == NULL && conn->handshake_timer == NULL && conn->idle_timer == NULL) {
- _ll_try_remove(conn->client->conn, conn);
- if (conn->tls != NULL) {
- free(conn->tls);
- conn->tls = NULL;
- }
- if (conn->http2 != NULL) {
- free(conn->http2);
- conn->http2 = NULL;
- }
- free(conn);
- }
-}
-
-static void _on_handshake_timer_closed(uv_handle_t* handle)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)handle->data;
- mlassert(conn, "conn is nil");
- mlassert(conn->handshake_timer, "conn must have handshake timer when closing it");
- free(conn->handshake_timer);
- conn->handshake_timer = NULL;
- _output_dnssim_conn_maybe_free(conn);
-}
-
-static void _on_idle_timer_closed(uv_handle_t* handle)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)handle->data;
- mlassert(conn, "conn is nil");
- mlassert(conn->idle_timer, "conn must have idle timer when closing it");
- free(conn->idle_timer);
- conn->is_idle = false;
- conn->idle_timer = NULL;
- _output_dnssim_conn_maybe_free(conn);
-}
-
-void _output_dnssim_conn_close(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn can't be nil");
- mlassert(conn->stats, "conn must have stats");
- mlassert(conn->client, "conn must have client");
- mlassert(conn->client->dnssim, "client must have dnssim");
-
- output_dnssim_t* self = conn->client->dnssim;
-
- switch (conn->state) {
- case _OUTPUT_DNSSIM_CONN_CLOSING:
- case _OUTPUT_DNSSIM_CONN_CLOSED:
- return;
- case _OUTPUT_DNSSIM_CONN_TCP_HANDSHAKE:
- case _OUTPUT_DNSSIM_CONN_TLS_HANDSHAKE:
- conn->stats->conn_handshakes_failed++;
- self->stats_sum->conn_handshakes_failed++;
- break;
- case _OUTPUT_DNSSIM_CONN_ACTIVE:
- case _OUTPUT_DNSSIM_CONN_CONGESTED:
- self->stats_current->conn_active--;
- break;
- case _OUTPUT_DNSSIM_CONN_INITIALIZED:
- case _OUTPUT_DNSSIM_CONN_CLOSE_REQUESTED:
- break;
- default:
- lfatal("unknown conn state: %d", conn->state);
- }
- if (conn->prevent_close) {
- lassert(conn->state <= _OUTPUT_DNSSIM_CONN_CLOSE_REQUESTED, "conn already closing");
- conn->state = _OUTPUT_DNSSIM_CONN_CLOSE_REQUESTED;
- return;
- }
- conn->state = _OUTPUT_DNSSIM_CONN_CLOSING;
-
- if (conn->handshake_timer != NULL) {
- uv_timer_stop(conn->handshake_timer);
- uv_close((uv_handle_t*)conn->handshake_timer, _on_handshake_timer_closed);
- }
- if (conn->idle_timer != NULL) {
- conn->is_idle = false;
- uv_timer_stop(conn->idle_timer);
- uv_close((uv_handle_t*)conn->idle_timer, _on_idle_timer_closed);
- }
-
- switch (_self->transport) {
- case OUTPUT_DNSSIM_TRANSPORT_TCP:
- _output_dnssim_tcp_close(conn);
- break;
- case OUTPUT_DNSSIM_TRANSPORT_TLS:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- _output_dnssim_tls_close(conn);
-#else
- lfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- case OUTPUT_DNSSIM_TRANSPORT_HTTPS2:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- _output_dnssim_https2_close(conn);
-#else
- lfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- default:
- lfatal("unsupported transport");
- break;
- }
-}
-
-/* Close connection or run idle timer when there are no more outstanding queries. */
-void _output_dnssim_conn_idle(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn can't be nil");
-
- if (conn->queued == NULL && conn->sent == NULL) {
- if (conn->idle_timer == NULL)
- _output_dnssim_conn_close(conn);
- else if (!conn->is_idle) {
- conn->is_idle = true;
- uv_timer_again(conn->idle_timer);
- }
- }
-}
-
-static void _send_pending_queries(_output_dnssim_connection_t* conn)
-{
- _output_dnssim_query_tcp_t* qry;
- mlassert(conn, "conn is nil");
- mlassert(conn->client, "conn->client is nil");
- qry = (_output_dnssim_query_tcp_t*)conn->client->pending;
-
- while (qry != NULL && conn->state == _OUTPUT_DNSSIM_CONN_ACTIVE) {
- _output_dnssim_query_tcp_t* next = (_output_dnssim_query_tcp_t*)qry->qry.next;
- if (qry->qry.state == _OUTPUT_DNSSIM_QUERY_PENDING_WRITE) {
- switch (qry->qry.transport) {
- case OUTPUT_DNSSIM_TRANSPORT_TCP:
- _output_dnssim_tcp_write_query(conn, qry);
- break;
- case OUTPUT_DNSSIM_TRANSPORT_TLS:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- _output_dnssim_tls_write_query(conn, qry);
-#else
- mlfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- case OUTPUT_DNSSIM_TRANSPORT_HTTPS2:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- _output_dnssim_https2_write_query(conn, qry);
-#else
- mlfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- default:
- mlfatal("unsupported protocol");
- break;
- }
- }
- qry = next;
- }
-}
-
-int _output_dnssim_handle_pending_queries(_output_dnssim_client_t* client)
-{
- int ret = 0;
- mlassert(client, "client is nil");
-
- if (client->pending == NULL)
- return ret;
-
- output_dnssim_t* self = client->dnssim;
- mlassert(self, "client must belong to dnssim");
-
- /* Get active connection or find out whether new connection has to be opened. */
- bool is_connecting = false;
- _output_dnssim_connection_t* conn = client->conn;
- while (conn != NULL) {
- if (conn->state == _OUTPUT_DNSSIM_CONN_ACTIVE)
- break;
- else if (_conn_is_connecting(conn))
- is_connecting = true;
- conn = conn->next;
- }
-
- if (conn != NULL) { /* Send data right away over active connection. */
- _send_pending_queries(conn);
- } else if (!is_connecting) { /* No active or connecting connection -> open a new one. */
- lfatal_oom(conn = calloc(1, sizeof(_output_dnssim_connection_t)));
- conn->state = _OUTPUT_DNSSIM_CONN_INITIALIZED;
- conn->client = client;
- conn->stats = self->stats_current;
- if (_self->transport == OUTPUT_DNSSIM_TRANSPORT_TLS) {
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- ret = _output_dnssim_tls_init(conn);
- if (ret < 0) {
- free(conn);
- return ret;
- }
-#else
- lfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- } else if (_self->transport == OUTPUT_DNSSIM_TRANSPORT_HTTPS2) {
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- ret = _output_dnssim_https2_init(conn);
- if (ret < 0) {
- free(conn);
- return ret;
- }
-#else
- lfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- }
- ret = _output_dnssim_tcp_connect(self, conn);
- if (ret < 0)
- return ret;
- _ll_append(client->conn, conn);
- } /* Otherwise, pending queries wil be sent after connected callback. */
-
- return ret;
-}
-
-void _output_dnssim_conn_activate(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn is nil");
- mlassert(conn->client, "conn must be associated with a client");
- mlassert(conn->client->dnssim, "client must be associated with dnssim");
-
- uv_timer_stop(conn->handshake_timer);
-
- conn->state = _OUTPUT_DNSSIM_CONN_ACTIVE;
- conn->client->dnssim->stats_current->conn_active++;
- conn->read_state = _OUTPUT_DNSSIM_READ_STATE_DNSLEN;
- conn->dnsbuf_len = 2;
- conn->dnsbuf_pos = 0;
- conn->dnsbuf_free_after_use = false;
-
- _send_pending_queries(conn);
- _output_dnssim_conn_idle(conn);
-}
-
-int _process_dnsmsg(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn can't be nil");
- mlassert(conn->client, "conn must have client");
- mlassert(conn->client->dnssim, "client must have dnssim");
-
- output_dnssim_t* self = conn->client->dnssim;
-
- core_object_payload_t payload = CORE_OBJECT_PAYLOAD_INIT(NULL);
- core_object_dns_t dns_a = CORE_OBJECT_DNS_INIT(&payload);
-
- payload.payload = (uint8_t*)conn->dnsbuf_data;
- payload.len = conn->dnsbuf_len;
-
- dns_a.obj_prev = (core_object_t*)&payload;
- int ret = core_object_dns_parse_header(&dns_a);
- if (ret != 0) {
- lwarning("tcp response malformed");
- return _ERR_MALFORMED;
- }
- ldebug("tcp recv dnsmsg id: %04x", dns_a.id);
-
- _output_dnssim_query_t* qry;
-
- if (_self->transport == OUTPUT_DNSSIM_TRANSPORT_HTTPS2) {
- lassert(conn->http2, "conn must have http2 ctx");
- lassert(conn->http2->current_qry, "http2 has no current_qry");
- lassert(conn->http2->current_qry->qry.req, "current_qry has no req");
- lassert(conn->http2->current_qry->qry.req->dns_q, "req has no dns_q");
-
- ret = _output_dnssim_answers_request(conn->http2->current_qry->qry.req, &dns_a);
- switch (ret) {
- case 0:
- _output_dnssim_request_answered(conn->http2->current_qry->qry.req, &dns_a);
- break;
- case _ERR_MSGID:
- lwarning("https2 QID mismatch: request=0x%04x, response=0x%04x",
- conn->http2->current_qry->qry.req->dns_q->id, dns_a.id);
- break;
- case _ERR_QUESTION:
- default:
- lwarning("https2 response question mismatch");
- break;
- }
- } else {
- qry = conn->sent;
- while (qry != NULL) {
- if (qry->req->dns_q->id == dns_a.id) {
- ret = _output_dnssim_answers_request(qry->req, &dns_a);
- if (ret != 0) {
- lwarning("response question mismatch");
- } else {
- _output_dnssim_request_answered(qry->req, &dns_a);
- }
- break;
- }
- qry = qry->next;
- }
- }
-
- return 0;
-}
-
-static int _parse_dnsbuf_data(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn can't be nil");
- mlassert(conn->dnsbuf_pos == conn->dnsbuf_len, "attempt to parse incomplete dnsbuf_data");
- int ret = 0;
-
- switch (conn->read_state) {
- case _OUTPUT_DNSSIM_READ_STATE_DNSLEN: {
- uint16_t* p_dnslen = (uint16_t*)conn->dnsbuf_data;
- conn->dnsbuf_len = ntohs(*p_dnslen);
- if (conn->dnsbuf_len == 0) {
- mlwarning("invalid dnslen received: 0");
- conn->dnsbuf_len = 2;
- conn->read_state = _OUTPUT_DNSSIM_READ_STATE_DNSLEN;
- } else if (conn->dnsbuf_len < 12) {
- mldebug("invalid dnslen received: %d", conn->dnsbuf_len);
- ret = -1;
- } else {
- mldebug("dnslen: %d", conn->dnsbuf_len);
- conn->read_state = _OUTPUT_DNSSIM_READ_STATE_DNSMSG;
- }
- break;
- }
- case _OUTPUT_DNSSIM_READ_STATE_DNSMSG:
- ret = _process_dnsmsg(conn);
- if (ret) {
- conn->read_state = _OUTPUT_DNSSIM_READ_STATE_INVALID;
- } else {
- conn->dnsbuf_len = 2;
- conn->read_state = _OUTPUT_DNSSIM_READ_STATE_DNSLEN;
- }
- break;
- default:
- mlfatal("tcp invalid connection read_state");
- break;
- }
-
- conn->dnsbuf_pos = 0;
- if (conn->dnsbuf_free_after_use) {
- conn->dnsbuf_free_after_use = false;
- free(conn->dnsbuf_data);
- }
- conn->dnsbuf_data = NULL;
-
- return ret;
-}
-
-static unsigned int _read_dns_stream_chunk(_output_dnssim_connection_t* conn, size_t len, const char* data)
-{
- mlassert(conn, "conn can't be nil");
- mlassert(data, "data can't be nil");
- mlassert(len > 0, "no data to read");
- mlassert((conn->read_state == _OUTPUT_DNSSIM_READ_STATE_DNSLEN || conn->read_state == _OUTPUT_DNSSIM_READ_STATE_DNSMSG),
- "connection has invalid read_state");
-
- int ret = 0;
- unsigned int nread;
- size_t expected = conn->dnsbuf_len - conn->dnsbuf_pos;
- mlassert(expected > 0, "no data expected");
-
- if (conn->dnsbuf_free_after_use == false && expected > len) {
- /* Start of partial read. */
- mlassert(conn->dnsbuf_pos == 0, "conn->dnsbuf_pos must be 0 at start of partial read");
- mlassert(conn->dnsbuf_len > 0, "conn->dnsbuf_len must be set at start of partial read");
- mlfatal_oom(conn->dnsbuf_data = malloc(conn->dnsbuf_len * sizeof(char)));
- conn->dnsbuf_free_after_use = true;
- }
-
- if (conn->dnsbuf_free_after_use) { /* Partial read is in progress. */
- char* dest = conn->dnsbuf_data + conn->dnsbuf_pos;
- if (expected < len)
- len = expected;
- memcpy(dest, data, len);
- conn->dnsbuf_pos += len;
- nread = len;
- } else { /* Complete and clean read. */
- mlassert(expected <= len, "not enough data to perform complete read");
- conn->dnsbuf_data = (char*)data;
- conn->dnsbuf_pos = conn->dnsbuf_len;
- nread = expected;
- }
-
- /* If entire dnslen/dnsmsg was read, attempt to parse it. */
- if (conn->dnsbuf_len == conn->dnsbuf_pos) {
- ret = _parse_dnsbuf_data(conn);
- if (ret < 0)
- return ret;
- }
-
- return nread;
-}
-
-void _output_dnssim_read_dns_stream(_output_dnssim_connection_t* conn, size_t len, const char* data)
-{
- int pos = 0;
- int chunk = 0;
- while (pos < len) {
- chunk = _read_dns_stream_chunk(conn, len - pos, data + pos);
- if (chunk < 0) {
- mlwarning("lost orientation in DNS stream, closing");
- _output_dnssim_conn_close(conn);
- break;
- } else {
- pos += chunk;
- }
- }
- mlassert((pos == len) || (chunk < 0), "dns stream read invalid, pos != len");
-}
-
-void _output_dnssim_read_dnsmsg(_output_dnssim_connection_t* conn, size_t len, const char* data)
-{
- mlassert(conn, "conn is nil");
- mlassert(len > 0, "len is zero");
- mlassert(data, "no data");
- mlassert(conn->dnsbuf_pos == 0, "dnsbuf not empty");
- mlassert(conn->dnsbuf_free_after_use == false, "dnsbuf read in progress");
-
- /* Read dnsmsg of given length from input data. */
- conn->dnsbuf_len = len;
- conn->read_state = _OUTPUT_DNSSIM_READ_STATE_DNSMSG;
- int nread = _read_dns_stream_chunk(conn, len, data);
-
- if (nread != len) {
- mlwarning("failed to read received dnsmsg");
- if (conn->dnsbuf_free_after_use)
- free(conn->dnsbuf_data);
- }
-
- /* Clean state afterwards. */
- conn->read_state = _OUTPUT_DNSSIM_READ_STATE_DNSLEN;
- conn->dnsbuf_len = 2;
- conn->dnsbuf_pos = 0;
- conn->dnsbuf_free_after_use = false;
-}
diff --git a/src/output/dnssim/https2.c b/src/output/dnssim/https2.c
deleted file mode 100644
index 72fcdaf..0000000
--- a/src/output/dnssim/https2.c
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- * Copyright (c) 2020, CZ.NIC, z.s.p.o.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "output/dnssim.h"
-#include "output/dnssim/internal.h"
-#include "output/dnssim/ll.h"
-#include "core/assert.h"
-#include "lib/base64url.h"
-
-#include <gnutls/gnutls.h>
-#include <string.h>
-
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
-
-#define OUTPUT_DNSSIM_MAKE_NV(NAME, VALUE, VALUELEN) \
- { \
- (uint8_t*)NAME, (uint8_t*)VALUE, sizeof(NAME) - 1, VALUELEN, \
- NGHTTP2_NV_FLAG_NONE \
- }
-
-#define OUTPUT_DNSSIM_MAKE_NV2(NAME, VALUE) \
- { \
- (uint8_t*)NAME, (uint8_t*)VALUE, sizeof(NAME) - 1, sizeof(VALUE) - 1, \
- NGHTTP2_NV_FLAG_NONE \
- }
-
-#define OUTPUT_DNSSIM_HTTP_GET_TEMPLATE "?dns="
-#define OUTPUT_DNSSIM_HTTP_GET_TEMPLATE_LEN (sizeof(OUTPUT_DNSSIM_HTTP_GET_TEMPLATE) - 1)
-#define OUTPUT_DNSSIM_HTTP2_INITIAL_MAX_CONCURRENT_STREAMS 100
-#define OUTPUT_DNSSIM_HTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
-
-static core_log_t _log = LOG_T_INIT("output.dnssim");
-
-static ssize_t _http2_send(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)user_data;
- mlassert(conn, "conn can't be null");
- mlassert(conn->tls, "conn must have tls ctx");
- mlassert(conn->tls->session, "conn must have tls session");
-
- mldebug("http2 (%p): sending data, len=%ld", session, length);
-
- ssize_t len = 0;
- if ((len = gnutls_record_send(conn->tls->session, data, length)) < 0) {
- mlwarning("gnutls_record_send failed: %s", gnutls_strerror(len));
- len = NGHTTP2_ERR_CALLBACK_FAILURE;
- }
-
- return len;
-}
-
-static ssize_t _http2_on_data_provider_read(nghttp2_session* session, int32_t stream_id, uint8_t* buf, size_t length, uint32_t* data_flags, nghttp2_data_source* source, void* user_data)
-{
- _output_dnssim_https2_data_provider_t* buffer = source->ptr;
- mlassert(buffer, "no data provider");
- mlassert(buffer->len <= MAX_DNSMSG_SIZE, "invalid dnsmsg size: %zu B", buffer->len);
-
- ssize_t sent = (length < buffer->len) ? length : buffer->len;
- mlassert(sent >= 0, "negative length of bytes to send");
-
- memcpy(buf, buffer->buf, sent);
- buffer->buf += sent;
- buffer->len -= sent;
- if (buffer->len == 0)
- *data_flags |= NGHTTP2_DATA_FLAG_EOF;
-
- return sent;
-}
-
-static _output_dnssim_query_tcp_t* _http2_get_stream_qry(_output_dnssim_connection_t* conn, int32_t stream_id)
-{
- mlassert(conn, "conn is nil");
- mlassert(stream_id >= 0, "invalid stream_id");
-
- _output_dnssim_query_tcp_t* qry = (_output_dnssim_query_tcp_t*)conn->sent;
- while (qry != NULL && qry->stream_id != stream_id) {
- qry = (_output_dnssim_query_tcp_t*)qry->qry.next;
- }
-
- return qry;
-}
-
-static int _http2_on_header(nghttp2_session* session, const nghttp2_frame* frame, const uint8_t* name, size_t namelen, const uint8_t* value, size_t valuelen, uint8_t flags, void* user_data)
-{
- if (frame->hd.type == NGHTTP2_HEADERS && frame->headers.cat == NGHTTP2_HCAT_RESPONSE) {
- if (namelen == 7 && strncmp((char*)name, ":status", 7) == 0) {
- if (valuelen != 3 || (value[0] != '1' && value[0] != '2')) {
- /* When reponse code isn't 1xx or 2xx, close the query.
- * This will result in request timeout, which currently seems
- * slightly better than mocking SERVFAIL for statistics. */
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)user_data;
- mlassert(conn, "conn is nil");
- _output_dnssim_query_tcp_t* qry = _http2_get_stream_qry(conn, frame->hd.stream_id);
-
- if (qry != NULL) {
- _output_dnssim_close_query_https2(qry);
- mlinfo("http response %s, closing query", value);
- }
- }
- }
- }
- return 0;
-}
-
-static int _http2_on_data_recv(nghttp2_session* session, uint8_t flags, int32_t stream_id, const uint8_t* data, size_t len, void* user_data)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)user_data;
- mlassert(conn, "conn is nil");
-
- _output_dnssim_query_tcp_t* qry = _http2_get_stream_qry(conn, stream_id);
-
- mldebug("http2: data chunk recv, session=%p, len=%d", session, len);
-
- if (qry) {
- if (qry->recv_buf_len == 0) {
- if (len > MAX_DNSMSG_SIZE) {
- mlwarning("http response exceeded maximum size of dns message");
- return -1;
- }
- mlfatal_oom(qry->recv_buf = malloc(len));
- memcpy(qry->recv_buf, data, len);
- qry->recv_buf_len = len;
- } else {
- size_t total_len = qry->recv_buf_len + len;
- if (total_len > MAX_DNSMSG_SIZE) {
- mlwarning("http response exceeded maximum size of dns message");
- return -1;
- }
- mlfatal_oom(qry->recv_buf = realloc(qry->recv_buf, total_len));
- memcpy(qry->recv_buf + qry->recv_buf_len, data, len);
- qry->recv_buf_len = total_len;
- }
- } else {
- mldebug("no query associated with this stream id, ignoring");
- }
-
- return 0;
-}
-
-static void _http2_check_max_streams(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn can't be null");
- mlassert(conn->http2, "conn must have http2 ctx");
-
- switch (conn->state) {
- case _OUTPUT_DNSSIM_CONN_ACTIVE:
- if (conn->http2->open_streams >= conn->http2->max_concurrent_streams) {
- mlinfo("http2 (%p): reached maximum number of concurrent streams (%ld)",
- conn->http2->session, conn->http2->max_concurrent_streams);
- conn->state = _OUTPUT_DNSSIM_CONN_CONGESTED;
- }
- break;
- case _OUTPUT_DNSSIM_CONN_CONGESTED:
- if (conn->http2->open_streams < conn->http2->max_concurrent_streams)
- conn->state = _OUTPUT_DNSSIM_CONN_ACTIVE;
- break;
- default:
- break;
- }
-}
-
-static int _http2_on_stream_close(nghttp2_session* session, int32_t stream_id, uint32_t error_code, void* user_data)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)user_data;
- mlassert(conn, "conn can't be null");
- mlassert(conn->http2, "conn must have http2 ctx");
- mlassert(conn->http2->open_streams > 0, "conn has no open streams");
-
- conn->http2->open_streams--;
- _http2_check_max_streams(conn);
- return 0;
-}
-
-static int _http2_on_frame_recv(nghttp2_session* session, const nghttp2_frame* frame, void* user_data)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)user_data;
- mlassert(conn, "conn can't be null");
- mlassert(conn->tls, "conn must have tls ctx");
- mlassert(conn->tls->session, "conn must have tls session");
- mlassert(conn->http2, "conn must have http2 ctx");
-
- switch (frame->hd.type) {
- case NGHTTP2_DATA:
- if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
- mldebug("http2 (%p): final DATA frame recv", session);
- _output_dnssim_query_tcp_t* qry = _http2_get_stream_qry(conn, frame->hd.stream_id);
-
- if (qry != NULL) {
- conn->http2->current_qry = qry;
- _output_dnssim_read_dnsmsg(conn, qry->recv_buf_len, (char*)qry->recv_buf);
- }
- }
- break;
- case NGHTTP2_SETTINGS:
- if (!conn->http2->remote_settings_received) {
- /* On the first SETTINGS frame, set concurrent streams to unlimited, same as nghttp2. */
- conn->http2->remote_settings_received = true;
- conn->http2->max_concurrent_streams = OUTPUT_DNSSIM_HTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
- _http2_check_max_streams(conn);
- }
- nghttp2_settings* settings = (nghttp2_settings*)frame;
- int i;
- for (i = 0; i < settings->niv; i++) {
- switch (settings->iv[i].settings_id) {
- case NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS:
- conn->http2->max_concurrent_streams = settings->iv[i].value;
- _http2_check_max_streams(conn);
- break;
- default:
- break;
- }
- }
- break;
- default:
- break;
- }
- return 0;
-}
-
-int _output_dnssim_https2_init(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn is nil");
- mlassert(conn->tls == NULL, "conn already has tls context");
- mlassert(conn->http2 == NULL, "conn already has http2 context");
- mlassert(conn->client, "conn must be associated with a client");
- mlassert(conn->client->dnssim, "client must have dnssim");
-
- int ret = -1;
- nghttp2_session_callbacks* callbacks;
- nghttp2_option* option;
- output_dnssim_t* self = conn->client->dnssim;
-
- /* Initialize TLS session. */
- ret = _output_dnssim_tls_init(conn);
- if (ret < 0)
- return ret;
-
- /* Configure ALPN to negotiate HTTP/2. */
- const gnutls_datum_t protos[] = {
- { (unsigned char*)"h2", 2 }
- };
- ret = gnutls_alpn_set_protocols(conn->tls->session, protos, 1, 0);
- if (ret < 0) {
- lwarning("failed to set ALPN protocol: %s", gnutls_strerror(ret));
- return ret;
- }
-
- lfatal_oom(conn->http2 = calloc(1, sizeof(_output_dnssim_http2_ctx_t)));
- conn->http2->max_concurrent_streams = OUTPUT_DNSSIM_HTTP2_INITIAL_MAX_CONCURRENT_STREAMS;
-
- /* Set up HTTP/2 callbacks and client. */
- lassert(nghttp2_session_callbacks_new(&callbacks) == 0, "out of memory");
- nghttp2_session_callbacks_set_send_callback(callbacks, _http2_send);
- nghttp2_session_callbacks_set_on_header_callback(callbacks, _http2_on_header);
- nghttp2_session_callbacks_set_on_data_chunk_recv_callback(callbacks, _http2_on_data_recv);
- nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks, _http2_on_frame_recv);
- nghttp2_session_callbacks_set_on_stream_close_callback(callbacks, _http2_on_stream_close);
-
- lassert(nghttp2_option_new(&option) == 0, "out of memory");
- nghttp2_option_set_peer_max_concurrent_streams(option, conn->http2->max_concurrent_streams);
-
- ret = nghttp2_session_client_new2(&conn->http2->session, callbacks, conn, option);
-
- nghttp2_session_callbacks_del(callbacks);
- nghttp2_option_del(option);
-
- if (ret < 0) {
- free(conn->http2);
- conn->http2 = NULL;
- }
-
- return ret;
-}
-
-int _output_dnssim_https2_setup(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn is nil");
- mlassert(conn->tls, "conn must have tls ctx");
- mlassert(conn->tls->session, "conn must have tls session");
- mlassert(conn->http2, "conn must have http2 ctx");
- mlassert(conn->http2->session, "conn must have http2 session");
-
- int ret = -1;
-
- /* Check "h2" protocol was negotiated with ALPN. */
- gnutls_datum_t proto;
- ret = gnutls_alpn_get_selected_protocol(conn->tls->session, &proto);
- if (ret < 0) {
- mlwarning("http2: failed to get negotiated protocol: %s", gnutls_strerror(ret));
- return ret;
- }
- if (proto.size != 2 || memcmp("h2", proto.data, 2) != 0) {
- mlwarning("http2: protocol is not negotiated");
- return ret;
- }
-
- /* Submit SETTIGNS frame. */
- static const nghttp2_settings_entry iv[] = {
- { NGHTTP2_SETTINGS_MAX_FRAME_SIZE, MAX_DNSMSG_SIZE },
- { NGHTTP2_SETTINGS_ENABLE_PUSH, 0 }, /* Only we can initiate streams. */
- };
- ret = nghttp2_submit_settings(conn->http2->session, NGHTTP2_FLAG_NONE, iv, sizeof(iv) / sizeof(*iv));
- if (ret < 0) {
- mlwarning("http2: failed to submit SETTINGS: %s", nghttp2_strerror(ret));
- return ret;
- }
-
- ret = 0;
- return ret;
-}
-
-void _output_dnssim_https2_process_input_data(_output_dnssim_connection_t* conn, size_t len, const char* data)
-{
- mlassert(conn, "conn is nil");
- mlassert(conn->http2, "conn must have http2 ctx");
- mlassert(conn->http2->session, "conn must have http2 session");
-
- /* Process incoming frames. */
- ssize_t ret = 0;
- conn->prevent_close = true;
- ret = nghttp2_session_mem_recv(conn->http2->session, (uint8_t*)data, len);
- conn->prevent_close = false;
- if (ret < 0) {
- mlwarning("failed nghttp2_session_mem_recv: %s", nghttp2_strerror(ret));
- _output_dnssim_conn_close(conn);
- return;
- } else if (conn->state == _OUTPUT_DNSSIM_CONN_CLOSE_REQUESTED) {
- _output_dnssim_conn_close(conn);
- return;
- }
- mlassert(ret == len, "nghttp2_session_mem_recv didn't process all data");
-
- /* Send any frames the read might have triggered. */
- ret = nghttp2_session_send(conn->http2->session);
- if (ret < 0) {
- mlwarning("failed nghttp2_session_send: %s", nghttp2_strerror(ret));
- _output_dnssim_conn_close(conn);
- return;
- }
-}
-
-int _output_dnssim_create_query_https2(output_dnssim_t* self, _output_dnssim_request_t* req)
-{
- mlassert_self();
- lassert(req, "req is nil");
- lassert(req->client, "request must have a client associated with it");
-
- _output_dnssim_query_tcp_t* qry;
-
- lfatal_oom(qry = calloc(1, sizeof(_output_dnssim_query_tcp_t)));
-
- qry->qry.transport = OUTPUT_DNSSIM_TRANSPORT_HTTPS2;
- qry->qry.req = req;
- qry->qry.state = _OUTPUT_DNSSIM_QUERY_PENDING_WRITE;
- qry->stream_id = -1;
- req->qry = &qry->qry; // TODO change when adding support for multiple Qs for req
- _ll_append(req->client->pending, &qry->qry);
-
- return _output_dnssim_handle_pending_queries(req->client);
-}
-
-void _output_dnssim_close_query_https2(_output_dnssim_query_tcp_t* qry)
-{
- mlassert(qry, "qry can't be null");
- mlassert(qry->qry.req, "query must be part of a request");
- _output_dnssim_request_t* req = qry->qry.req;
- mlassert(req->client, "request must belong to a client");
-
- _ll_try_remove(req->client->pending, &qry->qry);
- if (qry->conn) {
- _output_dnssim_connection_t* conn = qry->conn;
- _ll_try_remove(conn->sent, &qry->qry);
- qry->conn = NULL;
- _output_dnssim_conn_idle(conn);
- }
-
- if (qry->recv_buf != NULL)
- free(qry->recv_buf);
-
- _ll_remove(req->qry, &qry->qry);
- free(qry);
-}
-
-void _output_dnssim_https2_close(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn can't be nil");
- mlassert(conn->http2, "conn must have http2 ctx");
-
- nghttp2_session_del(conn->http2->session);
- _output_dnssim_tls_close(conn);
-}
-
-static int _http2_send_query_get(_output_dnssim_connection_t* conn, _output_dnssim_query_tcp_t* qry)
-{
- mlassert(conn, "conn can't be null");
- mlassert(qry, "qry can't be null");
- mlassert(qry->qry.req, "req can't be null");
- mlassert(qry->qry.req->payload, "payload can't be null");
- mlassert(qry->qry.req->payload->len <= MAX_DNSMSG_SIZE, "payload too big");
- mlassert(conn->client, "conn must be associated with client");
- mlassert(conn->client->dnssim, "client must have dnssim");
-
- output_dnssim_t* self = conn->client->dnssim;
- core_object_payload_t* content = qry->qry.req->payload;
-
- const size_t uri_path_len = strlen(_self->h2_uri_path);
- const size_t path_len = uri_path_len
- + OUTPUT_DNSSIM_HTTP_GET_TEMPLATE_LEN
- + (content->len * 4) / 3 + 3 /* upper limit of base64 encoding */
- + 1; /* terminating null byte */
- if (path_len >= _MAX_URI_LEN) {
- self->discarded++;
- linfo("http2: uri path with query too long, query discarded");
- return 0;
- }
- char path[path_len];
- memcpy(path, _self->h2_uri_path, uri_path_len);
- memcpy(&path[uri_path_len], OUTPUT_DNSSIM_HTTP_GET_TEMPLATE, OUTPUT_DNSSIM_HTTP_GET_TEMPLATE_LEN);
-
- int32_t ret = base64url_encode(content->payload, content->len,
- (uint8_t*)&path[uri_path_len + OUTPUT_DNSSIM_HTTP_GET_TEMPLATE_LEN],
- sizeof(path) - uri_path_len - OUTPUT_DNSSIM_HTTP_GET_TEMPLATE_LEN - 1);
- if (ret < 0) {
- self->discarded++;
- linfo("http2: base64url encode of query failed, query discarded");
- return 0;
- }
-
- nghttp2_nv hdrs[] = {
- OUTPUT_DNSSIM_MAKE_NV2(":method", "GET"),
- OUTPUT_DNSSIM_MAKE_NV2(":scheme", "https"),
- OUTPUT_DNSSIM_MAKE_NV(":authority", _self->h2_uri_authority, strlen(_self->h2_uri_authority)),
- OUTPUT_DNSSIM_MAKE_NV(":path", path, uri_path_len + sizeof(OUTPUT_DNSSIM_HTTP_GET_TEMPLATE) - 1 + ret),
- OUTPUT_DNSSIM_MAKE_NV2("accept", "application/dns-message"),
- };
-
- qry->stream_id = nghttp2_submit_request(conn->http2->session, NULL, hdrs, sizeof(hdrs) / sizeof(nghttp2_nv), NULL, NULL);
-
- if (qry->stream_id < 0) {
- mldebug("http2 (%p): failed to submit request: %s", conn->http2->session, nghttp2_strerror(qry->stream_id));
- return -1;
- }
- mldebug("http2 (%p): GET %s", conn->http2->session, path);
- conn->http2->open_streams++;
- _http2_check_max_streams(conn);
-
- ret = nghttp2_session_send(conn->http2->session);
- if (ret < 0) {
- mldebug("http2 (%p): failed session send: %s", conn->http2->session, nghttp2_strerror(ret));
- return -1;
- }
-
- return 0;
-}
-
-static int _http2_send_query_post(_output_dnssim_connection_t* conn, _output_dnssim_query_tcp_t* qry)
-{
- mlassert(conn, "conn can't be null");
- mlassert(qry, "qry can't be null");
- mlassert(qry->qry.req, "req can't be null");
- mlassert(qry->qry.req->payload, "payload can't be null");
- mlassert(qry->qry.req->payload->len <= MAX_DNSMSG_SIZE, "payload too big");
- mlassert(conn->client, "conn must be associated with client");
- mlassert(conn->client->dnssim, "client must have dnssim");
-
- output_dnssim_t* self = conn->client->dnssim;
-
- core_object_payload_t* content = qry->qry.req->payload;
-
- int window_size = nghttp2_session_get_remote_window_size(conn->http2->session);
- if (content->len > window_size) {
- mldebug("http2 (%p): insufficient remote window size, deferring", conn->http2->session);
- return 0;
- }
-
- char content_length[6]; /* max dnslen "65535" */
- int content_length_len = snprintf(content_length, 6, "%zd", content->len);
-
- nghttp2_nv hdrs[] = {
- OUTPUT_DNSSIM_MAKE_NV2(":method", "POST"),
- OUTPUT_DNSSIM_MAKE_NV2(":scheme", "https"),
- OUTPUT_DNSSIM_MAKE_NV(":authority", _self->h2_uri_authority, strlen(_self->h2_uri_authority)),
- OUTPUT_DNSSIM_MAKE_NV(":path", _self->h2_uri_path, strlen(_self->h2_uri_path)),
- OUTPUT_DNSSIM_MAKE_NV2("accept", "application/dns-message"),
- OUTPUT_DNSSIM_MAKE_NV2("content-type", "application/dns-message"),
- OUTPUT_DNSSIM_MAKE_NV("content-length", content_length, content_length_len)
- };
-
- _output_dnssim_https2_data_provider_t data = {
- .buf = content->payload,
- .len = content->len
- };
-
- nghttp2_data_provider data_provider = {
- .source.ptr = &data,
- .read_callback = _http2_on_data_provider_read
- };
-
- qry->stream_id = nghttp2_submit_request(conn->http2->session, NULL, hdrs, sizeof(hdrs) / sizeof(nghttp2_nv), &data_provider, NULL);
-
- if (qry->stream_id < 0) {
- mldebug("http2 (%p): failed to submit request: %s", conn->http2->session, nghttp2_strerror(qry->stream_id));
- return -1;
- }
- mldebug("http2 (%p): POST payload len=%ld", conn->http2->session, content->len);
- conn->http2->open_streams++;
- _http2_check_max_streams(conn);
-
- window_size = nghttp2_session_get_stream_remote_window_size(conn->http2->session, qry->stream_id);
- mlassert(content->len <= window_size,
- "unsupported: http2 stream window size (%ld B) is smaller than dns payload (%ld B)",
- window_size, content->len);
-
- int ret = nghttp2_session_send(conn->http2->session);
- if (ret < 0) {
- mldebug("http2 (%p): failed session send: %s", conn->http2->session, nghttp2_strerror(ret));
- return -1;
- }
-
- return 0;
-}
-
-void _output_dnssim_https2_write_query(_output_dnssim_connection_t* conn, _output_dnssim_query_tcp_t* qry)
-{
- mlassert(qry, "qry can't be null");
- mlassert(qry->qry.state == _OUTPUT_DNSSIM_QUERY_PENDING_WRITE, "qry must be pending write");
- mlassert(conn, "conn can't be null");
- mlassert(conn->state == _OUTPUT_DNSSIM_CONN_ACTIVE, "connection state != ACTIVE");
- mlassert(conn->http2, "conn must have http2 ctx");
- mlassert(conn->http2->session, "conn must have http2 session");
- mlassert(conn->client, "conn must be associated with client");
- mlassert(conn->client->pending, "conn has no pending queries");
- mlassert(conn->client->dnssim, "client must have dnssim");
-
- int ret = 0;
- output_dnssim_t* self = conn->client->dnssim;
-
- if (!nghttp2_session_check_request_allowed(conn->http2->session)) {
- mldebug("http2 (%p): request not allowed", conn->http2->session);
- _output_dnssim_conn_close(conn);
- return;
- }
-
- switch (_self->h2_method) {
- case OUTPUT_DNSSIM_H2_POST:
- ret = _http2_send_query_post(conn, qry);
- break;
- case OUTPUT_DNSSIM_H2_GET:
- ret = _http2_send_query_get(conn, qry);
- break;
- default:
- lfatal("http2: unsupported method");
- }
-
- if (ret < 0) {
- _output_dnssim_conn_close(conn);
- return;
- }
-
- qry->conn = conn;
- _ll_remove(conn->client->pending, &qry->qry);
- _ll_append(conn->sent, &qry->qry);
-
- /* Stop idle timer, since there are queries to answer now. */
- if (conn->idle_timer != NULL) {
- conn->is_idle = false;
- uv_timer_stop(conn->idle_timer);
- }
-
- qry->qry.state = _OUTPUT_DNSSIM_QUERY_SENT;
-}
-
-#endif
diff --git a/src/output/dnssim/internal.h b/src/output/dnssim/internal.h
deleted file mode 100644
index b9feddf..0000000
--- a/src/output/dnssim/internal.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2019-2020, CZ.NIC, z.s.p.o.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __dnsjit_output_dnssim_internal_h
-#define __dnsjit_output_dnssim_internal_h
-
-#include <gnutls/gnutls.h>
-#include <nghttp2/nghttp2.h>
-#include <uv.h>
-#include "core/object/dns.h"
-#include "core/object/payload.h"
-
-#define DNSSIM_MIN_GNUTLS_VERSION 0x030603
-#define DNSSIM_MIN_GNUTLS_ERRORMSG "dnssim tls/https2 transport requires GnuTLS >= 3.6.3"
-
-#define _self ((_output_dnssim_t*)self)
-#define _ERR_MALFORMED -2
-#define _ERR_MSGID -3
-#define _ERR_TC -4
-#define _ERR_QUESTION -5
-
-#define _MAX_URI_LEN 65536
-#define MAX_DNSMSG_SIZE 65535
-#define WIRE_BUF_SIZE (MAX_DNSMSG_SIZE + 2 + 16384) /** max tcplen + 2b tcplen + 16kb tls record */
-
-typedef struct _output_dnssim_request _output_dnssim_request_t;
-typedef struct _output_dnssim_connection _output_dnssim_connection_t;
-typedef struct _output_dnssim_client _output_dnssim_client_t;
-
-/*
- * Query-related structures.
- */
-
-typedef struct _output_dnssim_query _output_dnssim_query_t;
-struct _output_dnssim_query {
- /*
- * Next query in the list.
- *
- * Currently, next is used for TCP clients/connection, which makes it
- * impossible to use for tracking multiple queries of a single request.
- *
- * TODO: refactor the linked lists to allow query to be part of multiple lists
- */
- _output_dnssim_query_t* next;
-
- output_dnssim_transport_t transport;
- _output_dnssim_request_t* req;
-
- /* Query state, currently used only for TCP. */
- enum {
- _OUTPUT_DNSSIM_QUERY_PENDING_WRITE,
- _OUTPUT_DNSSIM_QUERY_PENDING_WRITE_CB,
- _OUTPUT_DNSSIM_QUERY_PENDING_CLOSE,
- _OUTPUT_DNSSIM_QUERY_WRITE_FAILED,
- _OUTPUT_DNSSIM_QUERY_SENT,
- _OUTPUT_DNSSIM_QUERY_ORPHANED
- } state;
-};
-
-typedef struct _output_dnssim_query_udp _output_dnssim_query_udp_t;
-struct _output_dnssim_query_udp {
- _output_dnssim_query_t qry;
-
- uv_udp_t* handle;
- uv_buf_t buf;
-};
-
-typedef struct _output_dnssim_query_tcp _output_dnssim_query_tcp_t;
-struct _output_dnssim_query_tcp {
- _output_dnssim_query_t qry;
-
- /* Connection this query is assigned to. */
- _output_dnssim_connection_t* conn;
-
- uv_write_t write_req;
-
- /* Send buffers for libuv; 0 is for dnslen, 1 is for dnsmsg. */
- uv_buf_t bufs[2];
-
- /* HTTP/2 stream id that was used to send this query. */
- int32_t stream_id;
-
- /* HTTP/2 expected content length. */
- int32_t content_len;
-
- /* Receive buffer (currently used only by HTTP/2). */
- uint8_t* recv_buf;
- ssize_t recv_buf_len;
-};
-
-struct _output_dnssim_request {
- /* List of queries associated with this request. */
- _output_dnssim_query_t* qry;
-
- /* Client this request belongs to. */
- _output_dnssim_client_t* client;
-
- /* The DNS question to be resolved. */
- core_object_payload_t* payload;
- core_object_dns_t* dns_q;
- const uint8_t* question;
- ssize_t question_len;
-
- /* Timestamps for latency calculation. */
- uint64_t created_at;
- uint64_t ended_at;
-
- /* Timer for tracking timeout of the request. */
- uv_timer_t* timer;
-
- /* The output component of this request. */
- output_dnssim_t* dnssim;
-
- /* State of the request. */
- enum {
- _OUTPUT_DNSSIM_REQ_ONGOING,
- _OUTPUT_DNSSIM_REQ_CLOSING
- } state;
-
- /* Statistics interval in which this request is tracked. */
- output_dnssim_stats_t* stats;
-};
-
-/*
- * Connection-related structures.
- */
-
-/* Read-state of connection's data stream. */
-typedef enum _output_dnssim_read_state {
- _OUTPUT_DNSSIM_READ_STATE_CLEAN,
- _OUTPUT_DNSSIM_READ_STATE_DNSLEN, /* Expecting bytes of dnslen. */
- _OUTPUT_DNSSIM_READ_STATE_DNSMSG, /* Expecting bytes of dnsmsg. */
- _OUTPUT_DNSSIM_READ_STATE_INVALID
-} _output_dnssim_read_state_t;
-
-/* TLS-related data for a single connection. */
-typedef struct _output_dnssim_tls_ctx {
- gnutls_session_t session;
- uint8_t* buf;
- ssize_t buf_len;
- ssize_t buf_pos;
- size_t write_queue_size;
-} _output_dnssim_tls_ctx_t;
-
-/* HTTP2 context for a single connection. */
-typedef struct _output_dnssim_http2_ctx {
- nghttp2_session* session;
-
- /* Query to which the dnsbuf currently being processed belongs to. */
- _output_dnssim_query_tcp_t* current_qry;
-
- /* Maximum number of concurrent and currently open streams. */
- uint32_t max_concurrent_streams;
- uint32_t open_streams;
-
- /* Flag indicating whether we received the peer's initial SETTINGS frame. */
- bool remote_settings_received;
-} _output_dnssim_http2_ctx_t;
-
-struct _output_dnssim_connection {
- _output_dnssim_connection_t* next;
-
- uv_tcp_t* handle;
-
- /* Timeout timer for establishing the connection. */
- uv_timer_t* handshake_timer;
-
- /* Idle timer for connection reuse. rfc7766#section-6.2.3 */
- uv_timer_t* idle_timer;
- bool is_idle;
-
- /* List of queries that have been queued (pending write callback). */
- _output_dnssim_query_t* queued;
-
- /* List of queries that have been sent over this connection. */
- _output_dnssim_query_t* sent;
-
- /* Client this connection belongs to. */
- _output_dnssim_client_t* client;
-
- /* State of the connection.
- * Numeric ordering of constants is significant and follows the typical connection lifecycle.
- * Ensure new states are added to a proper place. */
- enum {
- _OUTPUT_DNSSIM_CONN_INITIALIZED = 0,
- _OUTPUT_DNSSIM_CONN_TCP_HANDSHAKE = 10,
- _OUTPUT_DNSSIM_CONN_TLS_HANDSHAKE = 20,
- _OUTPUT_DNSSIM_CONN_ACTIVE = 30,
- _OUTPUT_DNSSIM_CONN_CONGESTED = 35,
- _OUTPUT_DNSSIM_CONN_CLOSE_REQUESTED = 38,
- _OUTPUT_DNSSIM_CONN_CLOSING = 40,
- _OUTPUT_DNSSIM_CONN_CLOSED = 50
- } state;
-
- /* State of the data stream read. */
- _output_dnssim_read_state_t read_state;
-
- /* Total length of the expected dns data (either 2 for dnslen, or dnslen itself). */
- size_t dnsbuf_len;
-
- /* Current position in the receive dns buffer. */
- size_t dnsbuf_pos;
-
- /* Receive buffer used for incomplete messages or dnslen. */
- char* dnsbuf_data;
- bool dnsbuf_free_after_use;
-
- /* Statistics interval in which the handshake is tracked. */
- output_dnssim_stats_t* stats;
-
- /* TLS-related data. */
- _output_dnssim_tls_ctx_t* tls;
-
- /* HTTP/2-related data. */
- _output_dnssim_http2_ctx_t* http2;
-
- /* Prevents immediate closure of connection. Instead, connection is moved
- * to CLOSE_REQUESTED state and setter of this flag is responsible for
- * closing the connection when clearing this flag. */
- bool prevent_close;
-};
-
-/*
- * Client structure.
- */
-
-struct _output_dnssim_client {
- /* Dnssim component this client belongs to. */
- output_dnssim_t* dnssim;
-
- /* List of connections.
- * Multiple connections may be used (e.g. some are already closed for writing).
- */
- _output_dnssim_connection_t* conn;
-
- /* List of queries that are pending to be sent over any available connection. */
- _output_dnssim_query_t* pending;
-
- /* TLS-ticket for session resumption. */
- gnutls_datum_t tls_ticket;
-};
-
-/*
- * DnsSim-related structures.
- */
-
-typedef struct _output_dnssim_source _output_dnssim_source_t;
-struct _output_dnssim_source {
- _output_dnssim_source_t* next;
- struct sockaddr_storage addr;
-};
-
-typedef struct _output_dnssim _output_dnssim_t;
-struct _output_dnssim {
- output_dnssim_t pub;
-
- uv_loop_t loop;
- uv_timer_t stats_timer;
-
- struct sockaddr_storage target;
- _output_dnssim_source_t* source;
- output_dnssim_transport_t transport;
-
- char h2_uri_authority[_MAX_URI_LEN];
- char h2_uri_path[_MAX_URI_LEN];
- bool h2_zero_out_msgid;
- output_dnssim_h2_method_t h2_method;
-
- /* Array of clients, mapped by client ID (ranges from 0 to max_clients). */
- _output_dnssim_client_t* client_arr;
-
- gnutls_priority_t* tls_priority;
- gnutls_certificate_credentials_t tls_cred;
- char wire_buf[WIRE_BUF_SIZE]; /* thread-local buffer for processing tls input */
-};
-
-/* Provides data for HTTP/2 data frames. */
-typedef struct {
- const uint8_t* buf;
- size_t len;
-} _output_dnssim_https2_data_provider_t;
-
-/*
- * Forward function declarations.
- */
-
-int _output_dnssim_bind_before_connect(output_dnssim_t* self, uv_handle_t* handle);
-int _output_dnssim_create_query_udp(output_dnssim_t* self, _output_dnssim_request_t* req);
-int _output_dnssim_create_query_tcp(output_dnssim_t* self, _output_dnssim_request_t* req);
-void _output_dnssim_close_query_udp(_output_dnssim_query_udp_t* qry);
-void _output_dnssim_close_query_tcp(_output_dnssim_query_tcp_t* qry);
-int _output_dnssim_answers_request(_output_dnssim_request_t* req, core_object_dns_t* response);
-void _output_dnssim_request_answered(_output_dnssim_request_t* req, core_object_dns_t* msg);
-void _output_dnssim_maybe_free_request(_output_dnssim_request_t* req);
-void _output_dnssim_on_uv_alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf);
-void _output_dnssim_create_request(output_dnssim_t* self, _output_dnssim_client_t* client, core_object_payload_t* payload);
-int _output_dnssim_handle_pending_queries(_output_dnssim_client_t* client);
-int _output_dnssim_tcp_connect(output_dnssim_t* self, _output_dnssim_connection_t* conn);
-void _output_dnssim_tcp_close(_output_dnssim_connection_t* conn);
-void _output_dnssim_tcp_write_query(_output_dnssim_connection_t* conn, _output_dnssim_query_tcp_t* qry);
-void _output_dnssim_conn_close(_output_dnssim_connection_t* conn);
-void _output_dnssim_conn_idle(_output_dnssim_connection_t* conn);
-int _output_dnssim_handle_pending_queries(_output_dnssim_client_t* client);
-void _output_dnssim_conn_activate(_output_dnssim_connection_t* conn);
-void _output_dnssim_conn_maybe_free(_output_dnssim_connection_t* conn);
-void _output_dnssim_read_dns_stream(_output_dnssim_connection_t* conn, size_t len, const char* data);
-void _output_dnssim_read_dnsmsg(_output_dnssim_connection_t* conn, size_t len, const char* data);
-
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
-int _output_dnssim_create_query_tls(output_dnssim_t* self, _output_dnssim_request_t* req);
-void _output_dnssim_close_query_tls(_output_dnssim_query_tcp_t* qry);
-int _output_dnssim_tls_init(_output_dnssim_connection_t* conn);
-void _output_dnssim_tls_process_input_data(_output_dnssim_connection_t* conn);
-void _output_dnssim_tls_close(_output_dnssim_connection_t* conn);
-void _output_dnssim_tls_write_query(_output_dnssim_connection_t* conn, _output_dnssim_query_tcp_t* qry);
-
-int _output_dnssim_create_query_https2(output_dnssim_t* self, _output_dnssim_request_t* req);
-void _output_dnssim_close_query_https2(_output_dnssim_query_tcp_t* qry);
-int _output_dnssim_https2_init(_output_dnssim_connection_t* conn);
-int _output_dnssim_https2_setup(_output_dnssim_connection_t* conn);
-void _output_dnssim_https2_process_input_data(_output_dnssim_connection_t* conn, size_t len, const char* data);
-void _output_dnssim_https2_close(_output_dnssim_connection_t* conn);
-void _output_dnssim_https2_write_query(_output_dnssim_connection_t* conn, _output_dnssim_query_tcp_t* qry);
-#endif
-
-#endif
diff --git a/src/output/dnssim/ll.h b/src/output/dnssim/ll.h
deleted file mode 100644
index 8e0b07a..0000000
--- a/src/output/dnssim/ll.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2019-2020, CZ.NIC, z.s.p.o.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __dnsjit_output_dnssim_ll_h
-#define __dnsjit_output_dnssim_ll_h
-
-#include "core/assert.h"
-
-/* Utility macros for linked list structures.
- *
- * - "list" is the pointer to the first node of the linked list
- * - "list" can be NULL if there are no nodes
- * - every node has "next", which points to the next node (can be NULL)
- */
-
-/* Append a node to the list.
- *
- * Only a single node can be appended - node->next must be NULL.
- */
-#define _ll_append(list, node) \
- { \
- glassert((node)->next == NULL, "node->next must be null when appending"); \
- if ((list) == NULL) \
- (list) = (node); \
- else if ((node) != NULL) { \
- typeof(list) _current = (list); \
- while (_current->next != NULL) \
- _current = _current->next; \
- _current->next = node; \
- } \
- }
-
-/* Remove a node from the list.
- *
- * In strict mode, the node must be present in the list.
- */
-#define _ll_remove_template(list, node, strict) \
- { \
- if (strict) \
- glassert((list), "list can't be null when removing nodes"); \
- if ((list) != NULL && (node) != NULL) { \
- if ((list) == (node)) { \
- (list) = (node)->next; \
- (node)->next = NULL; \
- } else { \
- typeof(list) _current = (list); \
- while (_current != NULL && _current->next != (node)) { \
- if (strict) \
- glassert((_current->next), "list doesn't contain the node to be removed"); \
- _current = _current->next; \
- } \
- if (_current != NULL) { \
- _current->next = (node)->next; \
- (node)->next = NULL; \
- } \
- } \
- } \
- }
-
-/* Remove a node from the list. */
-#define _ll_remove(list, node) _ll_remove_template((list), (node), true)
-
-/* Remove a node from the list if it's present. */
-#define _ll_try_remove(list, node) _ll_remove_template((list), (node), false)
-
-#endif
diff --git a/src/output/dnssim/tcp.c b/src/output/dnssim/tcp.c
deleted file mode 100644
index 1f2b619..0000000
--- a/src/output/dnssim/tcp.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2019-2020, CZ.NIC, z.s.p.o.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "output/dnssim.h"
-#include "output/dnssim/internal.h"
-#include "output/dnssim/ll.h"
-#include "core/assert.h"
-
-#include <string.h>
-
-static core_log_t _log = LOG_T_INIT("output.dnssim");
-
-static void _move_queries_to_pending(_output_dnssim_query_tcp_t* qry)
-{
- _output_dnssim_query_tcp_t* qry_tmp;
- while (qry != NULL) {
- mlassert(qry->conn, "query must be associated with conn");
- mlassert(qry->conn->state == _OUTPUT_DNSSIM_CONN_CLOSED, "conn must be closed");
- mlassert(qry->conn->client, "conn must be associated with client");
- qry_tmp = (_output_dnssim_query_tcp_t*)qry->qry.next;
- qry->qry.next = NULL;
- _ll_append(qry->conn->client->pending, &qry->qry);
- qry->conn = NULL;
- qry->qry.state = _OUTPUT_DNSSIM_QUERY_ORPHANED;
- qry->stream_id = -1;
- qry->recv_buf_len = 0;
- if (qry->recv_buf != NULL) {
- free(qry->recv_buf);
- qry->recv_buf = NULL;
- }
- qry = qry_tmp;
- }
-}
-
-static void _on_tcp_closed(uv_handle_t* handle)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)handle->data;
- mlassert(conn, "conn is nil");
- conn->state = _OUTPUT_DNSSIM_CONN_CLOSED;
-
- /* Orphan any queries that are still unresolved. */
- _move_queries_to_pending((_output_dnssim_query_tcp_t*)conn->queued);
- conn->queued = NULL;
- _move_queries_to_pending((_output_dnssim_query_tcp_t*)conn->sent);
- conn->sent = NULL;
-
- /* TODO Improve client re-connect behavior in case the connection fails to
- * establish. Currently, queries are orphaned and attempted to be re-sent
- * along with the next query that triggers a new connection.
- *
- * Attempting to establish new connection immediately leads to performance
- * issues if the number of these attempts doesn't have upper limit. */
- ///* Ensure orhpaned queries are re-sent over a different connection. */
- //if (_output_dnssim_handle_pending_queries(conn->client) != 0)
- // mlinfo("tcp: orphaned queries failed to be re-sent");
-
- mlassert(conn->handle, "conn must have tcp handle when closing it");
- free(conn->handle);
- conn->handle = NULL;
- _output_dnssim_conn_maybe_free(conn);
-}
-
-static void _on_tcp_query_written(uv_write_t* wr_req, int status)
-{
- _output_dnssim_query_tcp_t* qry = (_output_dnssim_query_tcp_t*)wr_req->data;
- mlassert(qry, "qry/wr_req->data is nil");
- mlassert(qry->conn, "query must be associated with connection");
- _output_dnssim_connection_t* conn = qry->conn;
-
- free(((_output_dnssim_query_tcp_t*)qry)->bufs[0].base);
-
- if (qry->qry.state == _OUTPUT_DNSSIM_QUERY_PENDING_CLOSE) {
- qry->qry.state = status < 0 ? _OUTPUT_DNSSIM_QUERY_WRITE_FAILED : _OUTPUT_DNSSIM_QUERY_SENT;
- _output_dnssim_request_t* req = qry->qry.req;
- _output_dnssim_close_query_tcp(qry);
- _output_dnssim_maybe_free_request(req);
- qry = NULL;
- }
-
- if (status < 0) {
- if (status != UV_ECANCELED)
- mlinfo("tcp write failed: %s", uv_strerror(status));
- if (qry != NULL)
- qry->qry.state = _OUTPUT_DNSSIM_QUERY_WRITE_FAILED;
- _output_dnssim_conn_close(conn);
- return;
- }
-
- if (qry == NULL)
- return;
-
- /* Mark query as sent and assign it to connection. */
- mlassert(qry->qry.state == _OUTPUT_DNSSIM_QUERY_PENDING_WRITE_CB, "invalid query state");
- qry->qry.state = _OUTPUT_DNSSIM_QUERY_SENT;
- if (qry->conn->state == _OUTPUT_DNSSIM_CONN_ACTIVE) {
- mlassert(qry->conn->queued, "conn has no queued queries");
- _ll_remove(qry->conn->queued, &qry->qry);
- _ll_append(qry->conn->sent, &qry->qry);
- }
-}
-
-void _output_dnssim_tcp_write_query(_output_dnssim_connection_t* conn, _output_dnssim_query_tcp_t* qry)
-{
- mlassert(qry, "qry can't be null");
- mlassert(qry->qry.state == _OUTPUT_DNSSIM_QUERY_PENDING_WRITE, "qry must be pending write");
- mlassert(qry->qry.req, "req can't be null");
- mlassert(qry->qry.req->dns_q, "dns_q can't be null");
- mlassert(qry->qry.req->dns_q->obj_prev, "payload can't be null");
- mlassert(conn, "conn can't be null");
- mlassert(conn->state == _OUTPUT_DNSSIM_CONN_ACTIVE, "connection state != ACTIVE");
- mlassert(conn->client, "conn must be associated with client");
- mlassert(conn->client->pending, "conn has no pending queries");
-
- mldebug("tcp write dnsmsg id: %04x", qry->qry.req->dns_q->id);
-
- core_object_payload_t* payload = (core_object_payload_t*)qry->qry.req->dns_q->obj_prev;
- uint16_t* len;
- mlfatal_oom(len = malloc(sizeof(uint16_t)));
- *len = htons(payload->len);
- qry->bufs[0] = uv_buf_init((char*)len, 2);
- qry->bufs[1] = uv_buf_init((char*)payload->payload, payload->len);
-
- qry->conn = conn;
- _ll_remove(conn->client->pending, &qry->qry);
- _ll_append(conn->queued, &qry->qry);
-
- /* Stop idle timer, since there are queries to answer now. */
- if (conn->idle_timer != NULL) {
- conn->is_idle = false;
- uv_timer_stop(conn->idle_timer);
- }
-
- qry->write_req.data = (void*)qry;
- uv_write(&qry->write_req, (uv_stream_t*)conn->handle, qry->bufs, 2, _on_tcp_query_written);
- qry->qry.state = _OUTPUT_DNSSIM_QUERY_PENDING_WRITE_CB;
-}
-
-static void _on_tcp_read(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)handle->data;
- output_dnssim_t* self = conn->client->dnssim;
-
- if (nread > 0) {
- mldebug("tcp nread: %d", nread);
- switch (_self->transport) {
- case OUTPUT_DNSSIM_TRANSPORT_TCP:
- _output_dnssim_read_dns_stream(conn, nread, buf->base);
- break;
- case OUTPUT_DNSSIM_TRANSPORT_TLS:
- case OUTPUT_DNSSIM_TRANSPORT_HTTPS2:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- mlassert(conn->tls, "con must have tls ctx");
- conn->tls->buf = (uint8_t*)buf->base;
- conn->tls->buf_pos = 0;
- conn->tls->buf_len = nread;
- _output_dnssim_tls_process_input_data(conn);
-#else
- mlfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- default:
- mlfatal("unsupported transport");
- break;
- }
- } else if (nread < 0) {
- if (nread != UV_EOF)
- mlinfo("tcp conn unexpected close: %s", uv_strerror(nread));
- _output_dnssim_conn_close(conn);
- }
-
- if (buf->base != NULL)
- free(buf->base);
-}
-
-static void _on_tcp_connected(uv_connect_t* conn_req, int status)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)conn_req->handle->data;
- mlassert(conn, "conn is nil");
-
- free(conn_req);
-
- if (status < 0) {
- mldebug("tcp connect failed: %s", uv_strerror(status));
- _output_dnssim_conn_close(conn);
- return;
- }
-
- mlassert(conn->state == _OUTPUT_DNSSIM_CONN_TCP_HANDSHAKE, "connection state != TCP_HANDSHAKE");
- int ret = uv_read_start((uv_stream_t*)conn->handle, _output_dnssim_on_uv_alloc, _on_tcp_read);
- if (ret < 0) {
- mlwarning("tcp uv_read_start() failed: %s", uv_strerror(ret));
- _output_dnssim_conn_close(conn);
- return;
- }
-
- mldebug("tcp connected");
- mlassert(conn->client, "conn must be associated with a client");
- mlassert(conn->client->dnssim, "client must be associated with dnssim");
- output_dnssim_t* self = conn->client->dnssim;
- switch (_self->transport) {
- case OUTPUT_DNSSIM_TRANSPORT_TCP:
- _output_dnssim_conn_activate(conn);
- break;
- case OUTPUT_DNSSIM_TRANSPORT_TLS:
- case OUTPUT_DNSSIM_TRANSPORT_HTTPS2:
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
- mldebug("init tls handshake");
- _output_dnssim_tls_process_input_data(conn); /* Initiate TLS handshake. */
-#else
- mlfatal(DNSSIM_MIN_GNUTLS_ERRORMSG);
-#endif
- break;
- default:
- lfatal("unsupported transport protocol");
- break;
- }
-}
-
-static void _on_connection_timeout(uv_timer_t* handle)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)handle->data;
- _output_dnssim_conn_close(conn);
-}
-
-int _output_dnssim_tcp_connect(output_dnssim_t* self, _output_dnssim_connection_t* conn)
-{
- mlassert_self();
- lassert(conn, "connection can't be null");
- lassert(conn->handle == NULL, "connection already has a handle");
- lassert(conn->handshake_timer == NULL, "connection already has a handshake timer");
- lassert(conn->idle_timer == NULL, "connection already has idle timer");
- lassert(conn->state == _OUTPUT_DNSSIM_CONN_INITIALIZED, "connection state != INITIALIZED");
-
- lfatal_oom(conn->handle = malloc(sizeof(uv_tcp_t)));
- conn->handle->data = (void*)conn;
- int ret = uv_tcp_init(&_self->loop, conn->handle);
- if (ret < 0) {
- lwarning("failed to init uv_tcp_t");
- goto failure;
- }
-
- ret = _output_dnssim_bind_before_connect(self, (uv_handle_t*)conn->handle);
- if (ret < 0)
- goto failure;
-
- /* Set connection parameters. */
- ret = uv_tcp_nodelay(conn->handle, 1);
- if (ret < 0)
- lwarning("tcp: failed to set TCP_NODELAY: %s", uv_strerror(ret));
-
- /* Set connection handshake timeout. */
- lfatal_oom(conn->handshake_timer = malloc(sizeof(uv_timer_t)));
- uv_timer_init(&_self->loop, conn->handshake_timer);
- conn->handshake_timer->data = (void*)conn;
- uv_timer_start(conn->handshake_timer, _on_connection_timeout, self->handshake_timeout_ms, 0);
-
- /* Set idle connection timer. */
- if (self->idle_timeout_ms > 0) {
- lfatal_oom(conn->idle_timer = malloc(sizeof(uv_timer_t)));
- uv_timer_init(&_self->loop, conn->idle_timer);
- conn->idle_timer->data = (void*)conn;
-
- /* Start and stop the timer to set the repeat value without running the timer. */
- uv_timer_start(conn->idle_timer, _on_connection_timeout, self->idle_timeout_ms, self->idle_timeout_ms);
- uv_timer_stop(conn->idle_timer);
- }
-
- mldebug("tcp connecting");
- uv_connect_t* conn_req;
- lfatal_oom(conn_req = malloc(sizeof(uv_connect_t)));
- ret = uv_tcp_connect(conn_req, conn->handle, (struct sockaddr*)&_self->target, _on_tcp_connected);
- if (ret < 0)
- goto failure;
-
- conn->stats->conn_handshakes++;
- conn->client->dnssim->stats_sum->conn_handshakes++;
- conn->state = _OUTPUT_DNSSIM_CONN_TCP_HANDSHAKE;
- return 0;
-failure:
- _output_dnssim_conn_close(conn);
- return ret;
-}
-
-void _output_dnssim_tcp_close(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn can't be nil");
-
- if (conn->handle != NULL) {
- uv_read_stop((uv_stream_t*)conn->handle);
- uv_close((uv_handle_t*)conn->handle, _on_tcp_closed);
- }
-}
-
-int _output_dnssim_create_query_tcp(output_dnssim_t* self, _output_dnssim_request_t* req)
-{
- mlassert_self();
- lassert(req, "req is nil");
- lassert(req->client, "request must have a client associated with it");
-
- _output_dnssim_query_tcp_t* qry;
-
- lfatal_oom(qry = calloc(1, sizeof(_output_dnssim_query_tcp_t)));
-
- qry->qry.transport = OUTPUT_DNSSIM_TRANSPORT_TCP;
- qry->qry.req = req;
- qry->qry.state = _OUTPUT_DNSSIM_QUERY_PENDING_WRITE;
- req->qry = &qry->qry; // TODO change when adding support for multiple Qs for req
- _ll_append(req->client->pending, &qry->qry);
-
- return _output_dnssim_handle_pending_queries(req->client);
-}
-
-void _output_dnssim_close_query_tcp(_output_dnssim_query_tcp_t* qry)
-{
- mlassert(qry, "qry can't be null");
- mlassert(qry->qry.req, "query must be part of a request");
- _output_dnssim_request_t* req = qry->qry.req;
- mlassert(req->client, "request must belong to a client");
-
- if ((qry->qry.state == _OUTPUT_DNSSIM_QUERY_PENDING_WRITE_CB || qry->qry.state == _OUTPUT_DNSSIM_QUERY_PENDING_CLOSE)) {
- /* Query can't be freed until uv callback is called. */
- qry->qry.state = _OUTPUT_DNSSIM_QUERY_PENDING_CLOSE;
- return;
- }
-
- _ll_try_remove(req->client->pending, &qry->qry);
- if (qry->conn) {
- _output_dnssim_connection_t* conn = qry->conn;
- _ll_try_remove(conn->queued, &qry->qry); /* edge-case of cancelled queries */
- _ll_try_remove(conn->sent, &qry->qry);
- qry->conn = NULL;
- _output_dnssim_conn_idle(conn);
- }
-
- _ll_remove(req->qry, &qry->qry);
- free(qry);
-}
diff --git a/src/output/dnssim/tls.c b/src/output/dnssim/tls.c
deleted file mode 100644
index e87ca47..0000000
--- a/src/output/dnssim/tls.c
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (c) 2020, CZ.NIC, z.s.p.o.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "output/dnssim.h"
-#include "output/dnssim/internal.h"
-#include "output/dnssim/ll.h"
-#include "core/assert.h"
-
-#include <gnutls/gnutls.h>
-#include <string.h>
-
-#if GNUTLS_VERSION_NUMBER >= DNSSIM_MIN_GNUTLS_VERSION
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b)) /** Minimum of two numbers **/
-#endif
-
-static core_log_t _log = LOG_T_INIT("output.dnssim");
-
-struct async_write_ctx {
- uv_write_t write_req;
- _output_dnssim_connection_t* conn;
- char buf[];
-};
-
-static int _tls_handshake(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn is nil");
- mlassert(conn->tls, "conn must have tls context");
- mlassert(conn->client, "conn must belong to a client");
- mlassert(conn->state <= _OUTPUT_DNSSIM_CONN_TLS_HANDSHAKE, "conn in invalid state");
-
- /* Set TLS session resumption ticket if available. */
- if (conn->state < _OUTPUT_DNSSIM_CONN_TLS_HANDSHAKE && conn->client->tls_ticket.size != 0) {
- gnutls_datum_t* ticket = &conn->client->tls_ticket;
- gnutls_session_set_data(conn->tls->session, ticket->data, ticket->size);
- }
- conn->state = _OUTPUT_DNSSIM_CONN_TLS_HANDSHAKE;
-
- return gnutls_handshake(conn->tls->session);
-}
-
-void _output_dnssim_tls_process_input_data(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn is nil");
- mlassert(conn->client, "conn must have client");
- mlassert(conn->client->dnssim, "client must have dnssim");
- mlassert(conn->tls, "conn must have tls ctx");
-
- if (conn->state >= _OUTPUT_DNSSIM_CONN_CLOSING)
- return;
-
- output_dnssim_t* self = conn->client->dnssim;
-
- /* Ensure TLS handshake is performed before receiving data.
- * See https://www.gnutls.org/manual/html_node/TLS-handshake.html */
- while (conn->state <= _OUTPUT_DNSSIM_CONN_TLS_HANDSHAKE) {
- int err = _tls_handshake(conn);
- mldebug("tls handshake returned: %s", gnutls_strerror(err));
- if (err == GNUTLS_E_SUCCESS) {
- if (gnutls_session_is_resumed(conn->tls->session))
- conn->stats->conn_resumed++;
- if (_self->transport == OUTPUT_DNSSIM_TRANSPORT_HTTPS2) {
- if (_output_dnssim_https2_setup(conn) < 0) {
- _output_dnssim_conn_close(conn);
- return;
- }
- }
- _output_dnssim_conn_activate(conn);
- break;
- } else if (err == GNUTLS_E_AGAIN) {
- return; /* Wait for more data */
- } else if (err == GNUTLS_E_FATAL_ALERT_RECEIVED) {
- gnutls_alert_description_t alert = gnutls_alert_get(conn->tls->session);
- mlwarning("gnutls_handshake failed: %s", gnutls_alert_get_name(alert));
- _output_dnssim_conn_close(conn);
- return;
- } else if (gnutls_error_is_fatal(err)) {
- mlwarning("gnutls_handshake failed: %s", gnutls_strerror_name(err));
- _output_dnssim_conn_close(conn);
- return;
- }
- }
-
- /* See https://gnutls.org/manual/html_node/Data-transfer-and-termination.html#Data-transfer-and-termination */
- while (true) {
- /* Connection might have been closed due to an error, don't try to use it. */
- if (conn->state < _OUTPUT_DNSSIM_CONN_ACTIVE || conn->state >= _OUTPUT_DNSSIM_CONN_CLOSING)
- return;
-
- ssize_t count = gnutls_record_recv(conn->tls->session, _self->wire_buf, WIRE_BUF_SIZE);
- if (count > 0) {
- switch (_self->transport) {
- case OUTPUT_DNSSIM_TRANSPORT_TLS:
- _output_dnssim_read_dns_stream(conn, count, _self->wire_buf);
- break;
- case OUTPUT_DNSSIM_TRANSPORT_HTTPS2:
- _output_dnssim_https2_process_input_data(conn, count, _self->wire_buf);
- break;
- default:
- lfatal("unsupported transport layer");
- break;
- }
- } else if (count == GNUTLS_E_AGAIN) {
- if (conn->tls->buf_pos == conn->tls->buf_len) {
- /* See https://www.gnutls.org/manual/html_node/Asynchronous-operation.html */
- break; /* No more data available in this libuv buffer */
- }
- continue;
- } else if (count == GNUTLS_E_INTERRUPTED) {
- continue;
- } else if (count == GNUTLS_E_REHANDSHAKE) {
- continue; /* Ignore rehandshake request. */
- } else if (count < 0) {
- mlwarning("gnutls_record_recv failed: %s", gnutls_strerror_name(count));
- _output_dnssim_conn_close(conn);
- return;
- } else if (count == 0) {
- break;
- }
- }
- mlassert(conn->tls->buf_len == conn->tls->buf_pos, "tls didn't read the entire buffer");
-}
-
-static ssize_t _tls_pull(gnutls_transport_ptr_t ptr, void* buf, size_t len)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)ptr;
- mlassert(conn != NULL, "conn is null");
- mlassert(conn->tls != NULL, "conn must have tls ctx");
-
- ssize_t avail = conn->tls->buf_len - conn->tls->buf_pos;
- if (avail <= 0) {
- mldebug("tls pull: no more data");
- errno = EAGAIN;
- return -1;
- }
-
- ssize_t transfer = MIN(avail, len);
- memcpy(buf, conn->tls->buf + conn->tls->buf_pos, transfer);
- conn->tls->buf_pos += transfer;
- return transfer;
-}
-
-static void _tls_on_write_complete(uv_write_t* req, int status)
-{
- mlassert(req->data != NULL, "uv_write req has no data pointer");
- struct async_write_ctx* async_ctx = (struct async_write_ctx*)req->data;
- _output_dnssim_connection_t* conn = async_ctx->conn;
- mlassert(conn, "conn is nil");
- mlassert(conn->tls, "conn must have tls ctx");
- mlassert(conn->tls->write_queue_size > 0, "invalid write_queue_size: %d", conn->tls->write_queue_size);
- conn->tls->write_queue_size -= 1;
- free(req->data);
-
- if (status < 0)
- _output_dnssim_conn_close(conn);
-}
-
-static ssize_t _tls_vec_push(gnutls_transport_ptr_t ptr, const giovec_t* iov, int iovcnt)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)ptr;
- mlassert(conn != NULL, "conn is null");
- mlassert(conn->tls != NULL, "conn must have tls ctx");
-
- if (iovcnt == 0)
- return 0;
-
- /*
- * This is a little bit complicated. There are two different writes:
- * 1. Immediate, these don't need to own the buffered data and return immediately
- * 2. Asynchronous, these need to own the buffers until the write completes
- * In order to avoid copying the buffer, an immediate write is tried first if possible.
- * If it isn't possible to write the data without queueing, an asynchronous write
- * is created (with copied buffered data).
- */
-
- size_t total_len = 0;
- uv_buf_t uv_buf[iovcnt];
- int i;
- for (i = 0; i < iovcnt; ++i) {
- uv_buf[i].base = iov[i].iov_base;
- uv_buf[i].len = iov[i].iov_len;
- total_len += iov[i].iov_len;
- }
-
- /* Try to perform the immediate write first to avoid copy */
- int ret = 0;
- if (conn->tls->write_queue_size == 0) {
- ret = uv_try_write((uv_stream_t*)conn->handle, uv_buf, iovcnt);
- /* from libuv documentation -
- uv_try_write will return either:
- > 0: number of bytes written (can be less than the supplied buffer size).
- < 0: negative error code (UV_EAGAIN is returned if no data can be sent immediately).
- */
- if (ret == total_len) {
- /* All the data were buffered by libuv.
- * Return. */
- return ret;
- }
-
- if (ret < 0 && ret != UV_EAGAIN) {
- /* uv_try_write() has returned error code other then UV_EAGAIN.
- * Return. */
- errno = EIO;
- return -1;
- }
- /* Since we are here expression below is true
- * (ret != total_len) && (ret >= 0 || ret == UV_EAGAIN)
- * or the same
- * (ret != total_len && ret >= 0) || (ret != total_len && ret == UV_EAGAIN)
- * i.e. either occurs partial write or UV_EAGAIN.
- * Proceed and copy data amount to owned memory and perform async write.
- */
- if (ret == UV_EAGAIN) {
- /* No data were buffered, so we must buffer all the data. */
- ret = 0;
- }
- }
-
- /* Fallback when the queue is full, and it's not possible to do an immediate write */
- char* p = malloc(sizeof(struct async_write_ctx) + total_len - ret);
- if (p != NULL) {
- struct async_write_ctx* async_ctx = (struct async_write_ctx*)p;
- async_ctx->conn = conn;
- char* buf = async_ctx->buf;
- /* Skip data written in the partial write */
- size_t to_skip = ret;
- /* Copy the buffer into owned memory */
- size_t off = 0;
- int i;
- for (i = 0; i < iovcnt; ++i) {
- if (to_skip > 0) {
- /* Ignore current buffer if it's all skipped */
- if (to_skip >= uv_buf[i].len) {
- to_skip -= uv_buf[i].len;
- continue;
- }
- /* Skip only part of the buffer */
- uv_buf[i].base += to_skip;
- uv_buf[i].len -= to_skip;
- to_skip = 0;
- }
- memcpy(buf + off, uv_buf[i].base, uv_buf[i].len);
- off += uv_buf[i].len;
- }
- uv_buf[0].base = buf;
- uv_buf[0].len = off;
-
- /* Create an asynchronous write request */
- uv_write_t* write_req = &async_ctx->write_req;
- memset(write_req, 0, sizeof(uv_write_t));
- write_req->data = p;
-
- /* Perform an asynchronous write with a callback */
- if (uv_write(write_req, (uv_stream_t*)conn->handle, uv_buf, 1, _tls_on_write_complete) == 0) {
- ret = total_len;
- conn->tls->write_queue_size += 1;
- } else {
- free(p);
- errno = EIO;
- ret = -1;
- }
- } else {
- errno = ENOMEM;
- ret = -1;
- }
-
- return ret;
-}
-
-int _tls_pull_timeout(gnutls_transport_ptr_t ptr, unsigned int ms)
-{
- _output_dnssim_connection_t* conn = (_output_dnssim_connection_t*)ptr;
- mlassert(conn != NULL, "conn is null");
- mlassert(conn->tls != NULL, "conn must have tls ctx");
-
- ssize_t avail = conn->tls->buf_len - conn->tls->buf_pos;
- if (avail <= 0) {
- errno = EAGAIN;
- return -1;
- }
- return avail;
-}
-
-int _output_dnssim_tls_init(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn is nil");
- mlassert(conn->tls == NULL, "conn already has tls context");
-
- int ret;
- mlfatal_oom(conn->tls = malloc(sizeof(_output_dnssim_tls_ctx_t)));
- conn->tls->buf = NULL;
- conn->tls->buf_len = 0;
- conn->tls->buf_pos = 0;
- conn->tls->write_queue_size = 0;
-
- ret = gnutls_init(&conn->tls->session, GNUTLS_CLIENT | GNUTLS_NONBLOCK);
- if (ret < 0) {
- mldebug("failed gnutls_init() (%s)", gnutls_strerror(ret));
- free(conn->tls);
- conn->tls = 0;
- return ret;
- }
-
- output_dnssim_t* self = conn->client->dnssim;
- if (_self->tls_priority == NULL) {
- ret = gnutls_set_default_priority(conn->tls->session);
- if (ret < 0) {
- mldebug("failed gnutls_set_default_priority() (%s)", gnutls_strerror(ret));
- gnutls_deinit(conn->tls->session);
- free(conn->tls);
- conn->tls = 0;
- return ret;
- }
- } else {
- ret = gnutls_priority_set(conn->tls->session, *_self->tls_priority);
- if (ret < 0) {
- mldebug("failed gnutls_priority_set() (%s)", gnutls_strerror(ret));
- gnutls_deinit(conn->tls->session);
- free(conn->tls);
- conn->tls = 0;
- return ret;
- }
- }
-
- ret = gnutls_credentials_set(conn->tls->session, GNUTLS_CRD_CERTIFICATE, _self->tls_cred);
- if (ret < 0) {
- mldebug("failed gnutls_credentials_set() (%s)", gnutls_strerror(ret));
- gnutls_deinit(conn->tls->session);
- free(conn->tls);
- conn->tls = 0;
- return ret;
- }
-
- gnutls_transport_set_pull_function(conn->tls->session, _tls_pull);
- gnutls_transport_set_pull_timeout_function(conn->tls->session, _tls_pull_timeout);
- gnutls_transport_set_vec_push_function(conn->tls->session, _tls_vec_push);
- gnutls_transport_set_ptr(conn->tls->session, conn);
-
- return 0;
-}
-
-int _output_dnssim_create_query_tls(output_dnssim_t* self, _output_dnssim_request_t* req)
-{
- mlassert_self();
- lassert(req, "req is nil");
- lassert(req->client, "request must have a client associated with it");
-
- _output_dnssim_query_tcp_t* qry;
-
- lfatal_oom(qry = calloc(1, sizeof(_output_dnssim_query_tcp_t)));
-
- qry->qry.transport = OUTPUT_DNSSIM_TRANSPORT_TLS;
- qry->qry.req = req;
- qry->qry.state = _OUTPUT_DNSSIM_QUERY_PENDING_WRITE;
- req->qry = &qry->qry; // TODO change when adding support for multiple Qs for req
- _ll_append(req->client->pending, &qry->qry);
-
- return _output_dnssim_handle_pending_queries(req->client);
-}
-
-void _output_dnssim_close_query_tls(_output_dnssim_query_tcp_t* qry)
-{
- mlassert(qry, "qry can't be null");
- mlassert(qry->qry.req, "query must be part of a request");
- _output_dnssim_request_t* req = qry->qry.req;
- mlassert(req->client, "request must belong to a client");
-
- _ll_try_remove(req->client->pending, &qry->qry);
- if (qry->conn) {
- _output_dnssim_connection_t* conn = qry->conn;
- _ll_try_remove(conn->sent, &qry->qry);
- qry->conn = NULL;
- _output_dnssim_conn_idle(conn);
- }
-
- _ll_remove(req->qry, &qry->qry);
- free(qry);
-}
-
-void _output_dnssim_tls_close(_output_dnssim_connection_t* conn)
-{
- mlassert(conn, "conn can't be nil");
- mlassert(conn->tls, "conn must have tls ctx");
- mlassert(conn->client, "conn must belong to a client");
-
- /* Try and get a TLS session ticket for potential resumption. */
- int ret;
- if (gnutls_session_get_flags(conn->tls->session) & GNUTLS_SFLAGS_SESSION_TICKET) {
- if (conn->client->tls_ticket.size != 0) {
- gnutls_free(conn->client->tls_ticket.data);
- }
- ret = gnutls_session_get_data2(conn->tls->session, &conn->client->tls_ticket);
- if (ret < 0) {
- mldebug("gnutls_session_get_data2 failed: %s", gnutls_strerror(ret));
- conn->client->tls_ticket.size = 0;
- }
- }
-
- gnutls_deinit(conn->tls->session);
- _output_dnssim_tcp_close(conn);
-}
-
-void _output_dnssim_tls_write_query(_output_dnssim_connection_t* conn, _output_dnssim_query_tcp_t* qry)
-{
- mlassert(qry, "qry can't be null");
- mlassert(qry->qry.state == _OUTPUT_DNSSIM_QUERY_PENDING_WRITE, "qry must be pending write");
- mlassert(qry->qry.req, "req can't be null");
- mlassert(qry->qry.req->dns_q, "dns_q can't be null");
- mlassert(qry->qry.req->dns_q->obj_prev, "payload can't be null");
- mlassert(conn, "conn can't be null");
- mlassert(conn->state == _OUTPUT_DNSSIM_CONN_ACTIVE, "connection state != ACTIVE");
- mlassert(conn->tls, "conn must have tls ctx");
- mlassert(conn->client, "conn must be associated with client");
- mlassert(conn->client->pending, "conn has no pending queries");
-
- core_object_payload_t* payload = (core_object_payload_t*)qry->qry.req->dns_q->obj_prev;
- uint16_t len = htons(payload->len);
-
- gnutls_record_cork(conn->tls->session);
- ssize_t count = 0;
- if ((count = gnutls_record_send(conn->tls->session, &len, sizeof(len)) < 0) || (count = gnutls_record_send(conn->tls->session, payload->payload, payload->len) < 0)) {
- mlwarning("gnutls_record_send failed: %s", gnutls_strerror_name(count));
- _output_dnssim_conn_close(conn);
- return;
- }
-
- const ssize_t submitted = sizeof(len) + payload->len;
-
- int ret = gnutls_record_uncork(conn->tls->session, GNUTLS_RECORD_WAIT);
- if (gnutls_error_is_fatal(ret)) {
- mlinfo("gnutls_record_uncorck failed: %s", gnutls_strerror_name(ret));
- _output_dnssim_conn_close(conn);
- return;
- }
-
- if (ret != submitted) {
- mlwarning("gnutls_record_uncork didn't send all data");
- _output_dnssim_conn_close(conn);
- return;
- }
-
- qry->conn = conn;
- _ll_remove(conn->client->pending, &qry->qry);
- _ll_append(conn->sent, &qry->qry);
-
- /* Stop idle timer, since there are queries to answer now. */
- if (conn->idle_timer != NULL) {
- conn->is_idle = false;
- uv_timer_stop(conn->idle_timer);
- }
-
- qry->qry.state = _OUTPUT_DNSSIM_QUERY_SENT;
-}
-
-#endif
diff --git a/src/output/dnssim/udp.c b/src/output/dnssim/udp.c
deleted file mode 100644
index 74f8569..0000000
--- a/src/output/dnssim/udp.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2019-2020, CZ.NIC, z.s.p.o.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "output/dnssim.h"
-#include "output/dnssim/internal.h"
-#include "output/dnssim/ll.h"
-#include "core/assert.h"
-
-static core_log_t _log = LOG_T_INIT("output.dnssim");
-
-static int _process_udp_response(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf)
-{
- _output_dnssim_query_udp_t* qry = (_output_dnssim_query_udp_t*)handle->data;
- _output_dnssim_request_t* req;
- core_object_payload_t payload = CORE_OBJECT_PAYLOAD_INIT(NULL);
- core_object_dns_t dns_a = CORE_OBJECT_DNS_INIT(&payload);
- mlassert(qry, "qry is nil");
- mlassert(qry->qry.req, "query must be part of a request");
- req = qry->qry.req;
-
- payload.payload = (uint8_t*)buf->base;
- payload.len = nread;
-
- dns_a.obj_prev = (core_object_t*)&payload;
- int ret = core_object_dns_parse_header(&dns_a);
- if (ret != 0) {
- mldebug("udp response malformed");
- return _ERR_MALFORMED;
- }
- if (dns_a.id != req->dns_q->id) {
- mldebug("udp response msgid mismatch %x(q) != %x(a)", req->dns_q->id, dns_a.id);
- return _ERR_MSGID;
- }
- if (dns_a.tc == 1) {
- mldebug("udp response has TC=1");
- return _ERR_TC;
- }
- ret = _output_dnssim_answers_request(req, &dns_a);
- if (ret != 0) {
- mlwarning("udp reponse question mismatch");
- return _ERR_QUESTION;
- }
-
- _output_dnssim_request_answered(req, &dns_a);
- return 0;
-}
-
-static void _on_udp_query_recv(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags)
-{
- if (nread > 0) {
- mldebug("udp recv: %d", nread);
-
- // TODO handle TC=1
- _process_udp_response(handle, nread, buf);
- }
-
- if (buf->base != NULL) {
- free(buf->base);
- }
-}
-
-static void _on_query_udp_closed(uv_handle_t* handle)
-{
- _output_dnssim_query_udp_t* qry = (_output_dnssim_query_udp_t*)handle->data;
- _output_dnssim_request_t* req;
- mlassert(qry, "qry is nil");
- mlassert(qry->qry.req, "query must be part of a request");
- req = qry->qry.req;
-
- free(qry->handle);
-
- _ll_remove(req->qry, &qry->qry);
- free(qry);
-
- if (req->qry == NULL)
- _output_dnssim_maybe_free_request(req);
-}
-
-void _output_dnssim_close_query_udp(_output_dnssim_query_udp_t* qry)
-{
- int ret;
- mlassert(qry, "qry is nil");
-
- ret = uv_udp_recv_stop(qry->handle);
- if (ret < 0) {
- mldebug("failed uv_udp_recv_stop(): %s", uv_strerror(ret));
- }
-
- uv_close((uv_handle_t*)qry->handle, _on_query_udp_closed);
-}
-
-int _output_dnssim_create_query_udp(output_dnssim_t* self, _output_dnssim_request_t* req)
-{
- int ret;
- _output_dnssim_query_udp_t* qry;
- core_object_payload_t* payload;
- mlassert_self();
- lassert(req, "req is nil");
- payload = (core_object_payload_t*)req->dns_q->obj_prev;
-
- lfatal_oom(qry = calloc(1, sizeof(_output_dnssim_query_udp_t)));
- lfatal_oom(qry->handle = malloc(sizeof(uv_udp_t)));
-
- qry->qry.transport = OUTPUT_DNSSIM_TRANSPORT_UDP;
- qry->qry.req = req;
- qry->buf = uv_buf_init((char*)payload->payload, payload->len);
- qry->handle->data = (void*)qry;
- ret = uv_udp_init(&_self->loop, qry->handle);
- if (ret < 0) {
- lwarning("failed to init uv_udp_t");
- goto failure;
- }
- _ll_append(req->qry, &qry->qry);
-
- ret = _output_dnssim_bind_before_connect(self, (uv_handle_t*)qry->handle);
- if (ret < 0)
- return ret;
-
- ret = uv_udp_try_send(qry->handle, &qry->buf, 1, (struct sockaddr*)&_self->target);
- if (ret < 0) {
- lwarning("failed to send udp packet: %s", uv_strerror(ret));
- return ret;
- }
-
- // listen for reply
- ret = uv_udp_recv_start(qry->handle, _output_dnssim_on_uv_alloc, _on_udp_query_recv);
- if (ret < 0) {
- lwarning("failed uv_udp_recv_start(): %s", uv_strerror(ret));
- return ret;
- }
-
- return 0;
-failure:
- free(qry->handle);
- free(qry);
- return ret;
-}
diff --git a/src/output/null.c b/src/output/null.c
deleted file mode 100644
index 9360afd..0000000
--- a/src/output/null.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2018-2021, OARC, Inc.
- * All rights reserved.
- *
- * This file is part of dnsjit.
- *
- * dnsjit 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.
- *
- * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-
-#include "output/null.h"
-#include "core/assert.h"
-#include "core/object/pcap.h"
-
-static core_log_t _log = LOG_T_INIT("output.null");
-static output_null_t _defaults = {
- LOG_T_INIT_OBJ("output.null"),
- 0, 0, 0
-};
-
-core_log_t* output_null_log()
-{
- return &_log;
-}
-
-void output_null_init(output_null_t* self)
-{
- mlassert_self();
-
- *self = _defaults;
-}
-
-void output_null_destroy(output_null_t* self)
-{
- mlassert_self();
-}
-
-static void _receive(output_null_t* self, const core_object_t* obj)
-{
- mlassert_self();
-
- self->pkts++;
-}
-
-core_receiver_t output_null_receiver()
-{
- return (core_receiver_t)_receive;
-}
-
-void output_null_run(output_null_t* self, int64_t num)
-{
- mlassert_self();
-
- if (!self->prod) {
- lfatal("no producer set");
- }
-
- if (num > 0) {
- while (num--) {
- const core_object_t* obj = self->prod(self->ctx);
- if (!obj)
- break;
-
- self->pkts++;
- }
- } else {
- for (;;) {
- const core_object_t* obj = self->prod(self->ctx);
- if (!obj)
- break;
-
- self->pkts++;
- }
- }
-}
diff --git a/src/output/null.lua b/src/output/null.lua
index b634c56..b0e167f 100644
--- a/src/output/null.lua
+++ b/src/output/null.lua
@@ -17,64 +17,15 @@
-- along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
-- dnsjit.output.null
--- Output to nothing (/dev/null)
--- local output = require("dnsjit.output.null").new()
+-- Dummy layer to example.output.null
--
--- Output module for those that doesn't really like packets.
+-- This module has moved to example.output.null, see examples/modules/output-example in
+-- dnsjit source repository.
module(...,package.seeall)
-require("dnsjit.output.null_h")
-local ffi = require("ffi")
-local C = ffi.C
-
-local t_name = "output_null_t"
-local output_null_t = ffi.typeof(t_name)
-local Null = {}
-
--- Create a new Null output.
-function Null.new()
- local self = {
- _producer = nil,
- obj = output_null_t(),
- }
- C.output_null_init(self.obj)
- ffi.gc(self.obj, C.output_null_destroy)
- return setmetatable(self, { __index = Null })
-end
-
--- Return the Log object to control logging of this instance or module.
-function Null:log()
- if self == nil then
- return C.output_null_log()
- end
- return self.obj._log
-end
-
--- Return the C functions and context for receiving objects.
-function Null:receive()
- return C.output_null_receiver(), self.obj
-end
-
--- Set the producer to get objects from.
-function Null:producer(o)
- self.obj.prod, self.obj.ctx = o:produce()
- self._producer = o
-end
-
--- Retrieve all objects from the producer, if the optional
--- .I num
--- is a positive number then stop after that amount of objects have been
--- retrieved.
-function Null:run(num)
- if num == nil then
- num = -1
- end
- C.output_null_run(self.obj, num)
-end
-
--- Return the number of packets we sent into the void.
-function Null:packets()
- return tonumber(self.obj.pkts)
+ok, cls = pcall(require, "example.output.null")
+if not ok then
+ error("You need to install the example module output-example\n" .. cls)
end
-return Null
+return cls
diff --git a/src/output/pcap.c b/src/output/pcap.c
index 2b2aaa8..ede9881 100644
--- a/src/output/pcap.c
+++ b/src/output/pcap.c
@@ -82,6 +82,15 @@ void output_pcap_close(output_pcap_t* self)
}
}
+int output_pcap_have_errors(output_pcap_t* self)
+{
+ mlassert_self();
+ if (self->dumper) {
+ return ferror(pcap_dump_file(self->dumper));
+ }
+ return 0;
+}
+
static void _receive(output_pcap_t* self, const core_object_t* obj)
{
struct pcap_pkthdr hdr;
diff --git a/src/output/pcap.h b/src/output/pcap.h
index fccf58d..40146c2 100644
--- a/src/output/pcap.h
+++ b/src/output/pcap.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
#ifndef __dnsjit_output_pcap_h
#define __dnsjit_output_pcap_h
#include <pcap/pcap.h>
-#include "output/pcap.hh"
+#include <dnsjit/output/pcap.hh>
#endif
diff --git a/src/output/pcap.hh b/src/output/pcap.hh
index 45f5150..6205333 100644
--- a/src/output/pcap.hh
+++ b/src/output/pcap.hh
@@ -37,5 +37,6 @@ void output_pcap_init(output_pcap_t* self);
void output_pcap_destroy(output_pcap_t* self);
int output_pcap_open(output_pcap_t* self, const char* file, int linktype, int snaplen);
void output_pcap_close(output_pcap_t* self);
+int output_pcap_have_errors(output_pcap_t* self);
core_receiver_t output_pcap_receiver(output_pcap_t* self);
diff --git a/src/output/pcap.lua b/src/output/pcap.lua
index 13f0c29..26ae8e7 100644
--- a/src/output/pcap.lua
+++ b/src/output/pcap.lua
@@ -60,6 +60,10 @@ end
-- .I linktype
-- and
-- .IR snaplen .
+-- Uses
+-- .B pcap_dump_open()
+-- so you can pass "-" to it to open stdout, see it's man-page for more
+-- information.
-- Returns 0 on success.
function Pcap:open(file, linktype, snaplen)
return C.output_pcap_open(self.obj, file, linktype, snaplen)
@@ -70,6 +74,16 @@ function Pcap:close()
C.output_pcap_close(self.obj)
end
+-- Return true if the underlying
+-- .I FILE*
+-- indicates that there's been an error.
+function Pcap:have_errors()
+ if C.output_pcap_have_errors(self.obj) == 0 then
+ return false
+ end
+ return true
+end
+
-- Return the C functions and context for receiving objects.
function Pcap:receive()
return C.output_pcap_receiver(self.obj), self.obj
diff --git a/src/output/respdiff.h b/src/output/respdiff.h
index f375006..207e225 100644
--- a/src/output/respdiff.h
+++ b/src/output/respdiff.h
@@ -18,14 +18,14 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
#ifndef __dnsjit_output_respdiff_h
#define __dnsjit_output_respdiff_h
#include <stdint.h>
-#include "output/respdiff.hh"
+#include <dnsjit/output/respdiff.hh>
#endif
diff --git a/src/output/tcpcli.h b/src/output/tcpcli.h
index 6eb80f3..83b7ea4 100644
--- a/src/output/tcpcli.h
+++ b/src/output/tcpcli.h
@@ -18,15 +18,15 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
-#include "core/object/payload.h"
-#include "core/timespec.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
+#include <dnsjit/core/object/payload.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_output_tcpcli_h
#define __dnsjit_output_tcpcli_h
-#include "output/tcpcli.hh"
+#include <dnsjit/output/tcpcli.hh>
#endif
diff --git a/src/output/tlscli.h b/src/output/tlscli.h
index 2bdf69f..72e7b9d 100644
--- a/src/output/tlscli.h
+++ b/src/output/tlscli.h
@@ -18,17 +18,17 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
-#include "core/object/payload.h"
-#include "core/timespec.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
+#include <dnsjit/core/object/payload.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_output_tlscli_h
#define __dnsjit_output_tlscli_h
#include <gnutls/gnutls.h>
-#include "output/tlscli.hh"
+#include <dnsjit/output/tlscli.hh>
#endif
diff --git a/src/output/udpcli.h b/src/output/udpcli.h
index 4cb7af2..f783642 100644
--- a/src/output/udpcli.h
+++ b/src/output/udpcli.h
@@ -18,11 +18,11 @@
* along with dnsjit. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "core/log.h"
-#include "core/receiver.h"
-#include "core/producer.h"
-#include "core/object/payload.h"
-#include "core/timespec.h"
+#include <dnsjit/core/log.h>
+#include <dnsjit/core/receiver.h>
+#include <dnsjit/core/producer.h>
+#include <dnsjit/core/object/payload.h>
+#include <dnsjit/core/timespec.h>
#ifndef __dnsjit_output_udpcli_h
#define __dnsjit_output_udpcli_h
@@ -30,6 +30,6 @@
#include <sys/types.h>
#include <sys/socket.h>
-#include "output/udpcli.hh"
+#include <dnsjit/output/udpcli.hh>
#endif
diff --git a/src/test/Makefile.am b/src/test/Makefile.am
index 09a3c41..0556db6 100644
--- a/src/test/Makefile.am
+++ b/src/test/Makefile.am
@@ -18,12 +18,12 @@
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
CLEANFILES = test*.log test*.trs test*.out \
- *.pcap-dist
+ *.pcap-dist *.lz4-dist *.zst-dist
-TESTS = test1.sh test2.sh test3.sh test4.sh test5.sh test6.sh test-ipsplit.sh \
+TESTS = test1.sh test2.sh test3.sh test4.sh test6.sh test-ipsplit.sh \
test-trie.sh test-base64url.sh
-test1.sh: dns.pcap-dist
+test1.sh: dns.pcap-dist dns.pcap.lz4-dist dns.pcap.zst-dist
test2.sh: dns.pcap-dist
@@ -31,8 +31,6 @@ test3.sh: dns.pcap-dist
test4.sh: dns.pcap-dist
-test5.sh: dns.pcap-dist
-
test6.sh: dns.pcap-dist
test-ipsplit.sh: pellets.pcap-dist dns.pcap-dist
@@ -42,6 +40,13 @@ test-trie.sh: pellets.pcap-dist dns.pcap-dist
.pcap.pcap-dist:
cp "$<" "$@"
+.lz4.lz4-dist:
+ cp "$<" "$@"
+
+.zst.zst-dist:
+ cp "$<" "$@"
+
EXTRA_DIST = $(TESTS) \
dns.pcap pellets.pcap test_ipsplit.lua test_trie.lua test_base64url.lua \
- test1.gold test2.gold test3.gold test4.gold
+ test1.gold test2.gold test3.gold test4.gold test_compressupport.lua \
+ dns.pcap.lz4 dns.pcap.zst
diff --git a/src/test/Makefile.in b/src/test/Makefile.in
new file mode 100644
index 0000000..b03a826
--- /dev/null
+++ b/src/test/Makefile.in
@@ -0,0 +1,947 @@
+# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (c) 2018-2021, OARC, Inc.
+# All rights reserved.
+#
+# This file is part of dnsjit.
+#
+# dnsjit 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.
+#
+# dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/test
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cflags_warn_all.m4 \
+ $(top_srcdir)/m4/ax_check_compile_flag.m4 \
+ $(top_srcdir)/m4/ax_compiler_vendor.m4 \
+ $(top_srcdir)/m4/ax_ext.m4 \
+ $(top_srcdir)/m4/ax_gcc_x86_avx_xgetbv.m4 \
+ $(top_srcdir)/m4/ax_gcc_x86_cpuid.m4 \
+ $(top_srcdir)/m4/ax_prepend_flag.m4 \
+ $(top_srcdir)/m4/ax_pthread.m4 \
+ $(top_srcdir)/m4/ax_require_defined.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/src/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__extra_recursive_targets = gcov-recursive
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPUEXT_FLAGS = @CPUEXT_FLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+LUAJIT = @LUAJIT@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PTHREAD_CC = @PTHREAD_CC@
+PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIMD_FLAGS = @SIMD_FLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+ax_pthread_config = @ax_pthread_config@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+ck_CFLAGS = @ck_CFLAGS@
+ck_LIBS = @ck_LIBS@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+liblz4_CFLAGS = @liblz4_CFLAGS@
+liblz4_LIBS = @liblz4_LIBS@
+libzstd_CFLAGS = @libzstd_CFLAGS@
+libzstd_LIBS = @libzstd_LIBS@
+localedir = @localedir@
+localstatedir = @localstatedir@
+luajit_CFLAGS = @luajit_CFLAGS@
+luajit_LIBS = @luajit_LIBS@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+runstatedir = @runstatedir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+CLEANFILES = test*.log test*.trs test*.out \
+ *.pcap-dist *.lz4-dist *.zst-dist
+
+TESTS = test1.sh test2.sh test3.sh test4.sh test6.sh test-ipsplit.sh \
+ test-trie.sh test-base64url.sh
+
+EXTRA_DIST = $(TESTS) \
+ dns.pcap pellets.pcap test_ipsplit.lua test_trie.lua test_base64url.lua \
+ test1.gold test2.gold test3.gold test4.gold test_compressupport.lua \
+ dns.pcap.lz4 dns.pcap.zst
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .log .lz4 .lz4-dist .pcap .pcap-dist .test .test$(EXEEXT) .trs .zst .zst-dist
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/test/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/test/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+gcov-local:
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS:
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+test1.sh.log: test1.sh
+ @p='test1.sh'; \
+ b='test1.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)
+test2.sh.log: test2.sh
+ @p='test2.sh'; \
+ b='test2.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)
+test3.sh.log: test3.sh
+ @p='test3.sh'; \
+ b='test3.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)
+test4.sh.log: test4.sh
+ @p='test4.sh'; \
+ b='test4.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)
+test6.sh.log: test6.sh
+ @p='test6.sh'; \
+ b='test6.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-ipsplit.sh.log: test-ipsplit.sh
+ @p='test-ipsplit.sh'; \
+ b='test-ipsplit.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-trie.sh.log: test-trie.sh
+ @p='test-trie.sh'; \
+ b='test-trie.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-base64url.sh.log: test-base64url.sh
+ @p='test-base64url.sh'; \
+ b='test-base64url.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); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+gcov: gcov-am
+
+gcov-am: gcov-local
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-TESTS check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags-am distclean \
+ distclean-generic distclean-libtool distdir dvi dvi-am gcov-am \
+ gcov-local html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \
+ uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+test1.sh: dns.pcap-dist dns.pcap.lz4-dist dns.pcap.zst-dist
+
+test2.sh: dns.pcap-dist
+
+test3.sh: dns.pcap-dist
+
+test4.sh: dns.pcap-dist
+
+test6.sh: dns.pcap-dist
+
+test-ipsplit.sh: pellets.pcap-dist dns.pcap-dist
+
+test-trie.sh: pellets.pcap-dist dns.pcap-dist
+
+.pcap.pcap-dist:
+ cp "$<" "$@"
+
+.lz4.lz4-dist:
+ cp "$<" "$@"
+
+.zst.zst-dist:
+ cp "$<" "$@"
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/test/dns.pcap.lz4 b/src/test/dns.pcap.lz4
new file mode 100644
index 0000000..d042863
--- /dev/null
+++ b/src/test/dns.pcap.lz4
Binary files differ
diff --git a/src/test/dns.pcap.zst b/src/test/dns.pcap.zst
new file mode 100644
index 0000000..07b43c0
--- /dev/null
+++ b/src/test/dns.pcap.zst
Binary files differ
diff --git a/src/test/test1.sh b/src/test/test1.sh
index 42bc635..1af3a21 100755
--- a/src/test/test1.sh
+++ b/src/test/test1.sh
@@ -19,3 +19,13 @@
../dnsjit "$srcdir/../../examples/dumpdns.lua" dns.pcap-dist >test1.out
diff "$srcdir/test1.gold" test1.out
+
+support=`../dnsjit "$srcdir/test_compressupport.lua"`
+if echo "$support"|grep -q lz4; then
+ ../dnsjit "$srcdir/../../examples/dumpdns.lua" dns.pcap.lz4-dist lz4 >test1.out
+ diff "$srcdir/test1.gold" test1.out
+fi
+if echo "$support"|grep -q zstd; then
+ ../dnsjit "$srcdir/../../examples/dumpdns.lua" dns.pcap.zst-dist zstd >test1.out
+ diff "$srcdir/test1.gold" test1.out
+fi
diff --git a/src/test/test_compressupport.lua b/src/test/test_compressupport.lua
new file mode 100644
index 0000000..9d4502e
--- /dev/null
+++ b/src/test/test_compressupport.lua
@@ -0,0 +1,10 @@
+local zpcap = require("dnsjit.input.zpcap").new()
+
+zpcap:lz4()
+if zpcap:have_support() then
+ print("lz4")
+end
+zpcap:zstd()
+if zpcap:have_support() then
+ print("zstd")
+end
diff --git a/src/version.h b/src/version.h
new file mode 100644
index 0000000..c53bdf3
--- /dev/null
+++ b/src/version.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018-2021, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of dnsjit.
+ *
+ * dnsjit 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.
+ *
+ * dnsjit 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 dnsjit. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __dnsjit_version_h
+#define __dnsjit_version_h
+
+#define DNSJIT_MAJOR_VERSION 1
+#define DNSJIT_MINOR_VERSION 2
+#define DNSJIT_PATCH_VERSION 1
+
+#endif