message.h 35.2 KB
Newer Older
1
/*
Mark Andrews's avatar
Mark Andrews committed
2
 * Copyright (C) 2004-2006  Internet Systems Consortium, Inc. ("ISC")
Mark Andrews's avatar
Mark Andrews committed
3
 * Copyright (C) 1999-2003  Internet Software Consortium.
4
 *
5 6 7
 * Permission to use, copy, modify, and distribute this software for any
 * 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
 */

18
/* $Id: message.h,v 1.119 2006/02/28 02:39:51 marka 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 37 38
/*! \file 
 * \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 105
#define DNS_MESSAGEEXTFLAG_DO		0x8000U

106
#define DNS_MESSAGE_REPLYPRESERVE	(DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD)
107
#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
108

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

111
#define DNS_MESSAGE_MAGIC		ISC_MAGIC('M','S','G','@')
Michael Graff's avatar
Michael Graff committed
112
#define DNS_MESSAGE_VALID(msg)		ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC)
Michael Graff's avatar
Michael Graff committed
113

Michael Graff's avatar
Michael Graff committed
114 115 116 117
/*
 * 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
118
typedef int dns_section_t;
Michael Graff's avatar
Michael Graff committed
119
#define DNS_SECTION_ANY			(-1)
Michael Graff's avatar
Michael Graff committed
120 121 122 123
#define DNS_SECTION_QUESTION		0
#define DNS_SECTION_ANSWER		1
#define DNS_SECTION_AUTHORITY		2
#define DNS_SECTION_ADDITIONAL		3
124
#define DNS_SECTION_MAX			4
125

126 127 128 129 130 131 132
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

133 134 135
typedef int dns_messagetextflag_t;
#define DNS_MESSAGETEXTFLAG_NOCOMMENTS	0x0001
#define DNS_MESSAGETEXTFLAG_NOHEADERS	0x0002
136

137
/*
Andreas Gustafsson's avatar
Andreas Gustafsson committed
138
 * Dynamic update names for these sections.
139 140 141 142
 */
#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
143 144

/*
Michael Graff's avatar
Michael Graff committed
145
 * These tell the message library how the created dns_message_t will be used.
Michael Graff's avatar
Michael Graff committed
146
 */
147 148 149
#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
150

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

Michael Graff's avatar
Michael Graff committed
163 164 165
/*
 * Control behavior of rendering
 */
166 167 168 169 170 171 172
#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
173

Michael Graff's avatar
Michael Graff committed
174 175
typedef struct dns_msgblock dns_msgblock_t;

Bob Halley's avatar
Bob Halley committed
176
struct dns_message {
Michael Graff's avatar
Michael Graff committed
177
	/* public from here down */
Michael Graff's avatar
Michael Graff committed
178
	unsigned int			magic;
179

180
	dns_messageid_t			id;
Michael Graff's avatar
Michael Graff committed
181
	unsigned int			flags;
182
	dns_rcode_t			rcode;
Michael Graff's avatar
Michael Graff committed
183
	unsigned int			opcode;
Michael Graff's avatar
Michael Graff committed
184
	dns_rdataclass_t		rdclass;
Michael Graff's avatar
Michael Graff committed
185

186
	/* 4 real, 1 pseudo */
Michael Graff's avatar
Michael Graff committed
187
	unsigned int			counts[DNS_SECTION_MAX];
Michael Graff's avatar
Michael Graff committed
188 189

	/* private from here down */
Michael Graff's avatar
Michael Graff committed
190 191
	dns_namelist_t			sections[DNS_SECTION_MAX];
	dns_name_t		       *cursors[DNS_SECTION_MAX];
Bob Halley's avatar
Bob Halley committed
192
	dns_rdataset_t		       *opt;
193
	dns_rdataset_t		       *sig0;
194
	dns_rdataset_t		       *tsig;
195

Michael Graff's avatar
Michael Graff committed
196
	int				state;
Michael Graff's avatar
Michael Graff committed
197
	unsigned int			from_to_wire : 2;
Bob Halley's avatar
Bob Halley committed
198 199
	unsigned int			header_ok : 1;
	unsigned int			question_ok : 1;
200
	unsigned int			tcp_continuation : 1;
201 202
	unsigned int			verified_sig : 1;
	unsigned int			verify_attempted : 1;
203 204
	unsigned int			free_query : 1;
	unsigned int			free_saved : 1;
205

206
	unsigned int			opt_reserved;
207
	unsigned int			sig_reserved;
208
	unsigned int			reserved; /* reserved space (render) */
209

210
	isc_buffer_t		       *buffer;
211
	dns_compress_t		       *cctx;
212

Michael Graff's avatar
Michael Graff committed
213
	isc_mem_t		       *mctx;
214 215 216
	isc_mempool_t		       *namepool;
	isc_mempool_t		       *rdspool;

217
	isc_bufferlist_t		scratchpad;
218 219
	isc_bufferlist_t		cleanup;

Michael Graff's avatar
Michael Graff committed
220 221
	ISC_LIST(dns_msgblock_t)	rdatas;
	ISC_LIST(dns_msgblock_t)	rdatalists;
222
	ISC_LIST(dns_msgblock_t)	offsets;
223 224 225

