message.h 35.7 KB
Newer Older
1
/*
Automatic Updater's avatar
Automatic Updater committed
2
 * Copyright (C) 2004-2008  Internet Systems Consortium, Inc. ("ISC")
Mark Andrews's avatar
Mark Andrews committed
3
 * Copyright (C) 1999-2003  Internet Software Consortium.
4
 *
Automatic Updater's avatar
Automatic Updater committed
5
 * Permission to use, copy, modify, and/or distribute this software for any
6 7
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
8
 *
Mark Andrews's avatar
Mark Andrews committed
9 10 11 12 13 14 15
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
16 17
 */

Automatic Updater's avatar
Automatic Updater committed
18
/* $Id: message.h,v 1.125 2008/04/03 06:09:04 tbox Exp $ */
David Lawrence's avatar
David Lawrence committed
19

20 21
#ifndef DNS_MESSAGE_H
#define DNS_MESSAGE_H 1
22 23 24 25 26

/***
 ***	Imports
 ***/

27 28
#include <isc/lang.h>
#include <isc/magic.h>
29

Michael Graff's avatar
Michael Graff committed
30
#include <dns/compress.h>
31
#include <dns/masterdump.h>
32
#include <dns/types.h>
33

34 35
#include <dst/dst.h>

36
/*! \file dns/message.h
37 38
 * \brief Message Handling Module
 *
39 40
 * How this beast works:
 *
41
 * When a dns message is received in a buffer, dns_message_fromwire() is called
42 43 44 45 46
 * on the memory region.  Various items are checked including the format
 * of the message (if counts are right, if counts consume the entire sections,
 * and if sections consume the entire message) and known pseudo-RRs in the
 * additional data section are analyzed and removed.
 *
Brian Wellington's avatar
Brian Wellington committed
47 48
 * TSIG checking is also done at this layer, and any DNSSEC transaction
 * signatures should also be checked here.
49 50 51 52
 *
 * Notes on using the gettemp*() and puttemp*() functions:
 *
 * These functions return items (names, rdatasets, etc) allocated from some
53 54 55 56
 * internal state of the dns_message_t.
 *
 * Names and rdatasets must be put back into the dns_message_t in
 * one of two ways.  Assume a name was allocated via
57 58
 * dns_message_gettempname():
 *
59
 *\li	(1) insert it into a section, using dns_message_addname().
60
 *
61
 *\li	(2) return it to the message using dns_message_puttempname().
62
 *
63 64
 * The same applies to rdatasets.
 *
65
 * On the other hand, offsets, rdatalists and rdatas allocated using
66 67
 * dns_message_gettemp*() will always be freed automatically
 * when the message is reset or destroyed; calling dns_message_puttemp*()
68 69 70
 * on rdatalists and rdatas is optional and serves only to enable the item
 * to be reused multiple times during the lifetime of the message; offsets
 * cannot be reused.
71 72 73 74 75 76 77 78
 *
 * Buffers allocated using isc_buffer_allocate() can be automatically freed
 * as well by giving the buffer to the message using dns_message_takebuffer().
 * Doing this will cause the buffer to be freed using isc_buffer_free()
 * when the section lists are cleared, such as in a reset or in a destroy.
 * Since the buffer itself exists until the message is destroyed, this sort
 * of code can be written:
 *
79
 * \code
80
 *	buffer = isc_buffer_allocate(mctx, 512);
81 82 83 84 85 86
 *	name = NULL;
 *	name = dns_message_gettempname(message, &name);
 *	dns_name_init(name, NULL);
 *	result = dns_name_fromtext(name, &source, dns_rootname, ISC_FALSE,
 *				   buffer);
 *	dns_message_takebuffer(message, &buffer);
87
 * \endcode
88 89 90 91
 *
 *
 * TODO:
 *
Brian Wellington's avatar
Brian Wellington committed
92 93
 * XXX Needed:  ways to set and retrieve EDNS information, add rdata to a
 * section, move rdata from one section to another, remove rdata, etc.
94 95
 */

96 97 98 99 100
#define DNS_MESSAGEFLAG_QR		0x8000U
#define DNS_MESSAGEFLAG_AA		0x0400U
#define DNS_MESSAGEFLAG_TC		0x0200U
#define DNS_MESSAGEFLAG_RD		0x0100U
#define DNS_MESSAGEFLAG_RA		0x0080U
Bob Halley's avatar
Bob Halley committed
101 102
#define DNS_MESSAGEFLAG_AD		0x0020U
#define DNS_MESSAGEFLAG_CD		0x0010U
103

