From a8264065f66efd9622b36d03ccaedd3ac2602adc Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Thu, 30 Jan 2020 17:11:07 +0100 Subject: [PATCH] - put fstrm protocol contents in separate files, dnstap_fstrm.c and dnstap_fstrm.h --- Makefile.in | 1 + configure | 4 +- configure.ac | 4 +- dnstap/dnstap_fstrm.c | 91 +++++++++++++++++++++ dnstap/dnstap_fstrm.h | 142 +++++++++++++++++++++++++++++++++ dnstap/dtstream.c | 47 +---------- dnstap/dtstream.h | 94 ---------------------- dnstap/unbound-dnstap-socket.c | 1 + 8 files changed, 240 insertions(+), 144 deletions(-) create mode 100644 dnstap/dnstap_fstrm.c create mode 100644 dnstap/dnstap_fstrm.h diff --git a/Makefile.in b/Makefile.in index 792ea6185..24f6f5059 100644 --- a/Makefile.in +++ b/Makefile.in @@ -410,6 +410,7 @@ unbound-dnstap-socket$(EXEEXT): $(DNSTAP_SOCKET_OBJ_LINK) dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dtstream.h +dnstap_fstrm.lo dnstap_fstrm.o: $(srcdir)/dnstap/dnstap_fstrm.c config.h $(srcdir)/dnstap/dnstap_fstrm.h unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnstap-socket.c config.h $(srcdir)/dnstap/dtstream.h # dnscrypt diff --git a/configure b/configure index 7832d0997..36f42644e 100755 --- a/configure +++ b/configure @@ -21039,9 +21039,9 @@ cat >>confdefs.h <<_ACEOF _ACEOF - DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dtstream.c" + DNSTAP_SRC="dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c" - DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo dtstream.lo" + DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo" else diff --git a/configure.ac b/configure.ac index a9734f6f5..913703092 100644 --- a/configure.ac +++ b/configure.ac @@ -1688,8 +1688,8 @@ dt_DNSTAP([$UNBOUND_RUN_DIR/dnstap.sock], AC_DEFINE_UNQUOTED(DNSTAP_SOCKET_PATH, ["$hdr_dnstap_socket_path"], [default dnstap socket path]) - AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dtstream.c"]) - AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo dtstream.lo"]) + AC_SUBST([DNSTAP_SRC], ["dnstap/dnstap.c dnstap/dnstap.pb-c.c dnstap/dnstap_fstrm.c dnstap/dtstream.c"]) + AC_SUBST([DNSTAP_OBJ], ["dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo"]) ], [ AC_SUBST([ENABLE_DNSTAP], [0]) diff --git a/dnstap/dnstap_fstrm.c b/dnstap/dnstap_fstrm.c new file mode 100644 index 000000000..51ff71a6e --- /dev/null +++ b/dnstap/dnstap_fstrm.c @@ -0,0 +1,91 @@ +/* + * dnstap/dnstap_fstrm.c - Frame Streams protocol for dnstap + * + * Copyright (c) 2020, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * \file + * + * Definitions for the Frame Streams data transport protocol for + * dnstap message logs. + */ + +#include "config.h" +#include "dnstap/dnstap_fstrm.h" + +void* fstrm_create_control_frame_start(char* contenttype, size_t* len) +{ + uint32_t* control; + size_t n; + /* start framestream message: + * 4byte 0: control indicator. + * 4byte bigendian: length of control frame + * 4byte bigendian: type START + * 4byte bigendian: frame option: content-type + * 4byte bigendian: length of string + * string of content type (dnstap) + */ + n = 4+4+4+4+4+strlen(contenttype); + control = malloc(n); + if(!control) + return NULL; + control[0] = 0; + control[1] = htonl(4+4+4+strlen(contenttype)); + control[2] = htonl(FSTRM_CONTROL_FRAME_START); + control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE); + control[4] = htonl(strlen(contenttype)); + memmove(&control[5], contenttype, strlen(contenttype)); + *len = n; + return control; +} + +void* fstrm_create_control_frame_stop(size_t* len) +{ + uint32_t* control; + size_t n; + /* stop framestream message: + * 4byte 0: control indicator. + * 4byte bigendian: length of control frame + * 4byte bigendian: type STOP + */ + n = 4+4+4; + control = malloc(n); + if(!control) + return NULL; + control[0] = 0; + control[1] = htonl(4); + control[2] = htonl(FSTRM_CONTROL_FRAME_STOP); + *len = n; + return control; +} diff --git a/dnstap/dnstap_fstrm.h b/dnstap/dnstap_fstrm.h new file mode 100644 index 000000000..3b70547f1 --- /dev/null +++ b/dnstap/dnstap_fstrm.h @@ -0,0 +1,142 @@ +/* + * dnstap/dnstap_fstrm.h - Frame Streams protocol for dnstap + * + * Copyright (c) 2020, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * \file + * + * Definitions for the Frame Streams data transport protocol for + * dnstap message logs. + */ + +#ifndef DNSTAP_FSTRM_H +#define DNSTAP_FSTRM_H + +/* Frame Streams data transfer protocol encode for DNSTAP messages. + * The protocol looks to be specified in the libfstrm library. + * + * Quick writeup for DNSTAP usage, from reading fstrm/control.h eloquent + * comments and fstrm/control.c for some bytesize details (the content type + * length). + * + * The Frame Streams can be unidirectional or bi-directional. + * bi-directional streams use control frame types READY, ACCEPT and FINISH. + * uni-directional streams use control frame types START and STOP. + * unknown control frame types should be ignored by the receiver, they + * do not change the data frame encoding. + * + * bi-directional control frames implement a simple handshake protocol + * between sender and receiver. + * + * The uni-directional control frames have one start and one stop frame, + * before and after the data. The start frame can have a content type. + * The start and stop frames are not optional. + * + * data frames are preceded by 4byte length, bigendian. + * zero length data frames are not possible, they are an escape that + * signals the presence of a control frame. + * + * a control frame consists of 0 value in 4byte bigendian, this is really + * the data frame length, with 0 the escape sequence that indicates one + * control frame follows. + * Then, 4byte bigendian, length of the control frame message. + * Then, the control frame payload (of that length). with in it: + * 4byte bigendian, control type (eg. START, STOP, READY, ACCEPT, FINISH). + * perhaps nothing more (STOP, FINISH), but for other types maybe + * control fields + * 4byte bigendian, the control-field-type, currently only content-type. + * 4byte bigendian, length of the string for this option. + * .. bytes of that string. + * + * The START type can have only one field. Field max len 256. + * control frame max frame length 512 (excludes the 0-escape and control + * frame length bytes). + * + * the bidirectional type of transmission is like this: + * client sends READY (with content type included), + * client waits for ACCEPT (with content type included), + * client sends START (with matched content type from ACCEPT) + * .. data frames + * client sends STOP. + * client waits for FINISH frame. + * + */ + +/** max length of Frame Streams content type field string */ +#define FSTRM_CONTENT_TYPE_LENGTH_MAX 256 +/** control frame value to denote the control frame ACCEPT */ +#define FSTRM_CONTROL_FRAME_ACCEPT 0x01 +/** control frame value to denote the control frame START */ +#define FSTRM_CONTROL_FRAME_START 0x02 +/** control frame value to denote the control frame STOP */ +#define FSTRM_CONTROL_FRAME_STOP 0x03 +/** control frame value to denote the control frame READY */ +#define FSTRM_CONTROL_FRAME_READY 0x04 +/** control frame value to denote the control frame FINISH */ +#define FSTRM_CONTROL_FRAME_FINISH 0x05 +/** the constant that denotes the control field type that is the + * string for the content type of the stream. */ +#define FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE 0x01 +/** the content type for DNSTAP frame streams */ +#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" + +/** + * This creates an FSTRM control frame of type START. + * @param contenttype: a zero delimited string with the content type. + * eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as + * "protobuf:dnstap.Dnstap", for a dnstap frame stream. + * @param len: if a buffer is returned this is the length of that buffer. + * @return NULL on malloc failure. Returns a malloced buffer with the + * protocol message. The buffer starts with the 4 bytes of 0 that indicate + * a control frame. The buffer should be sent without preceding it with + * the 'len' variable (like data frames are), but straight the content of the + * buffer, because the lengths are included in the buffer. This is so that + * the zero control indicator can be included before the control frame length. + */ +void* fstrm_create_control_frame_start(char* contenttype, size_t* len); + +/** + * This creates an FSTRM control frame of type STOP. + * @param len: if a buffer is returned this is the length of that buffer. + * @return NULL on malloc failure. Returns a malloced buffer with the + * protocol message. The buffer starts with the 4 bytes of 0 that indicate + * a control frame. The buffer should be sent without preceding it with + * the 'len' variable (like data frames are), but straight the content of the + * buffer, because the lengths are included in the buffer. This is so that + * the zero control indicator can be included before the control frame length. + */ +void* fstrm_create_control_frame_stop(size_t* len); + +#endif /* DNSTAP_FSTRM_H */ diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index bd4d39acb..b734fc9c1 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -43,6 +43,7 @@ #include "config.h" #include "dnstap/dtstream.h" +#include "dnstap/dnstap_fstrm.h" #include "util/config_file.h" #include "util/ub_event.h" #include "util/net_help.h" @@ -73,52 +74,6 @@ static void dtio_add_output_event_write(struct dt_io_thread* dtio); /** start reconnection attempts */ static void dtio_reconnect_enable(struct dt_io_thread* dtio); -void* fstrm_create_control_frame_start(char* contenttype, size_t* len) -{ - uint32_t* control; - size_t n; - /* start framestream message: - * 4byte 0: control indicator. - * 4byte bigendian: length of control frame - * 4byte bigendian: type START - * 4byte bigendian: frame option: content-type - * 4byte bigendian: length of string - * string of content type (dnstap) - */ - n = 4+4+4+4+4+strlen(contenttype); - control = malloc(n); - if(!control) - return NULL; - control[0] = 0; - control[1] = htonl(4+4+4+strlen(contenttype)); - control[2] = htonl(FSTRM_CONTROL_FRAME_START); - control[3] = htonl(FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE); - control[4] = htonl(strlen(contenttype)); - memmove(&control[5], contenttype, strlen(contenttype)); - *len = n; - return control; -} - -void* fstrm_create_control_frame_stop(size_t* len) -{ - uint32_t* control; - size_t n; - /* stop framestream message: - * 4byte 0: control indicator. - * 4byte bigendian: length of control frame - * 4byte bigendian: type STOP - */ - n = 4+4+4; - control = malloc(n); - if(!control) - return NULL; - control[0] = 0; - control[1] = htonl(4); - control[2] = htonl(FSTRM_CONTROL_FRAME_STOP); - *len = n; - return control; -} - struct dt_msg_queue* dt_msg_queue_create(void) { diff --git a/dnstap/dtstream.h b/dnstap/dtstream.h index 9309f5c0b..f2c13fde4 100644 --- a/dnstap/dtstream.h +++ b/dnstap/dtstream.h @@ -185,100 +185,6 @@ struct dt_io_list_item { struct dt_msg_queue* queue; }; -/* Frame Streams data transfer protocol encode for DNSTAP messages. - * The protocol looks to be specified in the libfstrm library. - * - * Quick writeup for DNSTAP usage, from reading fstrm/control.h eloquent - * comments and fstrm/control.c for some bytesize details (the content type - * length). - * - * The Frame Streams can be unidirectional or bi-directional. - * bi-directional streams use control frame types READY, ACCEPT and FINISH. - * uni-directional streams use control frame types START and STOP. - * unknown control frame types should be ignored by the receiver, they - * do not change the data frame encoding. - * - * bi-directional control frames implement a simple handshake protocol - * between sender and receiver. - * - * The uni-directional control frames have one start and one stop frame, - * before and after the data. The start frame can have a content type. - * The start and stop frames are not optional. - * - * data frames are preceded by 4byte length, bigendian. - * zero length data frames are not possible, they are an escape that - * signals the presence of a control frame. - * - * a control frame consists of 0 value in 4byte bigendian, this is really - * the data frame length, with 0 the escape sequence that indicates one - * control frame follows. - * Then, 4byte bigendian, length of the control frame message. - * Then, the control frame payload (of that length). with in it: - * 4byte bigendian, control type (eg. START, STOP, READY, ACCEPT, FINISH). - * perhaps nothing more (STOP, FINISH), but for other types maybe - * control fields - * 4byte bigendian, the control-field-type, currently only content-type. - * 4byte bigendian, length of the string for this option. - * .. bytes of that string. - * - * The START type can have only one field. Field max len 256. - * control frame max frame length 512 (excludes the 0-escape and control - * frame length bytes). - * - * the bidirectional type of transmission is like this: - * client sends READY (with content type included), - * client waits for ACCEPT (with content type included), - * client sends START (with matched content type from ACCEPT) - * .. data frames - * client sends STOP. - * client waits for FINISH frame. - * - */ - -/** max length of Frame Streams content type field string */ -#define FSTRM_CONTENT_TYPE_LENGTH_MAX 256 -/** control frame value to denote the control frame ACCEPT */ -#define FSTRM_CONTROL_FRAME_ACCEPT 0x01 -/** control frame value to denote the control frame START */ -#define FSTRM_CONTROL_FRAME_START 0x02 -/** control frame value to denote the control frame STOP */ -#define FSTRM_CONTROL_FRAME_STOP 0x03 -/** control frame value to denote the control frame READY */ -#define FSTRM_CONTROL_FRAME_READY 0x04 -/** control frame value to denote the control frame FINISH */ -#define FSTRM_CONTROL_FRAME_FINISH 0x05 -/** the constant that denotes the control field type that is the - * string for the content type of the stream. */ -#define FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE 0x01 -/** the content type for DNSTAP frame streams */ -#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" - -/** - * This creates an FSTRM control frame of type START. - * @param contenttype: a zero delimited string with the content type. - * eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as - * "protobuf:dnstap.Dnstap", for a dnstap frame stream. - * @param len: if a buffer is returned this is the length of that buffer. - * @return NULL on malloc failure. Returns a malloced buffer with the - * protocol message. The buffer starts with the 4 bytes of 0 that indicate - * a control frame. The buffer should be sent without preceding it with - * the 'len' variable (like data frames are), but straight the content of the - * buffer, because the lengths are included in the buffer. This is so that - * the zero control indicator can be included before the control frame length. - */ -void* fstrm_create_control_frame_start(char* contenttype, size_t* len); -/** - * This creates an FSTRM control frame of type STOP. - * @param len: if a buffer is returned this is the length of that buffer. - * @return NULL on malloc failure. Returns a malloced buffer with the - * protocol message. The buffer starts with the 4 bytes of 0 that indicate - * a control frame. The buffer should be sent without preceding it with - * the 'len' variable (like data frames are), but straight the content of the - * buffer, because the lengths are included in the buffer. This is so that - * the zero control indicator can be included before the control frame length. - */ -void* fstrm_create_control_frame_stop(size_t* len); - /** * Create new (empty) worker message queue. Limit set to default on max. * @return NULL on malloc failure or a new queue (not locked). diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index a1705e1d7..8afb1c1fc 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -53,6 +53,7 @@ #include #include #include "dnstap/dtstream.h" +#include "dnstap/dnstap_fstrm.h" #include "util/log.h" #include "util/ub_event.h" #include "util/net_help.h" -- 2.47.3