	ISC_LIST(dns_rdata_t)		freerdata;
	ISC_LIST(dns_rdatalist_t)	freerdatalist;
226 227 228

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

Andreas Gustafsson's avatar
Andreas Gustafsson committed
236
	dns_name_t		       *sig0name; /* Owner name of SIG0, if any */
237 238
	dst_key_t		       *sig0key;
	dns_rcode_t			sig0status;
239 240
	isc_region_t			query;
	isc_region_t			saved;
241 242

	dns_rdatasetorderfunc_t		order;
243
	const void *			order_arg;
Bob Halley's avatar
Bob Halley committed
244
};
245

246 247 248 249 250 251
/***
 *** Functions
 ***/

ISC_LANG_BEGINDECLS

252
isc_result_t
253
dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp);
254

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

Michael Graff's avatar
Michael Graff committed
278
void
Bob Halley's avatar
Bob Halley committed
279
dns_message_reset(dns_message_t *msg, unsigned int intent);
280
/*%<
Michael Graff's avatar
Michael Graff committed
281 282 283 284 285
 * 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
286 287 288
 * 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
289 290
 * The intended next use of the message will be 'intent'.
 *
Michael Graff's avatar
Michael Graff committed
291 292
 * Requires:
 *
293
 *\li	'msg' be valid.
Bob Halley's avatar
Bob Halley committed
294
 *
295
 *\li	'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER
Michael Graff's avatar
Michael Graff committed
296
 */
Michael Graff's avatar
Michael Graff committed
297

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

311 312
isc_result_t
dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
313
			  const dns_master_style_t *style,
314
			  dns_messagetextflag_t flags,
315
			  isc_buffer_t *target);
316 317 318 319

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

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

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

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

467
isc_result_t
468
dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
469
/*%<
470
 * Reset the buffer.  This can be used after growing the old buffer
471
 * on a ISC_R_NOSPACE return from most of the render functions.
472
 *
Michael Graff's avatar
Michael Graff committed
473 474 475 476
 * 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.
 *
477 478
 * Requires:
 *
479
 *\li	'msg' be valid.
480
 *
481
 *\li	dns_message_renderbegin() was called.
482
 *
483
 *\li	buffer != NULL.
484 485
 *
 * Returns:
486 487
 *\li	#ISC_R_NOSPACE		-- new buffer is too small
 *\li	#ISC_R_SUCCESS		-- all is well.
488 489
 */

490
isc_result_t
491
dns_message_renderreserve(dns_message_t *msg, unsigned int space);
492
/*%<
Michael Graff's avatar
Michael Graff committed
493 494 495
 * XXXMLG should use size_t rather than unsigned int once the buffer
 * API is cleaned up
 *
Michael Graff's avatar
Michael Graff committed
496 497 498 499
 * Reserve "space" bytes in the given buffer.
 *
 * Requires:
 *
500
 *\li	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
501
 *
502
 *\li	dns_message_renderbegin() was called.
503
 *
Michael Graff's avatar
Michael Graff committed
504
 * Returns:
505 506
 *\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
507 508
 */

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

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

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

565
isc_result_t
566
dns_message_renderend(dns_message_t *msg);
567
/*%<
Michael Graff's avatar
Michael Graff committed
568 569 570 571 572 573
 * 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:
 *
574
 *\li	'msg' be a valid message.
Michael Graff's avatar
Michael Graff committed
575
 *
576
 *\li	dns_message_renderbegin() was called.
577
 *
Michael Graff's avatar
Michael Graff committed
578
 * Returns:
579
 *\li	#ISC_R_SUCCESS		-- all is well.
Michael Graff's avatar
Michael Graff committed
580
 */
