summaryrefslogtreecommitdiffstats
path: root/lib/dns/include/dns/dnstap.h
blob: ed2c199c466c5ce206a83763ce1f121cc7323e58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
/*
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
 *
 * SPDX-License-Identifier: MPL-2.0
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
 *
 * See the COPYRIGHT file distributed with this work for additional
 * information regarding copyright ownership.
 */

#pragma once

/*****
***** Module Info
*****/

/*! \file
 * \brief
 * The dt (dnstap) module provides fast passive logging of DNS messages.
 * Protocol Buffers.  The protobuf schema for Dnstap messages is in the
 * file dnstap.proto, which is compiled to dnstap.pb-c.c and dnstap.pb-c.h.
 */

#include <inttypes.h>
#include <stdbool.h>

struct fstrm_iothr_options;

#include <isc/log.h>
#include <isc/refcount.h>
#include <isc/region.h>
#include <isc/sockaddr.h>
#include <isc/time.h>
#include <isc/types.h>

#include <dns/name.h>
#include <dns/rdataclass.h>
#include <dns/rdatatype.h>
#include <dns/types.h>

/*%
 * Dnstap message types:
 *
 * STUB QUERY: SQ
 * STUB RESPONSE: SR
 * CLIENT QUERY: CQ
 * CLIENT RESPONSE: CR
 * AUTH QUERY: AQ
 * AUTH RESPONSE: AR
 * RESOLVER QUERY: RQ
 * RESOLVER RESPONSE: RR
 * FORWARDER QUERY: FQ
 * FORWARDER RESPONSE: FR
 */

#define DNS_DTTYPE_SQ 0x0001
#define DNS_DTTYPE_SR 0x0002
#define DNS_DTTYPE_CQ 0x0004
#define DNS_DTTYPE_CR 0x0008
#define DNS_DTTYPE_AQ 0x0010
#define DNS_DTTYPE_AR 0x0020
#define DNS_DTTYPE_RQ 0x0040
#define DNS_DTTYPE_RR 0x0080
#define DNS_DTTYPE_FQ 0x0100
#define DNS_DTTYPE_FR 0x0200
#define DNS_DTTYPE_TQ 0x0400
#define DNS_DTTYPE_TR 0x0800
#define DNS_DTTYPE_UQ 0x1000
#define DNS_DTTYPE_UR 0x2000

#define DNS_DTTYPE_QUERY                                                 \
	(DNS_DTTYPE_SQ | DNS_DTTYPE_CQ | DNS_DTTYPE_AQ | DNS_DTTYPE_RQ | \
	 DNS_DTTYPE_FQ | DNS_DTTYPE_TQ | DNS_DTTYPE_UQ)
#define DNS_DTTYPE_RESPONSE                                              \
	(DNS_DTTYPE_SR | DNS_DTTYPE_CR | DNS_DTTYPE_AR | DNS_DTTYPE_RR | \
	 DNS_DTTYPE_FR | DNS_DTTYPE_TR | DNS_DTTYPE_UR)
#define DNS_DTTYPE_ALL (DNS_DTTYPE_QUERY | DNS_DTTYPE_RESPONSE)

typedef enum {
	dns_dtmode_none = 0,
	dns_dtmode_file,
	dns_dtmode_unix
} dns_dtmode_t;

typedef struct dns_dthandle dns_dthandle_t;

#ifdef HAVE_DNSTAP
struct dns_dtdata {
	isc_mem_t *mctx;

	void *frame;

	bool		query;
	bool		tcp;
	dns_dtmsgtype_t type;

	isc_time_t qtime;
	isc_time_t rtime;

	isc_region_t qaddr;
	isc_region_t raddr;

	uint32_t qport;
	uint32_t rport;

	isc_region_t   msgdata;
	dns_message_t *msg;

	char namebuf[DNS_NAME_FORMATSIZE];
	char typebuf[DNS_RDATATYPE_FORMATSIZE];
	char classbuf[DNS_RDATACLASS_FORMATSIZE];
};
#endif /* HAVE_DNSTAP */

isc_result_t
dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path,
	      struct fstrm_iothr_options **foptp, isc_task_t *reopen_task,
	      dns_dtenv_t **envp);