104
/*%< EDNS0 extended message flags */
105 106
#define DNS_MESSAGEEXTFLAG_DO		0x8000U

107 108 109
/*%< EDNS0 extended OPT codes */
#define DNS_OPT_NSID		0x0003		/*%< NSID opt code */

110
#define DNS_MESSAGE_REPLYPRESERVE	(DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD)
111
#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
112

113
#define DNS_MESSAGE_HEADERLEN		12 /*%< 6 isc_uint16_t's */
Bob Halley's avatar
Bob Halley committed
114

115
#define DNS_MESSAGE_MAGIC		ISC_MAGIC('M','S','G','@')
Michael Graff's avatar
Michael Graff committed
116
#define DNS_MESSAGE_VALID(msg)		ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC)
Michael Graff's avatar
Michael Graff committed
117

Michael Graff's avatar
Michael Graff committed
118 119 120 121
/*
 * Ordering here matters.  DNS_SECTION_ANY must be the lowest and negative,
 * and DNS_SECTION_MAX must be one greater than the last used section.
 */
Michael Graff's avatar
Michael Graff committed
122
typedef int dns_section_t;
Michael Graff's avatar
Michael Graff committed
123
#define DNS_SECTION_ANY			(-1)
Michael Graff's avatar
Michael Graff committed
124 125 126 127
#define DNS_SECTION_QUESTION		0
#define DNS_SECTION_ANSWER		1
#define DNS_SECTION_AUTHORITY		2
#define DNS_SECTION_ADDITIONAL		3
128
#define DNS_SECTION_MAX			4
129

130 131 132 133 134 135 136
typedef int dns_pseudosection_t;
#define DNS_PSEUDOSECTION_ANY		(-1)
#define DNS_PSEUDOSECTION_OPT           0
#define DNS_PSEUDOSECTION_TSIG          1
#define DNS_PSEUDOSECTION_SIG0          2
#define DNS_PSEUDOSECTION_MAX           3

137 138 139
typedef int dns_messagetextflag_t;
#define DNS_MESSAGETEXTFLAG_NOCOMMENTS	0x0001
#define DNS_MESSAGETEXTFLAG_NOHEADERS	0x0002
140

141
/*
Andreas Gustafsson's avatar
Andreas Gustafsson committed
142
 * Dynamic update names for these sections.
143 144 145 146
 */
#define DNS_SECTION_ZONE		DNS_SECTION_QUESTION
#define DNS_SECTION_PREREQUISITE	DNS_SECTION_ANSWER
#define DNS_SECTION_UPDATE		DNS_SECTION_AUTHORITY
Michael Graff's avatar
Michael Graff committed
147 148

/*
Michael Graff's avatar
Michael Graff committed
149
 * These tell the message library how the created dns_message_t will be used.
Michael Graff's avatar
Michael Graff committed
150
 */
151 152 153
#define DNS_MESSAGE_INTENTUNKNOWN	0 /*%< internal use only */
#define DNS_MESSAGE_INTENTPARSE		1 /*%< parsing messages */
#define DNS_MESSAGE_INTENTRENDER	2 /*%< rendering */
Michael Graff's avatar
Michael Graff committed
154

155 156 157
/*
 * Control behavior of parsing
 */
158 159
#define DNS_MESSAGEPARSE_PRESERVEORDER	0x0001	/*%< preserve rdata order */
#define DNS_MESSAGEPARSE_BESTEFFORT	0x0002	/*%< return a message if a
160 161
						   recoverable parse error
						   occurs */
162
#define DNS_MESSAGEPARSE_CLONEBUFFER	0x0004	/*%< save a copy of the
163
						   source buffer */
164
#define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< trucation errors are
165
						  * not fatal. */
166

Michael Graff's avatar
Michael Graff committed
167 168 169
/*
 * Control behavior of rendering
 */
170 171 172 173 174 175 176
#define DNS_MESSAGERENDER_ORDERED	0x0001	/*%< don't change order */
#define DNS_MESSAGERENDER_PARTIAL	0x0002	/*%< allow a partial rdataset */
#define DNS_MESSAGERENDER_OMITDNSSEC	0x0004	/*%< omit DNSSEC records */
#define DNS_MESSAGERENDER_PREFER_A	0x0008	/*%< prefer A records in
						      additional section. */
#define DNS_MESSAGERENDER_PREFER_AAAA	0x0010	/*%< prefer AAAA records in
						  additional section. */
Michael Graff's avatar
Michael Graff committed
177

Michael Graff's avatar
Michael Graff committed
178 179
typedef struct dns_msgblock dns_msgblock_t;