581

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

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

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

Michael Graff's avatar
Michael Graff committed
636
void
Michael Graff's avatar
Michael Graff committed
637 638
dns_message_currentname(dns_message_t *msg, dns_section_t section,
			dns_name_t **name);
639
/*%<
Michael Graff's avatar
Michael Graff committed
640 641 642
 * Sets 'name' to point to the name where the per-section internal name
 * pointer is currently set.
 *
Michael Graff's avatar
Michael Graff committed
643 644 645
 * 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
646 647
 * Requires:
 *
648
 *\li	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
649
 *
650
 *\li	'name' be non-NULL, and *name be NULL.
Michael Graff's avatar
Michael Graff committed
651
 *
652
 *\li	'section' be a valid section.
Michael Graff's avatar
Michael Graff committed
653
 *
654
 *\li	dns_message_firstname() must have been called on this section,
Michael Graff's avatar
Michael Graff committed
655
 *	and the result of it and any dns_message_nextname() calls was
656
 *	#ISC_R_SUCCESS.
Michael Graff's avatar
Michael Graff committed
657 658
 */

659
isc_result_t
Michael Graff's avatar
Michael Graff committed
660 661
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
662 663
		     dns_rdatatype_t covers, dns_name_t **foundname,
		     dns_rdataset_t **rdataset);
664
/*%<
Michael Graff's avatar
Michael Graff committed
665 666
 * 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
667
 * rdataset (if type is specified as other than dns_rdatatype_any).
Michael Graff's avatar
Michael Graff committed
668 669
 *
 * Requires:
670
 *\li	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
671
 *
672
 *\li	'section' be a valid section.
Michael Graff's avatar
Michael Graff committed
673
 *
674
 *\li	If a pointer to the name is desired, 'foundname' should be non-NULL.
Michael Graff's avatar
Michael Graff committed
675
 *	If it is non-NULL, '*foundname' MUST be NULL.
Michael Graff's avatar
Michael Graff committed
676
 *
677
 *\li	If a type other than dns_datatype_any is searched for, 'rdataset'
Michael Graff's avatar
Michael Graff committed
678
 *	may be non-NULL, '*rdataset' be NULL, and will point at the found
Michael Graff's avatar
Michael Graff committed
679
 *	rdataset.  If the type is dns_datatype_any, 'rdataset' must be NULL.
Michael Graff's avatar
Michael Graff committed
680
 *
681
 *\li	'target' be a valid name.
Michael Graff's avatar
Michael Graff committed
682
 *
683
 *\li	'type' be a valid type.
Michael Graff's avatar
Michael Graff committed
684
 *
685
 *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
686 687
 *	Otherwise it should be 0.
 *
Michael Graff's avatar
Michael Graff committed
688
 * Returns:
689 690 691
 *\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
692
 *				   type does not.
Michael Graff's avatar
Michael Graff committed
693 694
 */

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

715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735
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
736 737 738 739
void
dns_message_movename(dns_message_t *msg, dns_name_t *name,
		     dns_section_t fromsection,
		     dns_section_t tosection);
740
/*%<
Michael Graff's avatar
Michael Graff committed
741
 * Move a name from one section to another.
Michael Graff's avatar
Michael Graff committed
742 743 744
 *
 * Requires:
 *
745
 *\li	'msg' be valid.
Michael Graff's avatar
Michael Graff committed
746
 *
747
 *\li	'name' must be a name already in 'fromsection'.
Michael Graff's avatar
Michael Graff committed
748
 *
749
 *\li	'fromsection' must be a valid section.
Michael Graff's avatar
Michael Graff committed
750
 *
751
 *\li	'tosection' must be a valid section.
Michael Graff's avatar
Michael Graff committed
752 753
 */

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

772 773 774 775 776 777 778 779
/*
 * LOANOUT FUNCTIONS
 *
 * Each of these functions loan a particular type of data to the caller.
 * The storage for these will vanish when the message is destroyed or
 * reset, and must NOT be used after these operations.
 */

780
isc_result_t
781
dns_message_gettempname(dns_message_t *msg, dns_name_t **item);
782
/*%<
783
 * Return a name that can be used for any temporary purpose, including
784 785 786
 * inserting into the message's linked lists.  The name must be returned
 * to the message code using dns_message_puttempname() or inserted into
 * one of the message's sections before the message is destroyed.
787 788 789 790
 *
 * It is the caller's responsibility to initialize this name.
 *
 * Requires: