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