/*%<
 * Create and initialize the dnstap environment.
 *
 * There should be a single global dnstap environment for the server;
 * copies of it will be attached to each view.
 *
 * Notes:
 *
 *\li	'path' refers to a UNIX domain socket by default. It may
 *	optionally be prepended with "socket:" or "file:". If prepended
 *	with "file:", then dnstap logs are sent to a file instead of a
 *	socket.
 *
 *\li	'*foptp' set the options for fstrm_iothr_init(). '*foptp' must have
 *	have had the number of input queues set and this should be set
 *	to the number of worker threads.  Additionally the queue model
 *	should also be set.  Other options may be set if desired.
 *	If dns_dt_create succeeds the *foptp is set to NULL.
 *
 *\li	'reopen_task' needs to be set to the task in the context of which
 *	dns_dt_reopen() will be called.  This is not an optional parameter:
 *	using dns_dt_create() (which sets 'reopen_task' to NULL) is only
 *	allowed in unit tests.
 *
 * Requires:
 *
 *\li	'mctx' is a valid memory context.
 *
 *\li	'path' is a valid C string.
 *
 *\li	'foptp' is non NULL.
 *
 *\li	envp != NULL && *envp == NULL
 *
 * Returns:
 *
 *\li	#ISC_R_SUCCESS
 *\li	#ISC_R_NOMEMORY
 *
 *\li	Other errors are possible.
 */

isc_result_t
dns_dt_setupfile(dns_dtenv_t *env, uint64_t max_size, int rolls,
		 isc_log_rollsuffix_t suffix);
/*%<
 * Sets up the dnstap logfile limits.
 *
 * 'max_size' is the size a log file may grow before it is rolled
 *
 * 'rolls' is the number of rolled files to retain.
 *
 * 'suffix' is the logfile suffix setting, increment or timestamp.
 *
 * Requires:
 *
 *\li	'env' is a valid dnstap environment.
 *
 * Returns:
 *\li	#ISC_R_SUCCESS on success
 *\li	#ISC_R_INVALIDFILE if dnstap is set to use a UNIX domain socket
 */

isc_result_t
dns_dt_reopen(dns_dtenv_t *env, int roll);
/*%<
 * Reopens files established by dns_dt_create2().
 *
 * If 'roll' is non-negative and 'env->mode' is dns_dtmode_file,
 * then the file is automatically rolled over before reopening.
 * The value of 'roll' indicates the number of backup log files to
 * keep.  If 'roll' is negative, or if 'env->mode' is dns_dtmode_unix,
 * then the channel is simply reopened.
 *
 * Note: dns_dt_reopen() uses task-exclusive mode and must be run in the
 * context of env->reopen_task.
 *
 * Requires:
 *\li	'env' is a valid dnstap environment.
 */

isc_result_t
dns_dt_setidentity(dns_dtenv_t *env, const char *identity);
isc_result_t
dns_dt_setversion(dns_dtenv_t *env, const char *version);
/*%<
 * Set the "identity" and "version" strings to be sent in dnstap messages.
 *
 * Requires:
 *
 *\li	'env' is a valid dnstap environment.
 */

void
dns_dt_attach(dns_dtenv_t *source, dns_dtenv_t **destp);
/*%<
 * Attach '*destp' to 'source', incrementing the reference counter.
 *
 * Requires:
 *
 *\li	'source' is a valid dnstap environment.
 *
 *\li	'destp' is not NULL and '*destp' is NULL.
 *
 *\li	*destp is attached to source.
 */

void
dns_dt_detach(dns_dtenv_t **envp);
/*%<
 * Detach '*envp', decrementing the reference counter.
 *
 * Requires:
 *
 *\li	'*envp' is a valid dnstap environment.
 *
 * Ensures:
 *
 *\li	'*envp' will be destroyed when the number of references reaches zero.
 *
 *\li	'*envp' is NULL.
 */

isc_result_t
dns_dt_getstats(dns_dtenv_t *env, isc_stats_t **statsp);
/*%<
 * Attach to the stats struct if it exists.
 *
 * Requires:
 *
 *\li	'env' is a valid dnstap environment.
 *
 *\li	'statsp' is non NULL and '*statsp' is NULL.
 *
 * Returns:
 *
 *\li	ISC_R_SUCCESS
 *
 *\li	ISC_R_NOTFOUND
 */

void
dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype, isc_sockaddr_t *qaddr,
	    isc_sockaddr_t *dstaddr, bool tcp, isc_region_t *zone,
	    isc_time_t *qtime, isc_time_t *rtime, isc_buffer_t *buf);