Bob Halley's avatar
Bob Halley committed
180
struct dns_message {
Michael Graff's avatar
Michael Graff committed
181
	/* public from here down */
Michael Graff's avatar
Michael Graff committed
182
	unsigned int			magic;
183

184
	dns_messageid_t			id;
Michael Graff's avatar
Michael Graff committed
185
	unsigned int			flags;
186
	dns_rcode_t			rcode;
Michael Graff's avatar
Michael Graff committed
187
	unsigned int			opcode;
Michael Graff's avatar
Michael Graff committed
188
	dns_rdataclass_t		rdclass;
Michael Graff's avatar
Michael Graff committed
189

190
	/* 4 real, 1 pseudo */
Michael Graff's avatar
Michael Graff committed
191
	unsigned int			counts[DNS_SECTION_MAX];
Michael Graff's avatar
Michael Graff committed
192 193

	/* private from here down */
Michael Graff's avatar
Michael Graff committed
194 195
	dns_namelist_t			sections[DNS_SECTION_MAX];
	dns_name_t		       *cursors[DNS_SECTION_MAX];
Bob Halley's avatar
Bob Halley committed
196
	dns_rdataset_t		       *opt;
197
	dns_rdataset_t		       *sig0;
198
	dns_rdataset_t		       *tsig;
199

Michael Graff's avatar
Michael Graff committed
200
	int				state;
Michael Graff's avatar
Michael Graff committed
201
	unsigned int			from_to_wire : 2;
Bob Halley's avatar
Bob Halley committed
202 203
	unsigned int			header_ok : 1;
	unsigned int			question_ok : 1;
204
	unsigned int			tcp_continuation : 1;
205 206
	unsigned int			verified_sig : 1;
	unsigned int			verify_attempted : 1;
207 208
	unsigned int			free_query : 1;
	unsigned int			free_saved : 1;
209

210
	unsigned int			opt_reserved;
211
	unsigned int			sig_reserved;
212
	unsigned int			reserved; /* reserved space (render) */
213

214
	isc_buffer_t		       *buffer;
215
	dns_compress_t		       *cctx;
216

Michael Graff's avatar
Michael Graff committed
217
	isc_mem_t		       *mctx;
218 219 220
	isc_mempool_t		       *namepool;
	isc_mempool_t		       *rdspool;

221
	isc_bufferlist_t		scratchpad;
222 223
	isc_bufferlist_t		cleanup;

Michael Graff's avatar
Michael Graff committed
224 225
	ISC_LIST(dns_msgblock_t)	rdatas;
	ISC_LIST(dns_msgblock_t)	rdatalists;
226
	ISC_LIST(dns_msgblock_t)	offsets;
227 228 229

	ISC_LIST(dns_rdata_t)		freerdata;
	ISC_LIST(dns_rdatalist_t)	freerdatalist;
230 231 232

	dns_rcode_t			tsigstatus;
	dns_rcode_t			querytsigstatus;
Andreas Gustafsson's avatar
Andreas Gustafsson committed
233
	dns_name_t		       *tsigname; /* Owner name of TSIG, if any */
234
	dns_rdataset_t		       *querytsig;
235
	dns_tsigkey_t		       *tsigkey;
Brian Wellington's avatar
Brian Wellington committed
236
	dst_context_t		       *tsigctx;
237
	int				sigstart;
238
	int				timeadjust;
239

Andreas Gustafsson's avatar
Andreas Gustafsson committed
240
	dns_name_t		       *sig0name; /* Owner name of SIG0, if any */
241 242
	dst_key_t		       *sig0key;
	dns_rcode_t			sig0status;
243 244
	isc_region_t			query;
	isc_region_t			saved;
245 246

	dns_rdatasetorderfunc_t		order;
247
	const void *			order_arg;
Bob Halley's avatar
Bob Halley committed
248
};
249

250 251 252 253 254 255
/***
 *** Functions
 ***/

ISC_LANG_BEGINDECLS

256
isc_result_t
257
dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp);
258

259
/*%<
Michael Graff's avatar
Michael Graff committed
260
 * Create msg structure.
261
 *
Michael Graff's avatar
Michael Graff committed
262
 * This function will allocate some internal blocks of memory that are
Michael Graff's avatar
Michael Graff committed
263
 * expected to be needed for parsing or rendering nearly any type of message.
Michael Graff's avatar
Michael Graff committed
264 265
 *
 * Requires:
266
 *\li	'mctx' be a valid memory context.
267
 *
268
 *\li	'msgp' be non-null and '*msg' be NULL.
Michael Graff's avatar
Michael Graff committed
269
 *
270 271
 *\li	'intent' must be one of DNS_MESSAGE_INTENTPARSE or
 *	#DNS_MESSAGE_INTENTRENDER.
Michael Graff's avatar
Michael Graff committed
272 273
 *
 * Ensures:
274
 *\li	The data in "*msg" is set to indicate an unused and empty msg
Michael Graff's avatar
Michael Graff committed
275 276 277
 *	structure.
 *
 * Returns:
278 279
 *\li	#ISC_R_NOMEMORY		-- out of memory
 *\li	#ISC_R_SUCCESS		-- success
280 281
 */

