1 /* 2 * dnstap/dnstap_fstrm.h - Frame Streams protocol for dnstap 3 * 4 * Copyright (c) 2020, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * Neither the name of the NLNET LABS nor the names of its contributors may 20 * be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 */ 36 37 /** 38 * \file 39 * 40 * Definitions for the Frame Streams data transport protocol for 41 * dnstap message logs. 42 */ 43 44 #ifndef DNSTAP_FSTRM_H 45 #define DNSTAP_FSTRM_H 46 47 /* Frame Streams data transfer protocol encode for DNSTAP messages. 48 * The protocol looks to be specified in the libfstrm library. 49 * 50 * Quick writeup for DNSTAP usage, from reading fstrm/control.h eloquent 51 * comments and fstrm/control.c for some bytesize details (the content type 52 * length). 53 * 54 * The Frame Streams can be unidirectional or bi-directional. 55 * bi-directional streams use control frame types READY, ACCEPT and FINISH. 56 * uni-directional streams use control frame types START and STOP. 57 * unknown control frame types should be ignored by the receiver, they 58 * do not change the data frame encoding. 59 * 60 * bi-directional control frames implement a simple handshake protocol 61 * between sender and receiver. 62 * 63 * The uni-directional control frames have one start and one stop frame, 64 * before and after the data. The start frame can have a content type. 65 * The start and stop frames are not optional. 66 * 67 * data frames are preceded by 4byte length, bigendian. 68 * zero length data frames are not possible, they are an escape that 69 * signals the presence of a control frame. 70 * 71 * a control frame consists of 0 value in 4byte bigendian, this is really 72 * the data frame length, with 0 the escape sequence that indicates one 73 * control frame follows. 74 * Then, 4byte bigendian, length of the control frame message. 75 * Then, the control frame payload (of that length). with in it: 76 * 4byte bigendian, control type (eg. START, STOP, READY, ACCEPT, FINISH). 77 * perhaps nothing more (STOP, FINISH), but for other types maybe 78 * control fields 79 * 4byte bigendian, the control-field-type, currently only content-type. 80 * 4byte bigendian, length of the string for this option. 81 * .. bytes of that string. 82 * 83 * The START type can have only one field. Field max len 256. 84 * control frame max frame length 512 (excludes the 0-escape and control 85 * frame length bytes). 86 * 87 * the bidirectional type of transmission is like this: 88 * client sends READY (with content type included), 89 * client waits for ACCEPT (with content type included), 90 * client sends START (with matched content type from ACCEPT) 91 * .. data frames 92 * client sends STOP. 93 * client waits for FINISH frame. 94 * 95 */ 96 97 /** max length of Frame Streams content type field string */ 98 #define FSTRM_CONTENT_TYPE_LENGTH_MAX 256 99 /** control frame value to denote the control frame ACCEPT */ 100 #define FSTRM_CONTROL_FRAME_ACCEPT 0x01 101 /** control frame value to denote the control frame START */ 102 #define FSTRM_CONTROL_FRAME_START 0x02 103 /** control frame value to denote the control frame STOP */ 104 #define FSTRM_CONTROL_FRAME_STOP 0x03 105 /** control frame value to denote the control frame READY */ 106 #define FSTRM_CONTROL_FRAME_READY 0x04 107 /** control frame value to denote the control frame FINISH */ 108 #define FSTRM_CONTROL_FRAME_FINISH 0x05 109 /** the constant that denotes the control field type that is the 110 * string for the content type of the stream. */ 111 #define FSTRM_CONTROL_FIELD_TYPE_CONTENT_TYPE 0x01 112 /** the content type for DNSTAP frame streams */ 113 #define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" 114 115 /** 116 * This creates an FSTRM control frame of type START. 117 * @param contenttype: a zero delimited string with the content type. 118 * eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as 119 * "protobuf:dnstap.Dnstap", for a dnstap frame stream. 120 * @param len: if a buffer is returned this is the length of that buffer. 121 * @return NULL on malloc failure. Returns a malloced buffer with the 122 * protocol message. The buffer starts with the 4 bytes of 0 that indicate 123 * a control frame. The buffer should be sent without preceding it with 124 * the 'len' variable (like data frames are), but straight the content of the 125 * buffer, because the lengths are included in the buffer. This is so that 126 * the zero control indicator can be included before the control frame length. 127 */ 128 void* fstrm_create_control_frame_start(char* contenttype, size_t* len); 129 130 /** 131 * This creates an FSTRM control frame of type READY. 132 * @param contenttype: a zero delimited string with the content type. 133 * eg. use the constant DNSTAP_CONTENT_TYPE, which is defined as 134 * "protobuf:dnstap.Dnstap", for a dnstap frame stream. 135 * @param len: if a buffer is returned this is the length of that buffer. 136 * @return NULL on malloc failure. Returns a malloced buffer with the 137 * protocol message. The buffer starts with the 4 bytes of 0 that indicate 138 * a control frame. The buffer should be sent without preceding it with 139 * the 'len' variable (like data frames are), but straight the content of the 140 * buffer, because the lengths are included in the buffer. This is so that 141 * the zero control indicator can be included before the control frame length. 142 */ 143 void* fstrm_create_control_frame_ready(char* contenttype, size_t* len); 144 145 /** 146 * This creates an FSTRM control frame of type STOP. 147 * @param len: if a buffer is returned this is the length of that buffer. 148 * @return NULL on malloc failure. Returns a malloced buffer with the 149 * protocol message. The buffer starts with the 4 bytes of 0 that indicate 150 * a control frame. The buffer should be sent without preceding it with 151 * the 'len' variable (like data frames are), but straight the content of the 152 * buffer, because the lengths are included in the buffer. This is so that 153 * the zero control indicator can be included before the control frame length. 154 */ 155 void* fstrm_create_control_frame_stop(size_t* len); 156 157 /** 158 * This creates an FSTRM control frame of type ACCEPT. 159 * @param contenttype: a zero delimited string with the content type. 160 * for dnstap streams use DNSTAP_CONTENT_TYPE. 161 * @param len: if a buffer is returned this is the length of that buffer. 162 * @return NULL on malloc failure. Returns a malloced buffer with the 163 * protocol message. The buffer starts with the 4 bytes of 0 that indicate 164 * a control frame. The buffer should be sent without preceding it with 165 * the 'len' variable (like data frames are), but straight the content of the 166 * buffer, because the lengths are included in the buffer. This is so that 167 * the zero control indicator can be included before the control frame length. 168 */ 169 void* fstrm_create_control_frame_accept(char* contenttype, size_t* len); 170 171 /** 172 * This creates an FSTRM control frame of type FINISH. 173 * @param len: if a buffer is returned this is the length of that buffer. 174 * @return NULL on malloc failure. Returns a malloced buffer with the 175 * protocol message. The buffer starts with the 4 bytes of 0 that indicate 176 * a control frame. The buffer should be sent without preceding it with 177 * the 'len' variable (like data frames are), but straight the content of the 178 * buffer, because the lengths are included in the buffer. This is so that 179 * the zero control indicator can be included before the control frame length. 180 */ 181 void* fstrm_create_control_frame_finish(size_t* len); 182 183 /** 184 * Return string that describes a control packet. For debug, logs. 185 * Like 'start content-type(protobuf:dnstap.Dnstap)' or 'stop'. 186 * @param pkt: the packet data, that is the data after the 4 zero start 187 * bytes and 4 length bytes. 188 * @param len: the length of the control packet data, in pkt. This is the 189 * ntohl of the 4 bytes length preceding the data. 190 * @return zero delimited string, malloced. Or NULL on malloc failure. 191 */ 192 char* fstrm_describe_control(void* pkt, size_t len); 193 194 #endif /* DNSTAP_FSTRM_H */ 195