summaryrefslogtreecommitdiffstats
path: root/src/dnswire
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2022-01-14 15:03:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2022-01-14 15:03:48 +0000
commitbe956cd27353a4bb585b1a648e8469cf7adb5edf (patch)
treea473793c3fd59ace461f23a8d75d9ca29a82b4ff /src/dnswire
parentInitial commit. (diff)
downloaddnswire-be956cd27353a4bb585b1a648e8469cf7adb5edf.tar.xz
dnswire-be956cd27353a4bb585b1a648e8469cf7adb5edf.zip
Adding upstream version 0.2.0.upstream/0.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/dnswire')
-rw-r--r--src/dnswire/decoder.h64
-rw-r--r--src/dnswire/dnstap.h151
-rw-r--r--src/dnswire/dnswire.h39
-rw-r--r--src/dnswire/encoder.h60
-rw-r--r--src/dnswire/reader.h91
-rw-r--r--src/dnswire/trace.h.in41
-rw-r--r--src/dnswire/version.h.in33
-rw-r--r--src/dnswire/writer.h90
8 files changed, 569 insertions, 0 deletions
diff --git a/src/dnswire/decoder.h b/src/dnswire/decoder.h
new file mode 100644
index 0000000..60ab44e
--- /dev/null
+++ b/src/dnswire/decoder.h
@@ -0,0 +1,64 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2019, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the dnswire library.
+ *
+ * dnswire library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * dnswire library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with dnswire library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dnswire/dnswire.h>
+#include <dnswire/dnstap.h>
+
+#include <tinyframe/tinyframe.h>
+
+#ifndef __dnswire_h_decoder
+#define __dnswire_h_decoder 1
+
+enum dnswire_decoder_state {
+ dnswire_decoder_reading_control = 0,
+ dnswire_decoder_checking_ready = 1,
+ dnswire_decoder_checking_accept = 2,
+ dnswire_decoder_reading_start = 3,
+ dnswire_decoder_checking_start = 4,
+ dnswire_decoder_reading_frames = 5,
+ dnswire_decoder_checking_finish = 6,
+ dnswire_decoder_done = 7,
+};
+extern const char* const dnswire_decoder_state_string[];
+
+struct dnswire_decoder {
+ enum dnswire_decoder_state state;
+ struct tinyframe_reader reader;
+ struct dnstap dnstap;
+
+ unsigned ready_support_dnstap_protobuf : 1;
+ unsigned accept_support_dnstap_protobuf : 1;
+};
+
+#define DNSWIRE_DECODER_INITIALIZER \
+ { \
+ .state = dnswire_decoder_reading_control, \
+ .reader = TINYFRAME_READER_INITIALIZER, \
+ .dnstap = DNSTAP_INITIALIZER, \
+ }
+
+#define dnswire_decoder_decoded(d) (d).reader.bytes_read
+#define dnswire_decoder_dnstap(d) (&(d).dnstap)
+#define dnswire_decoder_cleanup(d) dnstap_cleanup(&(d).dnstap)
+
+enum dnswire_result dnswire_decoder_decode(struct dnswire_decoder*, const uint8_t*, size_t);
+
+#endif
diff --git a/src/dnswire/dnstap.h b/src/dnswire/dnstap.h
new file mode 100644
index 0000000..97da495
--- /dev/null
+++ b/src/dnswire/dnstap.h
@@ -0,0 +1,151 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2019, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the dnswire library.
+ *
+ * dnswire library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * dnswire library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with dnswire library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dnswire/dnstap.pb-c.h>
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+
+#ifndef __dnswire_h_dnstap
+#define __dnswire_h_dnstap 1
+
+#define DNSTAP_PROTOBUF_CONTENT_TYPE "protobuf:dnstap.Dnstap"
+#define DNSTAP_PROTOBUF_CONTENT_TYPE_LENGTH 22
+
+enum dnstap_type {
+ DNSTAP_TYPE_UNKNOWN = 0,
+ DNSTAP_TYPE_MESSAGE = 1,
+};
+extern const char* const DNSTAP_TYPE_STRING[];
+
+enum dnstap_message_type {
+ DNSTAP_MESSAGE_TYPE_UNKNOWN = 0,
+ DNSTAP_MESSAGE_TYPE_AUTH_QUERY = 1,
+ DNSTAP_MESSAGE_TYPE_AUTH_RESPONSE = 2,
+ DNSTAP_MESSAGE_TYPE_RESOLVER_QUERY = 3,
+ DNSTAP_MESSAGE_TYPE_RESOLVER_RESPONSE = 4,
+ DNSTAP_MESSAGE_TYPE_CLIENT_QUERY = 5,
+ DNSTAP_MESSAGE_TYPE_CLIENT_RESPONSE = 6,
+ DNSTAP_MESSAGE_TYPE_FORWARDER_QUERY = 7,
+ DNSTAP_MESSAGE_TYPE_FORWARDER_RESPONSE = 8,
+ DNSTAP_MESSAGE_TYPE_STUB_QUERY = 9,
+ DNSTAP_MESSAGE_TYPE_STUB_RESPONSE = 10,
+ DNSTAP_MESSAGE_TYPE_TOOL_QUERY = 11,
+ DNSTAP_MESSAGE_TYPE_TOOL_RESPONSE = 12,
+};
+extern const char* const DNSTAP_MESSAGE_TYPE_STRING[];
+
+enum dnstap_socket_family {
+ DNSTAP_SOCKET_FAMILY_UNKNOWN = 0,
+ DNSTAP_SOCKET_FAMILY_INET = 1,
+ DNSTAP_SOCKET_FAMILY_INET6 = 2,
+};
+extern const char* const DNSTAP_SOCKET_FAMILY_STRING[];
+
+enum dnstap_socket_protocol {
+ DNSTAP_SOCKET_PROTOCOL_UNKNOWN = 0,
+ DNSTAP_SOCKET_PROTOCOL_UDP = 1,
+ DNSTAP_SOCKET_PROTOCOL_TCP = 2,
+};
+extern const char* const DNSTAP_SOCKET_PROTOCOL_STRING[];
+
+struct dnstap {
+ Dnstap__Dnstap dnstap;
+ Dnstap__Message message;
+
+ Dnstap__Dnstap* unpacked_dnstap;
+};
+
+#define DNSTAP_INITIALIZER \
+ { \
+ .dnstap = DNSTAP__DNSTAP__INIT, \
+ .message = DNSTAP__MESSAGE__INIT, \
+ .unpacked_dnstap = 0, \
+ }
+
+#include <dnswire/dnstap-macros.h>
+#define dnstap_type(d) (enum dnstap_type)((d).dnstap.type)
+#define dnstap_set_type(d, v) \
+ switch (v) { \
+ case DNSTAP_TYPE_MESSAGE: \
+ (d).dnstap.type = (enum _Dnstap__Dnstap__Type)v; \
+ (d).dnstap.message = &(d).message; \
+ break; \
+ default: \
+ (d).dnstap.type = (enum _Dnstap__Dnstap__Type)DNSTAP_TYPE_UNKNOWN; \
+ (d).dnstap.message = 0; \
+ }
+#define dnstap_has_message(d) ((d).dnstap.message != 0)
+
+#define dnstap_message_type(d) (enum dnstap_message_type)((d).message.type)
+#define dnstap_message_set_type(d, v) \
+ switch (v) { \
+ case DNSTAP_MESSAGE_TYPE_AUTH_QUERY: \
+ case DNSTAP_MESSAGE_TYPE_AUTH_RESPONSE: \
+ case DNSTAP_MESSAGE_TYPE_RESOLVER_QUERY: \
+ case DNSTAP_MESSAGE_TYPE_RESOLVER_RESPONSE: \
+ case DNSTAP_MESSAGE_TYPE_CLIENT_QUERY: \
+ case DNSTAP_MESSAGE_TYPE_CLIENT_RESPONSE: \
+ case DNSTAP_MESSAGE_TYPE_FORWARDER_QUERY: \
+ case DNSTAP_MESSAGE_TYPE_FORWARDER_RESPONSE: \
+ case DNSTAP_MESSAGE_TYPE_STUB_QUERY: \
+ case DNSTAP_MESSAGE_TYPE_STUB_RESPONSE: \
+ case DNSTAP_MESSAGE_TYPE_TOOL_QUERY: \
+ case DNSTAP_MESSAGE_TYPE_TOOL_RESPONSE: \
+ (d).message.type = (enum _Dnstap__Message__Type)v; \
+ break; \
+ default: \
+ (d).message.type = (enum _Dnstap__Message__Type)DNSTAP_MESSAGE_TYPE_UNKNOWN; \
+ }
+#define dnstap_message_set_socket_family(d, v) \
+ switch (v) { \
+ case DNSTAP_SOCKET_FAMILY_INET: \
+ case DNSTAP_SOCKET_FAMILY_INET6: \
+ (d).message.has_socket_family = true; \
+ (d).message.socket_family = (enum _Dnstap__SocketFamily)v; \
+ break; \
+ default: \
+ (d).message.has_socket_family = false; \
+ (d).message.socket_family = (enum _Dnstap__SocketFamily)DNSTAP_MESSAGE_TYPE_UNKNOWN; \
+ }
+#define dnstap_message_set_socket_protocol(d, v) \
+ switch (v) { \
+ case DNSTAP_SOCKET_PROTOCOL_UDP: \
+ case DNSTAP_SOCKET_PROTOCOL_TCP: \
+ (d).message.has_socket_protocol = true; \
+ (d).message.socket_protocol = (enum _Dnstap__SocketProtocol)v; \
+ break; \
+ default: \
+ (d).message.has_socket_protocol = false; \
+ (d).message.socket_protocol = (enum _Dnstap__SocketProtocol)DNSTAP_MESSAGE_TYPE_UNKNOWN; \
+ }
+
+int dnstap_decode_protobuf(struct dnstap*, const uint8_t*, size_t);
+// int dnstap_decode_cbor(struct dnstap*, const uint8_t*, size_t);
+
+size_t dnstap_encode_protobuf_size(const struct dnstap*);
+size_t dnstap_encode_protobuf(const struct dnstap*, uint8_t*);
+
+void dnstap_cleanup(struct dnstap*);
+
+#endif
diff --git a/src/dnswire/dnswire.h b/src/dnswire/dnswire.h
new file mode 100644
index 0000000..f113b22
--- /dev/null
+++ b/src/dnswire/dnswire.h
@@ -0,0 +1,39 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2019, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the dnswire library.
+ *
+ * dnswire library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * dnswire library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with dnswire library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __dnswire_h_dnswire
+#define __dnswire_h_dnswire 1
+
+#define DNSWIRE_DEFAULT_BUF_SIZE (4 * 1024)
+#define DNSWIRE_MAXIMUM_BUF_SIZE (64 * 1024)
+
+enum dnswire_result {
+ dnswire_ok = 0,
+ dnswire_error = 1,
+ dnswire_again = 2,
+ dnswire_need_more = 3,
+ dnswire_have_dnstap = 4,
+ dnswire_endofdata = 5,
+ dnswire_bidirectional = 6,
+};
+extern const char* const dnswire_result_string[];
+
+#endif
diff --git a/src/dnswire/encoder.h b/src/dnswire/encoder.h
new file mode 100644
index 0000000..c5fbc6a
--- /dev/null
+++ b/src/dnswire/encoder.h
@@ -0,0 +1,60 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2019, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the dnswire library.
+ *
+ * dnswire library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * dnswire library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with dnswire library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dnswire/dnswire.h>
+#include <dnswire/dnstap.h>
+
+#include <tinyframe/tinyframe.h>
+
+#ifndef __dnswire_h_encoder
+#define __dnswire_h_encoder 1
+
+enum dnswire_encoder_state {
+ dnswire_encoder_control_ready = 0,
+ dnswire_encoder_control_start = 1,
+ dnswire_encoder_control_accept = 2,
+ dnswire_encoder_control_finish = 3,
+ dnswire_encoder_frames = 4,
+ dnswire_encoder_control_stop = 5,
+ dnswire_encoder_done = 6,
+};
+extern const char* const dnswire_encoder_state_string[];
+
+struct dnswire_encoder {
+ enum dnswire_encoder_state state;
+ struct tinyframe_writer writer;
+ const struct dnstap* dnstap;
+};
+
+#define DNSWIRE_ENCODER_INITIALIZER \
+ { \
+ .state = dnswire_encoder_control_start, \
+ .writer = TINYFRAME_WRITER_INITIALIZER, \
+ .dnstap = 0, \
+ }
+
+#define dnswire_encoder_set_dnstap(e, d) (e).dnstap = d
+#define dnswire_encoder_encoded(e) (e).writer.bytes_wrote
+
+enum dnswire_result dnswire_encoder_encode(struct dnswire_encoder*, uint8_t*, size_t);
+enum dnswire_result dnswire_encoder_stop(struct dnswire_encoder*);
+
+#endif
diff --git a/src/dnswire/reader.h b/src/dnswire/reader.h
new file mode 100644
index 0000000..5fdfad5
--- /dev/null
+++ b/src/dnswire/reader.h
@@ -0,0 +1,91 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2019, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the dnswire library.
+ *
+ * dnswire library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * dnswire library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with dnswire library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dnswire/dnswire.h>
+#include <dnswire/decoder.h>
+#include <dnswire/encoder.h>
+
+#include <stdlib.h>
+
+#ifndef __dnswire_h_reader
+#define __dnswire_h_reader 1
+
+enum dnswire_reader_state {
+ dnswire_reader_reading_control = 0,
+ dnswire_reader_decoding_control = 1,
+ dnswire_reader_encoding_accept = 2,
+ dnswire_reader_writing_accept = 3,
+ dnswire_reader_reading = 4,
+ dnswire_reader_decoding = 5,
+ dnswire_reader_encoding_finish = 6,
+ dnswire_reader_writing_finish = 7,
+ dnswire_reader_done = 8,
+};
+extern const char* const dnswire_reader_state_string[];
+
+/*
+ * Attributes:
+ * - size: The current size of the buffer
+ * - inc: How much the buffer will be increased by if more spare is needed
+ * - max: The maximum size the buffer is allowed to have
+ * - at: Where in the buffer we are decoding (start of data)
+ * - left: How much data that is still left in the buffer from `at`
+ * - pushed: How much data that was pushed to the buffer by `dnswire_reader_push()`
+ */
+struct dnswire_reader {
+ enum dnswire_reader_state state;
+
+ struct dnswire_decoder decoder;
+ uint8_t* buf;
+ size_t size, inc, max, at, left, pushed;
+
+ struct dnswire_encoder encoder;
+ uint8_t* write_buf;
+ size_t write_size, write_inc, write_max, write_at, write_left;
+
+ bool allow_bidirectional, is_bidirectional;
+};
+
+enum dnswire_result dnswire_reader_init(struct dnswire_reader*);
+
+#define dnswire_reader_pushed(r) (r).pushed
+#define dnswire_reader_dnstap(r) (&(r).decoder.dnstap)
+#define dnswire_reader_cleanup(r) \
+ dnswire_decoder_cleanup((r).decoder)
+#define dnswire_reader_destroy(r) \
+ free((r).buf); \
+ free((r).write_buf); \
+ dnswire_decoder_cleanup((r).decoder)
+#define dnswire_reader_is_bidirectional(r) (r).is_bidirectional
+
+enum dnswire_result dnswire_reader_allow_bidirectional(struct dnswire_reader*, bool);
+enum dnswire_result dnswire_reader_set_bufsize(struct dnswire_reader*, size_t);
+enum dnswire_result dnswire_reader_set_bufinc(struct dnswire_reader*, size_t);
+enum dnswire_result dnswire_reader_set_bufmax(struct dnswire_reader*, size_t);
+
+enum dnswire_result dnswire_reader_push(struct dnswire_reader*, const uint8_t*, size_t, uint8_t*, size_t*);
+enum dnswire_result dnswire_reader_read(struct dnswire_reader*, int);
+static inline enum dnswire_result dnswire_reader_fread(struct dnswire_reader* handle, FILE* fp)
+{
+ return dnswire_reader_read(handle, fileno(fp));
+}
+
+#endif
diff --git a/src/dnswire/trace.h.in b/src/dnswire/trace.h.in
new file mode 100644
index 0000000..7b8e038
--- /dev/null
+++ b/src/dnswire/trace.h.in
@@ -0,0 +1,41 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2019, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the dnswire library.
+ *
+ * dnswire library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * dnswire library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with dnswire library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __dnswire_h_trace
+#define __dnswire_h_trace 1
+
+#if @DNSWIRE_TRACE@
+#define DNSWIRE_TRACE 1
+#include <stdio.h>
+#include <ctype.h>
+#include <stdint.h>
+const char* __printable_string(const uint8_t* data, size_t len);
+#define __trace(x...) \
+ fprintf(stderr, "dnswire %s(): ", __func__); \
+ fprintf(stderr, x); \
+ fprintf(stderr, "\n"); \
+ fflush(stderr);
+#else
+#define __trace(x...)
+#define __printable_string(x...)
+#endif
+
+#endif
diff --git a/src/dnswire/version.h.in b/src/dnswire/version.h.in
new file mode 100644
index 0000000..1a4f96f
--- /dev/null
+++ b/src/dnswire/version.h.in
@@ -0,0 +1,33 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2019, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the dnswire library.
+ *
+ * dnswire library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * dnswire library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with dnswire library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dnswire/dnswire.h>
+
+#ifndef __dnswire_h_version
+#define __dnswire_h_version 1
+
+#define DNSWIRE_VERSION @DNSWIRE_VERSION_MAJOR@@DNSWIRE_VERSION_MINOR@@DNSWIRE_VERSION_PATCH@
+#define DNSWIRE_VERSION_MAJOR @DNSWIRE_VERSION_MAJOR@
+#define DNSWIRE_VERSION_MINOR @DNSWIRE_VERSION_MINOR@
+#define DNSWIRE_VERSION_PATCH @DNSWIRE_VERSION_PATCH@
+#define DNSWIRE_VERSION_STRING "@PACKAGE_VERSION@"
+
+#endif
diff --git a/src/dnswire/writer.h b/src/dnswire/writer.h
new file mode 100644
index 0000000..99bae1a
--- /dev/null
+++ b/src/dnswire/writer.h
@@ -0,0 +1,90 @@
+/*
+ * Author Jerry Lundström <jerry@dns-oarc.net>
+ * Copyright (c) 2019, OARC, Inc.
+ * All rights reserved.
+ *
+ * This file is part of the dnswire library.
+ *
+ * dnswire library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * dnswire library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with dnswire library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <dnswire/dnswire.h>
+#include <dnswire/encoder.h>
+#include <dnswire/decoder.h>
+
+#include <stdlib.h>
+
+#ifndef __dnswire_h_writer
+#define __dnswire_h_writer 1
+
+enum dnswire_writer_state {
+ dnswire_writer_encoding_ready = 0,
+ dnswire_writer_writing_ready = 1,
+ dnswire_writer_reading_accept = 2,
+ dnswire_writer_decoding_accept = 3,
+ dnswire_writer_encoding = 4,
+ dnswire_writer_writing = 5,
+ dnswire_writer_stopping = 6,
+ dnswire_writer_encoding_stop = 7,
+ dnswire_writer_writing_stop = 8,
+ dnswire_writer_reading_finish = 9,
+ dnswire_writer_decoding_finish = 10,
+ dnswire_writer_done = 11,
+};
+extern const char* const dnswire_writer_state_string[];
+
+/*
+ * Attributes:
+ * - size: The current size of the buffer
+ * - inc: How much the buffer will be increased by if more spare is needed
+ * - max: The maximum size the buffer is allowed to have
+ * - at: Where in the buffer we are encoding to (end of data)
+ * - left: How much data that is still left in the buffer before `at`
+ */
+struct dnswire_writer {
+ enum dnswire_writer_state state;
+
+ struct dnswire_encoder encoder;
+ uint8_t* buf;
+ size_t size, inc, max, at, left, popped;
+
+ struct dnswire_decoder decoder;
+ uint8_t* read_buf;
+ size_t read_size, read_inc, read_max, read_at, read_left, read_pushed;
+
+ bool bidirectional;
+};
+
+enum dnswire_result dnswire_writer_init(struct dnswire_writer*);
+
+#define dnswire_writer_popped(w) (w).popped
+#define dnswire_writer_set_dnstap(w, d) (w).encoder.dnstap = d
+#define dnswire_writer_destroy(w) \
+ free((w).buf); \
+ free((w).read_buf)
+
+enum dnswire_result dnswire_writer_set_bidirectional(struct dnswire_writer*, bool);
+enum dnswire_result dnswire_writer_set_bufsize(struct dnswire_writer*, size_t);
+enum dnswire_result dnswire_writer_set_bufinc(struct dnswire_writer*, size_t);
+enum dnswire_result dnswire_writer_set_bufmax(struct dnswire_writer*, size_t);
+
+enum dnswire_result dnswire_writer_pop(struct dnswire_writer*, uint8_t*, size_t, uint8_t*, size_t*);
+enum dnswire_result dnswire_writer_write(struct dnswire_writer*, int);
+static inline enum dnswire_result dnswire_writer_fwrite(struct dnswire_writer* handle, FILE* fp)
+{
+ return dnswire_writer_write(handle, fileno(fp));
+}
+enum dnswire_result dnswire_writer_stop(struct dnswire_writer*);
+
+#endif