Michael Graff's avatar
Michael Graff committed
282
void
Bob Halley's avatar
Bob Halley committed
283
dns_message_reset(dns_message_t *msg, unsigned int intent);
284
/*%<
Michael Graff's avatar
Michael Graff committed
285 286 287 288 289
 * Reset a message structure to default state.  All internal lists are freed
 * or reset to a default state as well.  This is simply a more efficient
 * way to call dns_message_destroy() followed by dns_message_allocate(),
 * since it avoid many memory allocations.
 *
Michael Graff's avatar
Michael Graff committed
290 291 292
 * If any data loanouts (buffers, names, rdatas, etc) were requested,
 * the caller must no longer use them after this call.
 *
Bob Halley's avatar
Bob Halley committed
293 294
 * The intended next use of the message will be 'intent'.
 *
Michael Graff's avatar
Michael Graff committed
295 296
 * Requires:
 *
297
 *\li	'msg' be valid.
Bob Halley's avatar
Bob Halley committed
298
 *
299
 *\li	'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER
Michael Graff's avatar
Michael Graff committed
300
 */
Michael Graff's avatar
Michael Graff committed
301

Michael Graff's avatar
Michael Graff committed
302
void
Michael Graff's avatar
Michael Graff committed
303
dns_message_destroy(dns_message_t **msgp);
304
/*%<
Michael Graff's avatar
Michael Graff committed
305 306 307 308
 * Destroy all state in the message.
 *
 * Requires:
 *
309
 *\li	'msgp' be valid.
Michael Graff's avatar
Michael Graff committed
310 311
 *
 * Ensures:
312
 *\li	'*msgp' == NULL
Michael Graff's avatar
Michael Graff committed
313 314
 */

315 316
isc_result_t
dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
317
			  const dns_master_style_t *style,
318
			  dns_messagetextflag_t flags,
319
			  isc_buffer_t *target);
320 321 322 323

isc_result_t
dns_message_pseudosectiontotext(dns_message_t *msg,
				dns_pseudosection_t section,
324
				const dns_master_style_t *style,
325
				dns_messagetextflag_t flags,
326
				isc_buffer_t *target);
327
/*%<
328
 * Convert section 'section' or 'pseudosection' of message 'msg' to
329
 * a cleartext representation
330 331
 *
 * Notes:
332
 *     \li See dns_message_totext for meanings of flags.
333 334 335
 *
 * Requires:
 *
336
 *\li	'msg' is a valid message.
337
 *
338
 *\li	'style' is a valid master dump style.
339
 *
340
 *\li	'target' is a valid buffer.
341
 *
342
 *\li	'section' is a valid section label.
343 344 345
 *
 * Ensures:
 *
346
 *\li	If the result is success:
347 348 349 350
 *		The used space in 'target' is updated.
 *
 * Returns:
 *
351 352 353
 *\li	#ISC_R_SUCCESS
 *\li	#ISC_R_NOSPACE
 *\li	#ISC_R_NOMORE
354
 *
355
 *\li	Note: On error return, *target may be partially filled with data.
356 357 358
*/

isc_result_t
359 360
dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
		   dns_messagetextflag_t flags, isc_buffer_t *target);
361
/*%<
362 363 364
 * Convert all sections of message 'msg' to a cleartext representation
 *
 * Notes:
365
 * \li     In flags, If #DNS_MESSAGETEXTFLAG_OMITDOT is set, then the
366
 *      final '.' in absolute names will not be emitted.  If
367
 *      #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning
368
 *      with ";;" will be emitted indicating section name.  If
369
 *      #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will
370
 *      be emitted.
371 372 373
 *
 * Requires:
 *
374
 *\li	'msg' is a valid message.
375
 *
376
 *\li	'style' is a valid master dump style.
377
 *
378
 *\li	'target' is a valid buffer.
379 380 381
 *
 * Ensures:
 *
382
 *\li	If the result is success:
383 384 385 386
 *		The used space in 'target' is updated.
 *
 * Returns:
 *
387 388 389
 *\li	#ISC_R_SUCCESS
 *\li	#ISC_R_NOSPACE
 *\li	#ISC_R_NOMORE
390
 *
391
 *\li	Note: On error return, *target may be partially filled with data.
392
 */