/*%<
 * Sends a dnstap message to the log, if 'msgtype' is one of the message
 * types represented in 'view->dttypes'.
 *
 * Parameters are: 'qaddr' (query address, i.e, the address of the
 * query initiator); 'raddr' (response address, i.e., the address of
 * the query responder); 'tcp' (boolean indicating whether the transaction
 * was over TCP); 'zone' (the authoritative zone or bailiwick, in
 * uncompressed wire format), 'qtime' and 'rtime' (query and response
 * times; if NULL, they are set to the current time); and 'buf' (the
 * DNS message being logged, in wire format).
 *
 * Requires:
 *
 *\li	'view' is a valid view, and 'view->dtenv' is NULL or is a
 *	valid dnstap environment.
 */

isc_result_t
dns_dt_parse(isc_mem_t *mctx, isc_region_t *src, dns_dtdata_t **destp);
/*%<
 * Converts a raw dnstap frame in 'src' to a parsed dnstap data structure
 * in '*destp'.
 *
 * Requires:
 *\li	'src' is not NULL
 *
 *\li	'destp' is not NULL and '*destp' points to a valid buffer.
 *
 * Returns:
 *\li	#ISC_R_SUCCESS on success
 *
 *\li	Other errors are possible.
 */

isc_result_t
dns_dt_datatotext(dns_dtdata_t *d, isc_buffer_t **dest);
/*%<
 * Converts a parsed dnstap data structure 'd' to text, storing
 * the result in the buffer 'dest'.  If 'dest' points to a dynamically
 * allocated buffer, then it may be reallocated as needed.
 *
 * (XXX: add a 'long_form' option to generate a detailed listing of
 * dnstap data instead * of a one-line summary.)
 *
 * Requires:
 *\li	'd' is not NULL
 *
 *\li	'dest' is not NULL and '*dest' points to a valid buffer.
 *
 * Returns:
 *\li	#ISC_R_SUCCESS on success
 *\li	#ISC_R_NOSPACE if buffer is not dynamic and runs out of space
 *\li	#ISC_R_NOMEMORY if buffer is dynamic but memory could not be allocated
 *
 *\li	Other errors are possible.
 */

void
dns_dtdata_free(dns_dtdata_t **dp);
/*%<
 * Frees the specified dns_dtdata structure and all its members,
 * and sets *dp to NULL.
 */

isc_result_t
dns_dt_open(const char *filename, dns_dtmode_t mode, isc_mem_t *mctx,
	    dns_dthandle_t **handlep);
/*%<
 * Opens a dnstap framestream at 'filename' and stores a pointer to the
 * reader object in a dns_dthandle_t structure.
 *
 * The caller is responsible for allocating the handle structure.
 *
 * (XXX: Currently only file readers are supported, not unix-domain socket
 * readers.)
 *
 * Requires:
 *
 *\li	'filename' is not NULL.
 *
 *\li	'handlep' is not NULL and '*handlep' is NULL.
 *
 *\li	'*mctx' is not a valid memory context.
 *
 * Returns:
 *
 *\li	#ISC_R_SUCCESS on success
 *\li	#ISC_R_NOTIMPLEMENTED if 'mode' is not dns_dtmode_file. (XXX)
 *\li	#ISC_R_NOMEMORY if the fstrm library was unable to allocate a
 *      reader or options structure
 *\li	#ISC_R_FAILURE if 'filename' could not be opened.
 *\li	#DNS_R_BADDNSTAP if 'filename' does not contain a dnstap
 *      framestream.
 */

isc_result_t
dns_dt_getframe(dns_dthandle_t *handle, uint8_t **bufp, size_t *sizep);
/*%<
 * Read a dnstap frame from the framstream reader in 'handle', storing
 * a pointer to it in '*bufp' and its size in '*sizep'.
 *
 * Requires:
 *
 *\li	'handle' is not NULL
 *\li	'bufp' is not NULL
 *\li	'sizep' is not NULL
 *
 * Ensures:
 * \li	if returning ISC_R_SUCCESS then '*bufp' is not NULL
 *
 * Returns:
 *
 *\li	#ISC_R_SUCCESS on success
 *\li	#ISC_R_NOMORE at the end of the frame stream
 *\li	#ISC_R_FAILURE for any other failure
 */

void
dns_dt_close(dns_dthandle_t **handlep);
/*%<
 * Closes the dnstap file referenced by 'handle'.
 *
 * Requires:
 *
 *\li	'*handlep' is not NULL
 */