1/*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef DNS_MESSAGE_H
18#define DNS_MESSAGE_H 1
19
20/***
21 ***	Imports
22 ***/
23
24#include <dns/compress.h>
25#include <dns/masterdump.h>
26#include <dns/types.h>
27
28#include <dst/dst.h>
29
30/*! \file dns/message.h
31 * \brief Message Handling Module
32 *
33 * How this beast works:
34 *
35 * When a dns message is received in a buffer, dns_message_parse() is called
36 * on the memory region.  Various items are checked including the format
37 * of the message (if counts are right, if counts consume the entire sections,
38 * and if sections consume the entire message) and known pseudo-RRs in the
39 * additional data section are analyzed and removed.
40 *
41 * TSIG checking is also done at this layer, and any DNSSEC transaction
42 * signatures should also be checked here.
43 *
44 * Notes on using the gettemp*() and puttemp*() functions:
45 *
46 * These functions return items (names, rdatasets, etc) allocated from some
47 * internal state of the dns_message_t.
48 *
49 * Names and rdatasets must be put back into the dns_message_t in
50 * one of two ways.  Assume a name was allocated via
51 * dns_message_gettempname():
52 *
53 *\li	(1) insert it into a section, using dns_message_addname().
54 *
55 *\li	(2) return it to the message using dns_message_puttempname().
56 *
57 * The same applies to rdatasets.
58 *
59 * On the other hand, offsets, rdatalists and rdatas allocated using
60 * dns_message_gettemp*() will always be freed automatically
61 * when the message is reset or destroyed; calling dns_message_puttemp*()
62 * on rdatalists and rdatas is optional and serves only to enable the item
63 * to be reused multiple times during the lifetime of the message; offsets
64 * cannot be reused.
65 *
66 * Buffers allocated using isc_buffer_allocate() can be automatically freed
67 * as well by giving the buffer to the message using dns_message_takebuffer().
68 * Doing this will cause the buffer to be freed using isc_buffer_free()
69 * when the section lists are cleared, such as in a reset or in a destroy.
70 * Since the buffer itself exists until the message is destroyed, this sort
71 * of code can be written:
72 *
73 * \code
74 *	buffer = isc_buffer_allocate(mctx, 512);
75 *	name = NULL;
76 *	name = dns_message_gettempname(message, &name);
77 *	dns_name_init(name, NULL);
78 *	result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer);
79 *	dns_message_takebuffer(message, &buffer);
80 * \endcode
81 *
82 *
83 * TODO:
84 *
85 * XXX Needed:  ways to set and retrieve EDNS information, add rdata to a
86 * section, move rdata from one section to another, remove rdata, etc.
87 */
88
89#define DNS_MESSAGEFLAG_QR		0x8000U
90#define DNS_MESSAGEFLAG_AA		0x0400U
91#define DNS_MESSAGEFLAG_TC		0x0200U
92#define DNS_MESSAGEFLAG_RD		0x0100U
93#define DNS_MESSAGEFLAG_RA		0x0080U
94#define DNS_MESSAGEFLAG_AD		0x0020U
95#define DNS_MESSAGEFLAG_CD		0x0010U
96
97/*%< EDNS0 extended message flags */
98#define DNS_MESSAGEEXTFLAG_DO		0x8000U
99
100/*%< EDNS0 extended OPT codes */
101#define DNS_OPT_NSID		3		/*%< NSID opt code */
102#define DNS_OPT_CLIENT_SUBNET	8		/*%< client subnet opt code */
103#define DNS_OPT_EXPIRE		9		/*%< EXPIRE opt code */
104#define DNS_OPT_COOKIE		10		/*%< COOKIE opt code */
105#define DNS_OPT_PAD		12		/*%< PAD opt code */
106#define DNS_OPT_KEY_TAG		14		/*%< Key tag opt code */
107#define DNS_OPT_EDE		15		/* RFC 8914 */
108
109/*%< The number of EDNS options we know about. */
110#define DNS_EDNSOPTIONS	4
111
112#define DNS_MESSAGE_REPLYPRESERVE	(DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD)
113#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
114
115#define DNS_MESSAGE_HEADERLEN		12 /*%< 6 uint16_t's */
116
117/*
118 * Ordering here matters.  DNS_SECTION_ANY must be the lowest and negative,
119 * and DNS_SECTION_MAX must be one greater than the last used section.
120 */
121typedef int dns_section_t;
122#define DNS_SECTION_ANY			(-1)
123#define DNS_SECTION_QUESTION		0
124#define DNS_SECTION_ANSWER		1
125#define DNS_SECTION_AUTHORITY		2
126#define DNS_SECTION_ADDITIONAL		3
127#define DNS_SECTION_MAX			4
128
129typedef int dns_pseudosection_t;
130#define DNS_PSEUDOSECTION_ANY		(-1)
131#define DNS_PSEUDOSECTION_OPT           0
132#define DNS_PSEUDOSECTION_TSIG          1
133#define DNS_PSEUDOSECTION_SIG0          2
134#define DNS_PSEUDOSECTION_MAX           3
135
136typedef int dns_messagetextflag_t;
137#define DNS_MESSAGETEXTFLAG_NOCOMMENTS	0x0001
138#define DNS_MESSAGETEXTFLAG_NOHEADERS	0x0002
139#define DNS_MESSAGETEXTFLAG_ONESOA	0x0004
140#define DNS_MESSAGETEXTFLAG_OMITSOA	0x0008
141
142/*
143 * Dynamic update names for these sections.
144 */
145#define DNS_SECTION_ZONE		DNS_SECTION_QUESTION
146#define DNS_SECTION_PREREQUISITE	DNS_SECTION_ANSWER
147#define DNS_SECTION_UPDATE		DNS_SECTION_AUTHORITY
148
149/*
150 * These tell the message library how the created dns_message_t will be used.
151 */
152#define DNS_MESSAGE_INTENTUNKNOWN	0 /*%< internal use only */
153#define DNS_MESSAGE_INTENTPARSE		1 /*%< parsing messages */
154#define DNS_MESSAGE_INTENTRENDER	2 /*%< rendering */
155
156/*
157 * Control behavior of parsing
158 */
159#define DNS_MESSAGEPARSE_BESTEFFORT	0x0002	/*%< return a message if a
160						   recoverable parse error
161						   occurs */
162#define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< truncation errors are
163						  * not fatal. */
164
165typedef struct dns_msgblock dns_msgblock_t;
166
167struct dns_message {
168	/* public from here down */
169	dns_messageid_t			id;
170	unsigned int			flags;
171	dns_rcode_t			rcode;
172	dns_opcode_t			opcode;
173	dns_rdataclass_t		rdclass;
174
175	/* 4 real, 1 pseudo */
176	unsigned int			counts[DNS_SECTION_MAX];
177
178	/* private from here down */
179	dns_namelist_t			sections[DNS_SECTION_MAX];
180	dns_name_t		       *cursors[DNS_SECTION_MAX];
181	dns_rdataset_t		       *opt;
182	dns_rdataset_t		       *sig0;
183	dns_rdataset_t		       *tsig;
184
185	int				state;
186	unsigned int			from_to_wire : 2;
187	unsigned int			header_ok : 1;
188	unsigned int			question_ok : 1;
189	unsigned int			tcp_continuation : 1;
190	unsigned int			verified_sig : 1;
191	unsigned int			verify_attempted : 1;
192	unsigned int			free_query : 1;
193	unsigned int			free_saved : 1;
194	unsigned int			sitok : 1;
195	unsigned int			sitbad : 1;
196	unsigned int			tkey : 1;
197	unsigned int			rdclass_set : 1;
198
199	unsigned int			opt_reserved;
200	unsigned int			sig_reserved;
201	unsigned int			reserved; /* reserved space (render) */
202
203	isc_buffer_t		       *buffer;
204	dns_compress_t		       *cctx;
205
206	isc_bufferlist_t		scratchpad;
207	isc_bufferlist_t		cleanup;
208
209	ISC_LIST(dns_msgblock_t)	rdatas;
210	ISC_LIST(dns_msgblock_t)	rdatalists;
211	ISC_LIST(dns_msgblock_t)	offsets;
212
213	ISC_LIST(dns_rdata_t)		freerdata;
214	ISC_LIST(dns_rdatalist_t)	freerdatalist;
215
216	dns_rcode_t			tsigstatus;
217	dns_rcode_t			querytsigstatus;
218	dns_name_t		       *tsigname; /* Owner name of TSIG, if any */
219	dns_rdataset_t		       *querytsig;
220	dns_tsigkey_t		       *tsigkey;
221	dst_context_t		       *tsigctx;
222	int				sigstart;
223	int				timeadjust;
224
225	dns_name_t		       *sig0name; /* Owner name of SIG0, if any */
226	dns_rcode_t			sig0status;
227	isc_region_t			query;
228	isc_region_t			saved;
229};
230
231struct dns_ednsopt {
232	uint16_t			code;
233	uint16_t			length;
234	unsigned char			*value;
235};
236
237/***
238 *** Functions
239 ***/
240
241isc_result_t
242dns_message_create(unsigned int intent, dns_message_t **msgp);
243
244/*%<
245 * Create msg structure.
246 *
247 * This function will allocate some internal blocks of memory that are
248 * expected to be needed for parsing or rendering nearly any type of message.
249 *
250 * Requires:
251 *\li	'mctx' be a valid memory context.
252 *
253 *\li	'msgp' be non-null and '*msg' be NULL.
254 *
255 *\li	'intent' must be one of DNS_MESSAGE_INTENTPARSE or
256 *	#DNS_MESSAGE_INTENTRENDER.
257 *
258 * Ensures:
259 *\li	The data in "*msg" is set to indicate an unused and empty msg
260 *	structure.
261 *
262 * Returns:
263 *\li	#ISC_R_NOMEMORY		-- out of memory
264 *\li	#ISC_R_SUCCESS		-- success
265 */
266
267void
268dns_message_destroy(dns_message_t **msgp);
269/*%<
270 * Destroy all state in the message.
271 *
272 * Requires:
273 *
274 *\li	'msgp' be valid.
275 *
276 * Ensures:
277 *\li	'*msgp' == NULL
278 */
279
280isc_result_t
281dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
282			  const dns_master_style_t *style,
283			  dns_messagetextflag_t flags,
284			  isc_buffer_t *target);
285
286isc_result_t
287dns_message_pseudosectiontotext(dns_message_t *msg,
288				dns_pseudosection_t section,
289				const dns_master_style_t *style,
290				dns_messagetextflag_t flags,
291				isc_buffer_t *target);
292/*%<
293 * Convert section 'section' or 'pseudosection' of message 'msg' to
294 * a cleartext representation
295 *
296 * Notes:
297 *     \li See dns_message_totext for meanings of flags.
298 *
299 * Requires:
300 *
301 *\li	'msg' is a valid message.
302 *
303 *\li	'style' is a valid master dump style.
304 *
305 *\li	'target' is a valid buffer.
306 *
307 *\li	'section' is a valid section label.
308 *
309 * Ensures:
310 *
311 *\li	If the result is success:
312 *		The used space in 'target' is updated.
313 *
314 * Returns:
315 *
316 *\li	#ISC_R_SUCCESS
317 *\li	#ISC_R_NOSPACE
318 *\li	#ISC_R_NOMORE
319 *
320 *\li	Note: On error return, *target may be partially filled with data.
321*/
322
323isc_result_t
324dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
325		  unsigned int options);
326/*%<
327 * Parse raw wire data in 'source' as a DNS message.
328 *
329 * OPT records are detected and stored in the pseudo-section "opt".
330 * TSIGs are detected and stored in the pseudo-section "tsig".
331 *
332 * A separate dns_name_t object will be created for each RR in the
333 * message.  Each such dns_name_t will have a single rdataset containing the
334 * single RR, and the order of the RRs in the message is preserved.
335 *
336 * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
337 * not be considered FORMERRs.  If the entire message can be parsed, it
338 * will be returned and DNS_R_RECOVERABLE will be returned.
339 *
340 * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
341 * RR's as possible, DNS_R_RECOVERABLE will be returned.
342 *
343 *
344 * Requires:
345 *\li	"msg" be valid.
346 *
347 *\li	"buffer" be a wire format buffer.
348 *
349 * Ensures:
350 *\li	The buffer's data format is correct.
351 *
352 *\li	The buffer's contents verify as correct regarding header bits, buffer
353 * 	and rdata sizes, etc.
354 *
355 * Returns:
356 *\li	#ISC_R_SUCCESS		-- all is well
357 *\li	#ISC_R_NOMEMORY		-- no memory
358 *\li	#DNS_R_RECOVERABLE	-- the message parsed properly, but contained
359 *				   errors.
360 *\li	Many other errors possible XXXMLG
361 */
362
363isc_result_t
364dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
365			isc_buffer_t *buffer);
366/*%<
367 * Begin rendering on a message.  Only one call can be made to this function
368 * per message.
369 *
370 * The compression context is "owned" by the message library until
371 * dns_message_renderend() is called.  It must be invalidated by the caller.
372 *
373 * The buffer is "owned" by the message library until dns_message_renderend()
374 * is called.
375 *
376 * Requires:
377 *
378 *\li	'msg' be valid.
379 *
380 *\li	'cctx' be valid.
381 *
382 *\li	'buffer' is a valid buffer.
383 *
384 * Side Effects:
385 *
386 *\li	The buffer is cleared before it is used.
387 *
388 * Returns:
389 *\li	#ISC_R_SUCCESS		-- all is well
390 *\li	#ISC_R_NOSPACE		-- output buffer is too small
391 */
392
393isc_result_t
394dns_message_renderreserve(dns_message_t *msg, unsigned int space);
395/*%<
396 * XXXMLG should use size_t rather than unsigned int once the buffer
397 * API is cleaned up
398 *
399 * Reserve "space" bytes in the given buffer.
400 *
401 * Requires:
402 *
403 *\li	'msg' be valid.
404 *
405 *\li	dns_message_renderbegin() was called.
406 *
407 * Returns:
408 *\li	#ISC_R_SUCCESS		-- all is well.
409 *\li	#ISC_R_NOSPACE		-- not enough free space in the buffer.
410 */
411
412void
413dns_message_renderrelease(dns_message_t *msg, unsigned int space);
414/*%<
415 * XXXMLG should use size_t rather than unsigned int once the buffer
416 * API is cleaned up
417 *
418 * Release "space" bytes in the given buffer that was previously reserved.
419 *
420 * Requires:
421 *
422 *\li	'msg' be valid.
423 *
424 *\li	'space' is less than or equal to the total amount of space reserved
425 *	via prior calls to dns_message_renderreserve().
426 *
427 *\li	dns_message_renderbegin() was called.
428 */
429
430isc_result_t
431dns_message_rendersection(dns_message_t *msg, dns_section_t section);
432/*%<
433 * Render all names, rdatalists, etc from the given section at the
434 * specified priority or higher.
435 *
436 * Requires:
437 *\li	'msg' be valid.
438 *
439 *\li	'section' be a valid section.
440 *
441 *\li	dns_message_renderbegin() was called.
442 *
443 * Returns:
444 *\li	#ISC_R_SUCCESS		-- all records were written, and there are
445 *				   no more records for this section.
446 *\li	#ISC_R_NOSPACE		-- Not enough room in the buffer to write
447 *				   all records requested.
448 *\li	#DNS_R_MOREDATA		-- All requested records written, and there
449 *				   are records remaining for this section.
450 */
451
452void
453dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
454/*%<
455 * Render the message header.  This is implicitly called by
456 * dns_message_renderend().
457 *
458 * Requires:
459 *
460 *\li	'msg' be a valid message.
461 *
462 *\li	dns_message_renderbegin() was called.
463 *
464 *\li	'target' is a valid buffer with enough space to hold a message header
465 */
466
467isc_result_t
468dns_message_renderend(dns_message_t *msg);
469/*%<
470 * Finish rendering to the buffer.  Note that more data can be in the
471 * 'msg' structure.  Destroying the structure will free this, or in a multi-
472 * part EDNS1 message this data can be rendered to another buffer later.
473 *
474 * Requires:
475 *
476 *\li	'msg' be a valid message.
477 *
478 *\li	dns_message_renderbegin() was called.
479 *
480 * Returns:
481 *\li	#ISC_R_SUCCESS		-- all is well.
482 */
483
484void
485dns_message_renderreset(dns_message_t *msg);
486/*%<
487 * Reset the message so that it may be rendered again.
488 *
489 * Notes:
490 *
491 *\li	If dns_message_renderbegin() has been called, dns_message_renderend()
492 *	must be called before calling this function.
493 *
494 * Requires:
495 *
496 *\li	'msg' be a valid message with rendering intent.
497 */
498
499isc_result_t
500dns_message_firstname(dns_message_t *msg, dns_section_t section);
501/*%<
502 * Set internal per-section name pointer to the beginning of the section.
503 *
504 * The functions dns_message_firstname() and dns_message_nextname() may
505 * be used for iterating over the owner names in a section.
506 *
507 * Requires:
508 *
509 *\li   	'msg' be valid.
510 *
511 *\li	'section' be a valid section.
512 *
513 * Returns:
514 *\li	#ISC_R_SUCCESS		-- All is well.
515 *\li	#ISC_R_NOMORE		-- No names on given section.
516 */
517
518isc_result_t
519dns_message_nextname(dns_message_t *msg, dns_section_t section);
520/*%<
521 * Sets the internal per-section name pointer to point to the next name
522 * in that section.
523 *
524 * Requires:
525 *
526 * \li  	'msg' be valid.
527 *
528 *\li	'section' be a valid section.
529 *
530 *\li	dns_message_firstname() must have been called on this section,
531 *	and the result was ISC_R_SUCCESS.
532 *
533 * Returns:
534 *\li	#ISC_R_SUCCESS		-- All is well.
535 *\li	#ISC_R_NOMORE		-- No more names in given section.
536 */
537
538void
539dns_message_currentname(dns_message_t *msg, dns_section_t section,
540			dns_name_t **name);
541/*%<
542 * Sets 'name' to point to the name where the per-section internal name
543 * pointer is currently set.
544 *
545 * This function returns the name in the database, so any data associated
546 * with it (via the name's "list" member) contains the actual rdatasets.
547 *
548 * Requires:
549 *
550 *\li	'msg' be valid.
551 *
552 *\li	'name' be non-NULL, and *name be NULL.
553 *
554 *\li	'section' be a valid section.
555 *
556 *\li	dns_message_firstname() must have been called on this section,
557 *	and the result of it and any dns_message_nextname() calls was
558 *	#ISC_R_SUCCESS.
559 */
560
561isc_result_t
562dns_message_findname(dns_message_t *msg, dns_section_t section,
563		     dns_name_t *target, dns_rdatatype_t type,
564		     dns_rdatatype_t covers, dns_name_t **foundname,
565		     dns_rdataset_t **rdataset);
566/*%<
567 * Search for a name in the specified section.  If it is found, *name is
568 * set to point to the name, and *rdataset is set to point to the found
569 * rdataset (if type is specified as other than dns_rdatatype_any).
570 *
571 * Requires:
572 *\li	'msg' be valid.
573 *
574 *\li	'section' be a valid section.
575 *
576 *\li	If a pointer to the name is desired, 'foundname' should be non-NULL.
577 *	If it is non-NULL, '*foundname' MUST be NULL.
578 *
579 *\li	If a type other than dns_datatype_any is searched for, 'rdataset'
580 *	may be non-NULL, '*rdataset' be NULL, and will point at the found
581 *	rdataset.  If the type is dns_datatype_any, 'rdataset' must be NULL.
582 *
583 *\li	'target' be a valid name.
584 *
585 *\li	'type' be a valid type.
586 *
587 *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
588 *	Otherwise it should be 0.
589 *
590 * Returns:
591 *\li	#ISC_R_SUCCESS		-- all is well.
592 *\li	#DNS_R_NXDOMAIN		-- name does not exist in that section.
593 *\li	#DNS_R_NXRRSET		-- The name does exist, but the desired
594 *				   type does not.
595 */
596
597isc_result_t
598dns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
599		     dns_rdatatype_t covers, dns_rdataset_t **rdataset);
600/*%<
601 * Search the name for the specified type.  If it is found, *rdataset is
602 * filled in with a pointer to that rdataset.
603 *
604 * Requires:
605 *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
606 *
607 *\li	'type' be a valid type, and NOT dns_rdatatype_any.
608 *
609 *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
610 *	Otherwise it should be 0.
611 *
612 * Returns:
613 *\li	#ISC_R_SUCCESS		-- all is well.
614 *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
615 */
616
617isc_result_t
618dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
619		 dns_rdatatype_t type, dns_rdatatype_t covers,
620		 dns_rdataset_t **rdataset);
621/*%<
622 * Search the name for the specified rdclass and type.  If it is found,
623 * *rdataset is filled in with a pointer to that rdataset.
624 *
625 * Requires:
626 *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
627 *
628 *\li	'type' be a valid type, and NOT dns_rdatatype_any.
629 *
630 *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
631 *	Otherwise it should be 0.
632 *
633 * Returns:
634 *\li	#ISC_R_SUCCESS		-- all is well.
635 *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
636 */
637
638void
639dns_message_addname(dns_message_t *msg, dns_name_t *name,
640		    dns_section_t section);
641/*%<
642 * Adds the name to the given section.
643 *
644 * It is the caller's responsibility to enforce any unique name requirements
645 * in a section.
646 *
647 * Requires:
648 *
649 *\li	'msg' be valid, and be a renderable message.
650 *
651 *\li	'name' be a valid absolute name.
652 *
653 *\li	'section' be a named section.
654 */
655
656/*
657 * LOANOUT FUNCTIONS
658 *
659 * Each of these functions loan a particular type of data to the caller.
660 * The storage for these will vanish when the message is destroyed or
661 * reset, and must NOT be used after these operations.
662 */
663
664isc_result_t
665dns_message_gettempname(dns_message_t *msg, dns_name_t **item);
666/*%<
667 * Return a name that can be used for any temporary purpose, including
668 * inserting into the message's linked lists.  The name must be returned
669 * to the message code using dns_message_puttempname() or inserted into
670 * one of the message's sections before the message is destroyed.
671 *
672 * It is the caller's responsibility to initialize this name.
673 *
674 * Requires:
675 *\li	msg be a valid message
676 *
677 *\li	item != NULL && *item == NULL
678 *
679 * Returns:
680 *\li	#ISC_R_SUCCESS		-- All is well.
681 *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
682 */
683
684isc_result_t
685dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
686/*%<
687 * Return a rdata that can be used for any temporary purpose, including
688 * inserting into the message's linked lists.  The rdata will be freed
689 * when the message is destroyed or reset.
690 *
691 * Requires:
692 *\li	msg be a valid message
693 *
694 *\li	item != NULL && *item == NULL
695 *
696 * Returns:
697 *\li	#ISC_R_SUCCESS		-- All is well.
698 *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
699 */
700
701isc_result_t
702dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item);
703/*%<
704 * Return a rdataset that can be used for any temporary purpose, including
705 * inserting into the message's linked lists. The name must be returned
706 * to the message code using dns_message_puttempname() or inserted into
707 * one of the message's sections before the message is destroyed.
708 *
709 * Requires:
710 *\li	msg be a valid message
711 *
712 *\li	item != NULL && *item == NULL
713 *
714 * Returns:
715 *\li	#ISC_R_SUCCESS		-- All is well.
716 *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
717 */
718
719isc_result_t
720dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
721/*%<
722 * Return a rdatalist that can be used for any temporary purpose, including
723 * inserting into the message's linked lists.  The rdatalist will be
724 * destroyed when the message is destroyed or reset.
725 *
726 * Requires:
727 *\li	msg be a valid message
728 *
729 *\li	item != NULL && *item == NULL
730 *
731 * Returns:
732 *\li	#ISC_R_SUCCESS		-- All is well.
733 *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
734 */
735
736void
737dns_message_puttempname(dns_message_t *msg, dns_name_t **item);
738/*%<
739 * Return a borrowed name to the message's name free list.
740 *
741 * Requires:
742 *\li	msg be a valid message
743 *
744 *\li	item != NULL && *item point to a name returned by
745 *	dns_message_gettempname()
746 *
747 * Ensures:
748 *\li	*item == NULL
749 */
750
751void
752dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item);
753/*%<
754 * Return a borrowed rdata to the message's rdata free list.
755 *
756 * Requires:
757 *\li	msg be a valid message
758 *
759 *\li	item != NULL && *item point to a rdata returned by
760 *	dns_message_gettemprdata()
761 *
762 * Ensures:
763 *\li	*item == NULL
764 */
765
766void
767dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item);
768/*%<
769 * Return a borrowed rdataset to the message's rdataset free list.
770 *
771 * Requires:
772 *\li	msg be a valid message
773 *
774 *\li	item != NULL && *item point to a rdataset returned by
775 *	dns_message_gettemprdataset()
776 *
777 * Ensures:
778 *\li	*item == NULL
779 */
780
781void
782dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
783/*%<
784 * Return a borrowed rdatalist to the message's rdatalist free list.
785 *
786 * Requires:
787 *\li	msg be a valid message
788 *
789 *\li	item != NULL && *item point to a rdatalist returned by
790 *	dns_message_gettemprdatalist()
791 *
792 * Ensures:
793 *\li	*item == NULL
794 */
795
796isc_result_t
797dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
798		       unsigned int *flagsp);
799/*%<
800 * Assume the remaining region of "source" is a DNS message.  Peek into
801 * it and fill in "*idp" with the message id, and "*flagsp" with the flags.
802 *
803 * Requires:
804 *
805 *\li	source != NULL
806 *
807 * Ensures:
808 *
809 *\li	if (idp != NULL) *idp == message id.
810 *
811 *\li	if (flagsp != NULL) *flagsp == message flags.
812 *
813 * Returns:
814 *
815 *\li	#ISC_R_SUCCESS		-- all is well.
816 *
817 *\li	#ISC_R_UNEXPECTEDEND	-- buffer doesn't contain enough for a header.
818 */
819
820dns_rdataset_t *
821dns_message_getopt(dns_message_t *msg);
822/*%<
823 * Get the OPT record for 'msg'.
824 *
825 * Requires:
826 *
827 *\li	'msg' is a valid message.
828 *
829 * Returns:
830 *
831 *\li	The OPT rdataset of 'msg', or NULL if there isn't one.
832 */
833
834isc_result_t
835dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
836/*%<
837 * Set the OPT record for 'msg'.
838 *
839 * Requires:
840 *
841 *\li	'msg' is a valid message with rendering intent
842 *	and no sections have been rendered.
843 *
844 *\li	'opt' is a valid OPT record.
845 *
846 * Ensures:
847 *
848 *\li	The OPT record has either been freed or ownership of it has
849 *	been transferred to the message.
850 *
851 *\li	If ISC_R_SUCCESS was returned, the OPT record will be rendered
852 *	when dns_message_renderend() is called.
853 *
854 * Returns:
855 *
856 *\li	#ISC_R_SUCCESS		-- all is well.
857 *
858 *\li	#ISC_R_NOSPACE		-- there is no space for the OPT record.
859 */
860
861dns_rdataset_t *
862dns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
863/*%<
864 * Get the TSIG record and owner for 'msg'.
865 *
866 * Requires:
867 *
868 *\li	'msg' is a valid message.
869 *\li	'owner' is NULL or *owner is NULL.
870 *
871 * Returns:
872 *
873 *\li	The TSIG rdataset of 'msg', or NULL if there isn't one.
874 *
875 * Ensures:
876 *
877 * \li	If 'owner' is not NULL, it will point to the owner name.
878 */
879
880isc_result_t
881dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
882/*%<
883 * Set the tsig key for 'msg'.  This is only necessary for when rendering a
884 * query or parsing a response.  The key (if non-NULL) is attached to, and
885 * will be detached when the message is destroyed.
886 *
887 * Requires:
888 *
889 *\li	'msg' is a valid message with rendering intent,
890 *	dns_message_renderbegin() has been called, and no sections have been
891 *	rendered.
892 *\li	'key' is a valid tsig key or NULL.
893 *
894 * Returns:
895 *
896 *\li	#ISC_R_SUCCESS		-- all is well.
897 *
898 *\li	#ISC_R_NOSPACE		-- there is no space for the TSIG record.
899 */
900
901dns_tsigkey_t *
902dns_message_gettsigkey(dns_message_t *msg);
903/*%<
904 * Gets the tsig key for 'msg'.
905 *
906 * Requires:
907 *
908 *\li	'msg' is a valid message
909 */
910
911isc_result_t
912dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
913/*%<
914 * Indicates that 'querytsig' is the TSIG from the signed query for which
915 * 'msg' is the response.  This is also used for chained TSIGs in TCP
916 * responses.
917 *
918 * Requires:
919 *
920 *\li	'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
921 *	or NULL
922 *
923 *\li	'msg' is a valid message
924 *
925 * Returns:
926 *
927 *\li	#ISC_R_SUCCESS
928 *\li	#ISC_R_NOMEMORY
929 */
930
931isc_result_t
932dns_message_getquerytsig(dns_message_t *msg, isc_buffer_t **querytsig);
933/*%<
934 * Gets the tsig from the TSIG from the signed query 'msg'.  This is also used
935 * for chained TSIGs in TCP responses.  Unlike dns_message_gettsig, this makes
936 * a copy of the data, so can be used if the message is destroyed.
937 *
938 * Requires:
939 *
940 *\li	'msg' is a valid signed message
941 *\li	'mctx' is a valid memory context
942 *\li	querytsig != NULL && *querytsig == NULL
943 *
944 * Returns:
945 *
946 *\li	#ISC_R_SUCCESS
947 *\li	#ISC_R_NOMEMORY
948 *
949 * Ensures:
950 *\li 	'tsig' points to NULL or an allocated buffer which must be freed
951 * 	by the caller.
952 */
953
954dns_rdataset_t *
955dns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
956/*%<
957 * Get the SIG(0) record and owner for 'msg'.
958 *
959 * Requires:
960 *
961 *\li	'msg' is a valid message.
962 *\li	'owner' is NULL or *owner is NULL.
963 *
964 * Returns:
965 *
966 *\li	The SIG(0) rdataset of 'msg', or NULL if there isn't one.
967 *
968 * Ensures:
969 *
970 * \li	If 'owner' is not NULL, it will point to the owner name.
971 */
972
973void
974dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
975/*%<
976 * Give the *buffer to the message code to clean up when it is no
977 * longer needed.  This is usually when the message is reset or
978 * destroyed.
979 *
980 * Requires:
981 *
982 *\li	msg be a valid message.
983 *
984 *\li	buffer != NULL && *buffer is a valid isc_buffer_t, which was
985 *	dynamically allocated via isc_buffer_allocate().
986 */
987
988isc_result_t
989dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt,
990		     unsigned int version, uint16_t udpsize,
991		     unsigned int flags, dns_ednsopt_t *ednsopts, size_t count);
992/*%<
993 * Built a opt record.
994 *
995 * Requires:
996 * \li   msg be a valid message.
997 * \li   opt to be a non NULL and *opt to be NULL.
998 *
999 * Returns:
1000 * \li	 ISC_R_SUCCESS on success.
1001 * \li	 ISC_R_NOMEMORY
1002 * \li	 ISC_R_NOSPACE
1003 * \li	 other.
1004 */
1005
1006#endif /* DNS_MESSAGE_H */
1007