393

394
isc_result_t
395
dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
396
		  unsigned int options);
397
/*%<
398
 * Parse raw wire data in 'source' as a DNS message.
Michael Graff's avatar
Michael Graff committed
399 400
 *
 * OPT records are detected and stored in the pseudo-section "opt".
Brian Wellington's avatar
Brian Wellington committed
401
 * TSIGs are detected and stored in the pseudo-section "tsig".
Michael Graff's avatar
Michael Graff committed
402
 *
403
 * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message
404 405
 * is UPDATE, a separate dns_name_t object will be created for each RR in the
 * message.  Each such dns_name_t will have a single rdataset containing the
Brian Wellington's avatar
Brian Wellington committed
406
 * single RR, and the order of the RRs in the message is preserved.
407 408
 * Otherwise, only one dns_name_t object will be created for each unique
 * owner name in the section, and each such dns_name_t will have a list
409 410
 * of rdatasets.  To access the names and their data, use
 * dns_message_firstname() and dns_message_nextname().
411
 *
412
 * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
413 414 415
 * not be considered FORMERRs.  If the entire message can be parsed, it
 * will be returned and DNS_R_RECOVERABLE will be returned.
 *
416
 * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
417 418
 * RR's as possible, DNS_R_RECOVERABLE will be returned.
 *
419 420 421
 * OPT and TSIG records are always handled specially, regardless of the
 * 'preserve_order' setting.
 *
Michael Graff's avatar
Michael Graff committed
422
 * Requires:
423
 *\li	"msg" be valid.
Michael Graff's avatar
Michael Graff committed
424
 *
425
 *\li	"buffer" be a wire format buffer.
Michael Graff's avatar
Michael Graff committed
426 427
 *
 * Ensures:
428
 *\li	The buffer's data format is correct.
Michael Graff's avatar
Michael Graff committed
429
 *
430
 *\li	The buffer's contents verify as correct regarding header bits, buffer
Michael Graff's avatar
Michael Graff committed
431
 * 	and rdata sizes, etc.
Michael Graff's avatar
Michael Graff committed
432 433
 *
 * Returns:
434 435 436
 *\li	#ISC_R_SUCCESS		-- all is well
 *\li	#ISC_R_NOMEMORY		-- no memory
 *\li	#DNS_R_RECOVERABLE	-- the message parsed properly, but contained
437
 *				   errors.
438
 *\li	Many other errors possible XXXMLG
Michael Graff's avatar
Michael Graff committed
439 440
 */

441
isc_result_t
442 443
dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
			isc_buffer_t *buffer);
444
/*%<
Michael Graff's avatar
Michael Graff committed
445 446
 * Begin rendering on a message.  Only one call can be made to this function
 * per message.
Michael Graff's avatar
Michael Graff committed
447
 *
448 449 450
 * The compression context is "owned" by the message library until
 * dns_message_renderend() is called.  It must be invalidated by the caller.
 *
Andreas Gustafsson's avatar
Andreas Gustafsson committed
451
 * The buffer is "owned" by the message library until dns_message_renderend()
Michael Graff's avatar
Michael Graff committed
452 453
 * is called.
 *
Michael Graff's avatar
Michael Graff committed
454
 * Requires:
Michael Graff's avatar
Michael Graff committed
455
 *
456
 *\li	'msg' be valid.
457
 *
458
 *\li	'cctx' be valid.
459
 *
460
 *\li	'buffer' is a valid buffer.
Michael Graff's avatar
Michael Graff committed
461 462 463
 *
 * Side Effects:
 *
464
 *\li	The buffer is cleared before it is used.
465
 *
Michael Graff's avatar
Michael Graff committed
466
 * Returns:
467 468
 *\li	#ISC_R_SUCCESS		-- all is well
 *\li	#ISC_R_NOSPACE		-- output buffer is too small
Michael Graff's avatar
Michael Graff committed
469 470
 */

471
isc_result_t
472
dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
473
/*%<
474
 * Reset the buffer.  This can be used after growing the old buffer
475
 * on a ISC_R_NOSPACE return from most of the render functions.
476
 *
Michael Graff's avatar
Michael Graff committed
477 478 479 480
 * On successful completion, the old buffer is no longer used by the
 * library.  The new buffer is owned by the library until
 * dns_message_renderend() is called.
 *
481 482
 * Requires:
 *
483
 *\li	'msg' be valid.
484
 *
485
 *\li	dns_message_renderbegin() was called.
486
 *
487
 *\li	buffer != NULL.
488 489
 *
 * Returns:
490 491
 *\li	#ISC_R_NOSPACE		-- new buffer is too small
 *\li	#ISC_R_SUCCESS		-- all is well.
492 493
 */

494
isc_result_t
495
dns_message_renderreserve(dns_message_t *msg, unsigned int space);
496
/*%<
Michael Graff's avatar
Michael Graff committed
497 498 499
 * XXXMLG should use size_t rather than unsigned int once the buffer
 * API is cleaned up
 *
Michael Graff's avatar
Michael Graff committed
500 501 502 503
 * Reserve "space" bytes in the given buffer.
 *
 * Requires:
 *
504
 *\li	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
505
 *
506
 *\li	dns_message_renderbegin() was called.
507
 *
Michael Graff's avatar
Michael Graff committed
508
 * Returns:
509 510
 *\li	#ISC_R_SUCCESS		-- all is well.
 *\li	#ISC_R_NOSPACE		-- not enough free space in the buffer.
Michael Graff's avatar
Michael Graff committed
511 512
 */

513
void
Michael Graff's avatar
Michael Graff committed
514
dns_message_renderrelease(dns_message_t *msg, unsigned int space);
515
/*%<
Michael Graff's avatar
Michael Graff committed
516 517 518
 * XXXMLG should use size_t rather than unsigned int once the buffer
 * API is cleaned up
 *
Michael Graff's avatar
Michael Graff committed
519 520 521 522
 * Release "space" bytes in the given buffer that was previously reserved.
 *
 * Requires:
 *
523
 *\li	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
524
 *
525
 *\li	'space' is less than or equal to the total amount of space reserved
526
 *	via prior calls to dns_message_renderreserve().
527
 *
528
 *\li	dns_message_renderbegin() was called.
Michael Graff's avatar
Michael Graff committed
529 530
 */

531
isc_result_t
532
dns_message_rendersection(dns_message_t *msg, dns_section_t section,
Michael Graff's avatar
Michael Graff committed
533
			  unsigned int options);
534
/*%<
Michael Graff's avatar
Michael Graff committed
535 536
 * Render all names, rdatalists, etc from the given section at the
 * specified priority or higher.
Michael Graff's avatar
Michael Graff committed
537 538
 *
 * Requires:
539
 *\li	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
540
 *
541
 *\li	'section' be a valid section.
Michael Graff's avatar
Michael Graff committed
542
 *
543
 *\li	dns_message_renderbegin() was called.
544
 *
Michael Graff's avatar
Michael Graff committed
545
 * Returns:
546
 *\li	#ISC_R_SUCCESS		-- all records were written, and there are
Michael Graff's avatar
Michael Graff committed
547
 *				   no more records for this section.
548
 *\li	#ISC_R_NOSPACE		-- Not enough room in the buffer to write
Michael Graff's avatar
Michael Graff committed
549
 *				   all records requested.
550
 *\li	#DNS_R_MOREDATA		-- All requested records written, and there
Michael Graff's avatar
Michael Graff committed
551
 *				   are records remaining for this section.
Michael Graff's avatar
Michael Graff committed
552 553
 */

554 555
void
dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
556
/*%<
557 558 559 560 561
 * Render the message header.  This is implicitly called by
 * dns_message_renderend().
 *
 * Requires:
 *
562
 *\li	'msg' be a valid message.
563
 *
564
 *\li	dns_message_renderbegin() was called.
565
 *
566
 *\li	'target' is a valid buffer with enough space to hold a message header
567 568
 */

569
isc_result_t
570
dns_message_renderend(dns_message_t *msg);
571
/*%<
Michael Graff's avatar
Michael Graff committed
572 573 574 575 576 577
 * Finish rendering to the buffer.  Note that more data can be in the
 * 'msg' structure.  Destroying the structure will free this, or in a multi-
 * part EDNS1 message this data can be rendered to another buffer later.
 *
 * Requires:
 *
578
 *\li	'msg' be a valid message.
Michael Graff's avatar
Michael Graff committed
579
 *
580
 *\li	dns_message_renderbegin() was called.
581
 *
Michael Graff's avatar
Michael Graff committed
582
 * Returns:
583
 *\li	#ISC_R_SUCCESS		-- all is well.
Michael Graff's avatar
Michael Graff committed
584
 */
585

Bob Halley's avatar
Bob Halley committed
586 587
void
dns_message_renderreset(dns_message_t *msg);
588
/*%<
Bob Halley's avatar
Bob Halley committed
589 590 591 592
 * Reset the message so that it may be rendered again.
 *
 * Notes:
 *
593
 *\li	If dns_message_renderbegin() has been called, dns_message_renderend()
Bob Halley's avatar
Bob Halley committed
594 595 596 597
 *	must be called before calling this function.
 *
 * Requires:
 *
598
 *\li	'msg' be a valid message with rendering intent.
Bob Halley's avatar
Bob Halley committed
599
 */
Michael Graff's avatar
Michael Graff committed
600

601
isc_result_t
Michael Graff's avatar
Michael Graff committed
602
dns_message_firstname(dns_message_t *msg, dns_section_t section);
603
/*%<
Michael Graff's avatar
Michael Graff committed
604 605
 * Set internal per-section name pointer to the beginning of the section.
 *
Michael Graff's avatar
Michael Graff committed
606
 * The functions dns_message_firstname() and dns_message_nextname() may
607
 * be used for iterating over the owner names in a section.
Michael Graff's avatar
Michael Graff committed
608
 *
Michael Graff's avatar
Michael Graff committed
609 610
 * Requires:
 *
611
 *\li   	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
612
 *
613
 *\li	'section' be a valid section.
Michael Graff's avatar
Michael Graff committed
614 615
 *
 * Returns:
616 617
 *\li	#ISC_R_SUCCESS		-- All is well.
 *\li	#ISC_R_NOMORE		-- No names on given section.
Michael Graff's avatar
Michael Graff committed
618 619
 */

620
isc_result_t
Michael Graff's avatar
Michael Graff committed
621
dns_message_nextname(dns_message_t *msg, dns_section_t section);
622
/*%<
Michael Graff's avatar
Michael Graff committed
623 624 625 626 627
 * Sets the internal per-section name pointer to point to the next name
 * in that section.
 *
 * Requires:
 *
628
 * \li  	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
629
 *
630
 *\li	'section' be a valid section.
Michael Graff's avatar
Michael Graff committed
631
 *
632
 *\li	dns_message_firstname() must have been called on this section,
633
 *	and the result was ISC_R_SUCCESS.
Michael Graff's avatar
Michael Graff committed
634
 *
Michael Graff's avatar
Michael Graff committed
635
 * Returns:
636 637
 *\li	#ISC_R_SUCCESS		-- All is well.
 *\li	#ISC_R_NOMORE		-- No more names in given section.
Michael Graff's avatar
Michael Graff committed
638 639
 */

Michael Graff's avatar
Michael Graff committed
640
void
Michael Graff's avatar
Michael Graff committed
641 642
dns_message_currentname(dns_message_t *msg, dns_section_t section,
			dns_name_t **name);
643
/*%<
Michael Graff's avatar
Michael Graff committed
644 645 646
 * Sets 'name' to point to the name where the per-section internal name
 * pointer is currently set.
 *
Michael Graff's avatar
Michael Graff committed
647 648 649
 * This function returns the name in the database, so any data associated
 * with it (via the name's "list" member) contains the actual rdatasets.
 *
Michael Graff's avatar
Michael Graff committed
650 651
 * Requires:
 *
652
 *\li	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
653
 *
654
 *\li	'name' be non-NULL, and *name be NULL.
Michael Graff's avatar
Michael Graff committed
655
 *
656
 *\li	'section' be a valid section.
Michael Graff's avatar
Michael Graff committed
657
 *
658
 *\li	dns_message_firstname() must have been called on this section,
Michael Graff's avatar
Michael Graff committed
659
 *	and the result of it and any dns_message_nextname() calls was
660
 *	#ISC_R_SUCCESS.
Michael Graff's avatar
Michael Graff committed
661 662
 */

663
isc_result_t
Michael Graff's avatar
Michael Graff committed
664 665
dns_message_findname(dns_message_t *msg, dns_section_t section,
		     dns_name_t *target, dns_rdatatype_t type,
Bob Halley's avatar
Bob Halley committed
666 667
		     dns_rdatatype_t covers, dns_name_t **foundname,
		     dns_rdataset_t **rdataset);
668
/*%<
Michael Graff's avatar
Michael Graff committed
669 670
 * Search for a name in the specified section.  If it is found, *name is
 * set to point to the name, and *rdataset is set to point to the found
Bob Halley's avatar
Bob Halley committed
671
 * rdataset (if type is specified as other than dns_rdatatype_any).
Michael Graff's avatar
Michael Graff committed
672 673
 *
 * Requires:
674
 *\li	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
675
 *
676
 *\li	'section' be a valid section.
Michael Graff's avatar
Michael Graff committed
677
 *
678
 *\li	If a pointer to the name is desired, 'foundname' should be non-NULL.
Michael Graff's avatar
Michael Graff committed
679
 *	If it is non-NULL, '*foundname' MUST be NULL.
Michael Graff's avatar
Michael Graff committed
680
 *
681
 *\li	If a type other than dns_datatype_any is searched for, 'rdataset'
Michael Graff's avatar
Michael Graff committed
682
 *	may be non-NULL, '*rdataset' be NULL, and will point at the found
Michael Graff's avatar
Michael Graff committed
683
 *	rdataset.  If the type is dns_datatype_any, 'rdataset' must be NULL.
Michael Graff's avatar
Michael Graff committed
684
 *
685
 *\li	'target' be a valid name.
Michael Graff's avatar
Michael Graff committed
686
 *
687
 *\li	'type' be a valid type.
Michael Graff's avatar
Michael Graff committed
688
 *
689
 *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
690 691
 *	Otherwise it should be 0.
 *
Michael Graff's avatar
Michael Graff committed
692
 * Returns:
693 694 695
 *\li	#ISC_R_SUCCESS		-- all is well.
 *\li	#DNS_R_NXDOMAIN		-- name does not exist in that section.
 *\li	#DNS_R_NXRRSET		-- The name does exist, but the desired
Michael Graff's avatar
Michael Graff committed
696
 *				   type does not.
Michael Graff's avatar
Michael Graff committed
697 698
 */

699
isc_result_t
700 701
dns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
		     dns_rdatatype_t covers, dns_rdataset_t **rdataset);
702
/*%<
703 704 705 706
 * Search the name for the specified type.  If it is found, *rdataset is
 * filled in with a pointer to that rdataset.
 *
 * Requires:
707
 *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
708
 *
709
 *\li	'type' be a valid type, and NOT dns_rdatatype_any.
710
 *
711
 *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
712 713
 *	Otherwise it should be 0.
 *
714
 * Returns:
715 716
 *\li	#ISC_R_SUCCESS		-- all is well.
 *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
717 718
 */

719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
isc_result_t
dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
		 dns_rdatatype_t type, dns_rdatatype_t covers,
		 dns_rdataset_t **rdataset);
/*%<
 * Search the name for the specified rdclass and type.  If it is found,
 * *rdataset is filled in with a pointer to that rdataset.
 *
 * Requires:
 *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
 *
 *\li	'type' be a valid type, and NOT dns_rdatatype_any.
 *
 *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
 *	Otherwise it should be 0.
 *
 * Returns:
 *\li	#ISC_R_SUCCESS		-- all is well.
 *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
 */

Michael Graff's avatar
Michael Graff committed
740 741 742 743
void
dns_message_movename(dns_message_t *msg, dns_name_t *name,
		     dns_section_t fromsection,
		     dns_section_t tosection);
744
/*%<
Michael Graff's avatar
Michael Graff committed
745
 * Move a name from one section to another.
Michael Graff's avatar
Michael Graff committed
746 747 748
 *
 * Requires:
 *
749
 *\li	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
750
 *
751
 *\li	'name' must be a name already in 'fromsection'.
Michael Graff's avatar
Michael Graff committed
752
 *
753
 *\li	'fromsection' must be a valid section.
Michael Graff's avatar
Michael Graff committed
754
 *
755
 *\li	'tosection' must be a valid section.
Michael Graff's avatar
Michael Graff committed
756 757
 */

Michael Graff's avatar
Michael Graff committed
758 759 760
void
dns_message_addname(dns_message_t *msg, dns_name_t *name,
		    dns_section_t section);
761
/*%<
Michael Graff's avatar
Michael Graff committed
762 763
 * Adds the name to the given section.
 *
Michael Graff's avatar
Michael Graff committed
764 765
 * It is the caller's responsibility to enforce any unique name requirements
 * in a section.
Michael Graff's avatar
Michael Graff committed
766 767 768
 *
 * Requires:
 *
769
 *\li	'msg' be valid, and be a renderable message.
Michael Graff's avatar
Michael Graff committed
770
 *
771
 *\li	'name' be a valid absolute name.
Michael Graff's avatar
Michael Graff committed
772
 *
773
 *\li	'section' be a named section.
Michael Graff's avatar
Michael Graff committed
774
 */
775

776 777
void
dns_message_removename(dns_message_t *msg, dns_name_t *name,
778
		       dns_section_t section);
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
/*%<
 * Remove a existing name from a given section.
 *
 * It is the caller's responsibility to ensure the name is part of the
 * given section.
 *
 * Requires:
 *
 *\li	'msg' be valid, and be a renderable message.
 *
 *\li	'name' be a valid absolute name.