1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * See the COPYRIGHT file distributed with this work for additional
9  * information regarding copyright ownership.
10  */
11 
12 #ifndef DNS_MESSAGE_H
13 #define DNS_MESSAGE_H 1
14 
15 /***
16  ***	Imports
17  ***/
18 
19 #include <inttypes.h>
20 #include <stdbool.h>
21 
22 #include <isc/lang.h>
23 #include <isc/magic.h>
24 
25 #include <dns/compress.h>
26 #include <dns/masterdump.h>
27 #include <dns/types.h>
28 
29 #include <dst/dst.h>
30 
31 /*! \file dns/message.h
32  * \brief Message Handling Module
33  *
34  * How this beast works:
35  *
36  * When a dns message is received in a buffer, dns_message_parse() is called
37  * on the memory region.  Various items are checked including the format
38  * of the message (if counts are right, if counts consume the entire sections,
39  * and if sections consume the entire message) and known pseudo-RRs in the
40  * additional data section are analyzed and removed.
41  *
42  * TSIG checking is also done at this layer, and any DNSSEC transaction
43  * signatures should also be checked here.
44  *
45  * Notes on using the gettemp*() and puttemp*() functions:
46  *
47  * These functions return items (names, rdatasets, etc) allocated from some
48  * internal state of the dns_message_t.
49  *
50  * Names and rdatasets must be put back into the dns_message_t in
51  * one of two ways.  Assume a name was allocated via
52  * dns_message_gettempname():
53  *
54  *\li	(1) insert it into a section, using dns_message_addname().
55  *
56  *\li	(2) return it to the message using dns_message_puttempname().
57  *
58  * The same applies to rdatasets.
59  *
60  * On the other hand, offsets, rdatalists and rdatas allocated using
61  * dns_message_gettemp*() will always be freed automatically
62  * when the message is reset or destroyed; calling dns_message_puttemp*()
63  * on rdatalists and rdatas is optional and serves only to enable the item
64  * to be reused multiple times during the lifetime of the message; offsets
65  * cannot be reused.
66  *
67  * Buffers allocated using isc_buffer_allocate() can be automatically freed
68  * as well by giving the buffer to the message using dns_message_takebuffer().
69  * Doing this will cause the buffer to be freed using isc_buffer_free()
70  * when the section lists are cleared, such as in a reset or in a destroy.
71  * Since the buffer itself exists until the message is destroyed, this sort
72  * of code can be written:
73  *
74  * \code
75  *	buffer = isc_buffer_allocate(mctx, 512);
76  *	name = NULL;
77  *	name = dns_message_gettempname(message, &name);
78  *	dns_name_init(name, NULL);
79  *	result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer);
80  *	dns_message_takebuffer(message, &buffer);
81  * \endcode
82  *
83  *
84  * TODO:
85  *
86  * XXX Needed:  ways to set and retrieve EDNS information, add rdata to a
87  * section, move rdata from one section to another, remove rdata, etc.
88  */
89 
90 #define DNS_MESSAGEFLAG_QR 0x8000U
91 #define DNS_MESSAGEFLAG_AA 0x0400U
92 #define DNS_MESSAGEFLAG_TC 0x0200U
93 #define DNS_MESSAGEFLAG_RD 0x0100U
94 #define DNS_MESSAGEFLAG_RA 0x0080U
95 #define DNS_MESSAGEFLAG_AD 0x0020U
96 #define DNS_MESSAGEFLAG_CD 0x0010U
97 
98 /*%< EDNS0 extended message flags */
99 #define DNS_MESSAGEEXTFLAG_DO 0x8000U
100 
101 /*%< EDNS0 extended OPT codes */
102 #define DNS_OPT_LLQ	      1	 /*%< LLQ opt code */
103 #define DNS_OPT_NSID	      3	 /*%< NSID opt code */
104 #define DNS_OPT_CLIENT_SUBNET 8	 /*%< client subnet opt code */
105 #define DNS_OPT_EXPIRE	      9	 /*%< EXPIRE opt code */
106 #define DNS_OPT_COOKIE	      10 /*%< COOKIE opt code */
107 #define DNS_OPT_TCP_KEEPALIVE 11 /*%< TCP keepalive opt code */
108 #define DNS_OPT_PAD	      12 /*%< PAD opt code */
109 #define DNS_OPT_KEY_TAG	      14 /*%< Key tag opt code */
110 #define DNS_OPT_EDE	      15 /*%< Extended DNS Error opt code */
111 #define DNS_OPT_CLIENT_TAG    16 /*%< Client tag opt code */
112 #define DNS_OPT_SERVER_TAG    17 /*%< Server tag opt code */
113 
114 /*%< Experimental options [65001...65534] as per RFC6891 */
115 
116 /*%< The number of EDNS options we know about. */
117 #define DNS_EDNSOPTIONS 7
118 
119 #define DNS_MESSAGE_REPLYPRESERVE	 (DNS_MESSAGEFLAG_RD | DNS_MESSAGEFLAG_CD)
120 #define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
121 
122 #define DNS_MESSAGE_HEADERLEN 12 /*%< 6 uint16_t's */
123 
124 #define DNS_MESSAGE_MAGIC      ISC_MAGIC('M', 'S', 'G', '@')
125 #define DNS_MESSAGE_VALID(msg) ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC)
126 
127 /*
128  * Ordering here matters.  DNS_SECTION_ANY must be the lowest and negative,
129  * and DNS_SECTION_MAX must be one greater than the last used section.
130  */
131 typedef int dns_section_t;
132 #define DNS_SECTION_ANY	       (-1)
133 #define DNS_SECTION_QUESTION   0
134 #define DNS_SECTION_ANSWER     1
135 #define DNS_SECTION_AUTHORITY  2
136 #define DNS_SECTION_ADDITIONAL 3
137 #define DNS_SECTION_MAX	       4
138 
139 typedef int dns_pseudosection_t;
140 #define DNS_PSEUDOSECTION_ANY  (-1)
141 #define DNS_PSEUDOSECTION_OPT  0
142 #define DNS_PSEUDOSECTION_TSIG 1
143 #define DNS_PSEUDOSECTION_SIG0 2
144 #define DNS_PSEUDOSECTION_MAX  3
145 
146 typedef int dns_messagetextflag_t;
147 #define DNS_MESSAGETEXTFLAG_NOCOMMENTS 0x0001
148 #define DNS_MESSAGETEXTFLAG_NOHEADERS  0x0002
149 #define DNS_MESSAGETEXTFLAG_ONESOA     0x0004
150 #define DNS_MESSAGETEXTFLAG_OMITSOA    0x0008
151 
152 /*
153  * Dynamic update names for these sections.
154  */
155 #define DNS_SECTION_ZONE	 DNS_SECTION_QUESTION
156 #define DNS_SECTION_PREREQUISITE DNS_SECTION_ANSWER
157 #define DNS_SECTION_UPDATE	 DNS_SECTION_AUTHORITY
158 
159 /*
160  * These tell the message library how the created dns_message_t will be used.
161  */
162 #define DNS_MESSAGE_INTENTUNKNOWN 0 /*%< internal use only */
163 #define DNS_MESSAGE_INTENTPARSE	  1 /*%< parsing messages */
164 #define DNS_MESSAGE_INTENTRENDER  2 /*%< rendering */
165 
166 /*
167  * Control behavior of parsing
168  */
169 #define DNS_MESSAGEPARSE_PRESERVEORDER 0x0001 /*%< preserve rdata order */
170 #define DNS_MESSAGEPARSE_BESTEFFORT       \
171 	0x0002 /*%< return a message if a \
172 		* recoverable parse error \
173 		* occurs */
174 #define DNS_MESSAGEPARSE_CLONEBUFFER   \
175 	0x0004 /*%< save a copy of the \
176 		* source buffer */
177 #define DNS_MESSAGEPARSE_IGNORETRUNCATION \
178 	0x0008 /*%< truncation errors are \
179 		* not fatal. */
180 
181 /*
182  * Control behavior of rendering
183  */
184 #define DNS_MESSAGERENDER_ORDERED    0x0001 /*%< don't change order */
185 #define DNS_MESSAGERENDER_PARTIAL    0x0002 /*%< allow a partial rdataset */
186 #define DNS_MESSAGERENDER_OMITDNSSEC 0x0004 /*%< omit DNSSEC records */
187 #define DNS_MESSAGERENDER_PREFER_A      \
188 	0x0008 /*%< prefer A records in \
189 		*   additional section. */
190 #define DNS_MESSAGERENDER_PREFER_AAAA      \
191 	0x0010 /*%< prefer AAAA records in \
192 		*   additional section. */
193 /* Obsolete: DNS_MESSAGERENDER_FILTER_AAAA	0x0020	*/
194 
195 typedef struct dns_msgblock dns_msgblock_t;
196 
197 struct dns_sortlist_arg {
198 	dns_aclenv_t *		env;
199 	const dns_acl_t *	acl;
200 	const dns_aclelement_t *element;
201 };
202 
203 struct dns_message {
204 	/* public from here down */
205 	unsigned int magic;
206 
207 	dns_messageid_t	 id;
208 	unsigned int	 flags;
209 	dns_rcode_t	 rcode;
210 	dns_opcode_t	 opcode;
211 	dns_rdataclass_t rdclass;
212 
213 	/* 4 real, 1 pseudo */
214 	unsigned int counts[DNS_SECTION_MAX];
215 
216 	/* private from here down */
217 	dns_namelist_t	sections[DNS_SECTION_MAX];
218 	dns_name_t *	cursors[DNS_SECTION_MAX];
219 	dns_rdataset_t *opt;
220 	dns_rdataset_t *sig0;
221 	dns_rdataset_t *tsig;
222 
223 	int	     state;
224 	unsigned int from_to_wire : 2;
225 	unsigned int header_ok : 1;
226 	unsigned int question_ok : 1;
227 	unsigned int tcp_continuation : 1;
228 	unsigned int verified_sig : 1;
229 	unsigned int verify_attempted : 1;
230 	unsigned int free_query : 1;
231 	unsigned int free_saved : 1;
232 	unsigned int cc_ok : 1;
233 	unsigned int cc_bad : 1;
234 	unsigned int tkey : 1;
235 	unsigned int rdclass_set : 1;
236 
237 	unsigned int opt_reserved;
238 	unsigned int sig_reserved;
239 	unsigned int reserved; /* reserved space (render) */
240 
241 	uint16_t     padding;
242 	unsigned int padding_off;
243 
244 	isc_buffer_t *	buffer;
245 	dns_compress_t *cctx;
246 
247 	isc_mem_t *    mctx;
248 	isc_mempool_t *namepool;
249 	isc_mempool_t *rdspool;
250 
251 	isc_bufferlist_t scratchpad;
252 	isc_bufferlist_t cleanup;
253 
254 	ISC_LIST(dns_msgblock_t) rdatas;
255 	ISC_LIST(dns_msgblock_t) rdatalists;
256 	ISC_LIST(dns_msgblock_t) offsets;
257 
258 	ISC_LIST(dns_rdata_t) freerdata;
259 	ISC_LIST(dns_rdatalist_t) freerdatalist;
260 
261 	dns_rcode_t tsigstatus;
262 	dns_rcode_t querytsigstatus;
263 	dns_name_t *tsigname; /* Owner name of TSIG, if any
264 			       * */
265 	dns_rdataset_t *querytsig;
266 	dns_tsigkey_t * tsigkey;
267 	dst_context_t * tsigctx;
268 	int		sigstart;
269 	int		timeadjust;
270 
271 	dns_name_t *sig0name; /* Owner name of SIG0, if any
272 			       * */
273 	dst_key_t *  sig0key;
274 	dns_rcode_t  sig0status;
275 	isc_region_t query;
276 	isc_region_t saved;
277 
278 	dns_rdatasetorderfunc_t order;
279 	dns_sortlist_arg_t	order_arg;
280 
281 	dns_indent_t indent;
282 };
283 
284 struct dns_ednsopt {
285 	uint16_t       code;
286 	uint16_t       length;
287 	unsigned char *value;
288 };
289 
290 /***
291  *** Functions
292  ***/
293 
294 ISC_LANG_BEGINDECLS
295 
296 isc_result_t
297 dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp);
298 
299 /*%<
300  * Create msg structure.
301  *
302  * This function will allocate some internal blocks of memory that are
303  * expected to be needed for parsing or rendering nearly any type of message.
304  *
305  * Requires:
306  *\li	'mctx' be a valid memory context.
307  *
308  *\li	'msgp' be non-null and '*msg' be NULL.
309  *
310  *\li	'intent' must be one of DNS_MESSAGE_INTENTPARSE or
311  *	#DNS_MESSAGE_INTENTRENDER.
312  *
313  * Ensures:
314  *\li	The data in "*msg" is set to indicate an unused and empty msg
315  *	structure.
316  *
317  * Returns:
318  *\li	#ISC_R_NOMEMORY		-- out of memory
319  *\li	#ISC_R_SUCCESS		-- success
320  */
321 
322 void
323 dns_message_reset(dns_message_t *msg, unsigned int intent);
324 /*%<
325  * Reset a message structure to default state.  All internal lists are freed
326  * or reset to a default state as well.  This is simply a more efficient
327  * way to call dns_message_destroy() followed by dns_message_allocate(),
328  * since it avoid many memory allocations.
329  *
330  * If any data loanouts (buffers, names, rdatas, etc) were requested,
331  * the caller must no longer use them after this call.
332  *
333  * The intended next use of the message will be 'intent'.
334  *
335  * Requires:
336  *
337  *\li	'msg' be valid.
338  *
339  *\li	'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER
340  */
341 
342 void
343 dns_message_destroy(dns_message_t **msgp);
344 /*%<
345  * Destroy all state in the message.
346  *
347  * Requires:
348  *
349  *\li	'msgp' be valid.
350  *
351  * Ensures:
352  *\li	'*msgp' == NULL
353  */
354 
355 isc_result_t
356 dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
357 			  const dns_master_style_t *style,
358 			  dns_messagetextflag_t flags, isc_buffer_t *target);
359 
360 isc_result_t
361 dns_message_pseudosectiontotext(dns_message_t *msg, dns_pseudosection_t section,
362 				const dns_master_style_t *style,
363 				dns_messagetextflag_t	  flags,
364 				isc_buffer_t *		  target);
365 /*%<
366  * Convert section 'section' or 'pseudosection' of message 'msg' to
367  * a cleartext representation
368  *
369  * Notes:
370  *     \li See dns_message_totext for meanings of flags.
371  *
372  * Requires:
373  *
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  *\li	'section' is a valid section label.
381  *
382  * Ensures:
383  *
384  *\li	If the result is success:
385  *		The used space in 'target' is updated.
386  *
387  * Returns:
388  *
389  *\li	#ISC_R_SUCCESS
390  *\li	#ISC_R_NOSPACE
391  *\li	#ISC_R_NOMORE
392  *
393  *\li	Note: On error return, *target may be partially filled with data.
394  */
395 
396 isc_result_t
397 dns_message_headertotext(dns_message_t *msg, const dns_master_style_t *style,
398 			 dns_messagetextflag_t flags, isc_buffer_t *target);
399 /*%<
400  * Convert the header section of message 'msg' to a cleartext
401  * representation. This is called from dns_message_totext().
402  *
403  * Notes on flags:
404  *\li	If #DNS_MESSAGETEXTFLAG_NOHEADERS is set, header lines will be
405  * 	suppressed and this function is a no-op.
406  *
407  * Requires:
408  *
409  *\li	'msg' is a valid message.
410  *
411  *\li	'target' is a valid buffer.
412  *
413  * Ensures:
414  *
415  *\li	If the result is success:
416  *		The used space in 'target' is updated.
417  *
418  * Returns:
419  *
420  *\li	#ISC_R_SUCCESS
421  *\li	#ISC_R_NOSPACE
422  *\li	#ISC_R_NOMORE
423  *
424  *\li	Note: On error return, *target may be partially filled with data.
425  */
426 
427 isc_result_t
428 dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
429 		   dns_messagetextflag_t flags, isc_buffer_t *target);
430 /*%<
431  * Convert all sections of message 'msg' to a cleartext representation
432  *
433  * Notes on flags:
434  *\li	If #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning with
435  * 	";;" will be emitted indicating section name.
436  *\li	If #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will be
437  * 	emitted.
438  *\li   If #DNS_MESSAGETEXTFLAG_ONESOA is set then only print the first
439  *	SOA record in the answer section.
440  *\li	If *#DNS_MESSAGETEXTFLAG_OMITSOA is set don't print any SOA records
441  *	in the answer section.
442  *
443  * The SOA flags are useful for suppressing the display of the second
444  * SOA record in an AXFR by setting #DNS_MESSAGETEXTFLAG_ONESOA on the
445  * first message in an AXFR stream and #DNS_MESSAGETEXTFLAG_OMITSOA on
446  * subsequent messages.
447  *
448  * Requires:
449  *
450  *\li	'msg' is a valid message.
451  *
452  *\li	'style' is a valid master dump style.
453  *
454  *\li	'target' is a valid buffer.
455  *
456  * Ensures:
457  *
458  *\li	If the result is success:
459  *		The used space in 'target' is updated.
460  *
461  * Returns:
462  *
463  *\li	#ISC_R_SUCCESS
464  *\li	#ISC_R_NOSPACE
465  *\li	#ISC_R_NOMORE
466  *
467  *\li	Note: On error return, *target may be partially filled with data.
468  */
469 
470 isc_result_t
471 dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
472 		  unsigned int options);
473 /*%<
474  * Parse raw wire data in 'source' as a DNS message.
475  *
476  * OPT records are detected and stored in the pseudo-section "opt".
477  * TSIGs are detected and stored in the pseudo-section "tsig".
478  *
479  * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message
480  * is UPDATE, a separate dns_name_t object will be created for each RR in the
481  * message.  Each such dns_name_t will have a single rdataset containing the
482  * single RR, and the order of the RRs in the message is preserved.
483  * Otherwise, only one dns_name_t object will be created for each unique
484  * owner name in the section, and each such dns_name_t will have a list
485  * of rdatasets.  To access the names and their data, use
486  * dns_message_firstname() and dns_message_nextname().
487  *
488  * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
489  * not be considered FORMERRs.  If the entire message can be parsed, it
490  * will be returned and DNS_R_RECOVERABLE will be returned.
491  *
492  * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
493  * RR's as possible, DNS_R_RECOVERABLE will be returned.
494  *
495  * OPT and TSIG records are always handled specially, regardless of the
496  * 'preserve_order' setting.
497  *
498  * Requires:
499  *\li	"msg" be valid.
500  *
501  *\li	"buffer" be a wire format buffer.
502  *
503  * Ensures:
504  *\li	The buffer's data format is correct.
505  *
506  *\li	The buffer's contents verify as correct regarding header bits, buffer
507  * 	and rdata sizes, etc.
508  *
509  * Returns:
510  *\li	#ISC_R_SUCCESS		-- all is well
511  *\li	#ISC_R_NOMEMORY		-- no memory
512  *\li	#DNS_R_RECOVERABLE	-- the message parsed properly, but contained
513  *				   errors.
514  *\li	Many other errors possible XXXMLG
515  */
516 
517 isc_result_t
518 dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
519 			isc_buffer_t *buffer);
520 /*%<
521  * Begin rendering on a message.  Only one call can be made to this function
522  * per message.
523  *
524  * The compression context is "owned" by the message library until
525  * dns_message_renderend() is called.  It must be invalidated by the caller.
526  *
527  * The buffer is "owned" by the message library until dns_message_renderend()
528  * is called.
529  *
530  * Requires:
531  *
532  *\li	'msg' be valid.
533  *
534  *\li	'cctx' be valid.
535  *
536  *\li	'buffer' is a valid buffer.
537  *
538  * Side Effects:
539  *
540  *\li	The buffer is cleared before it is used.
541  *
542  * Returns:
543  *\li	#ISC_R_SUCCESS		-- all is well
544  *\li	#ISC_R_NOSPACE		-- output buffer is too small
545  */
546 
547 isc_result_t
548 dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
549 /*%<
550  * Reset the buffer.  This can be used after growing the old buffer
551  * on a ISC_R_NOSPACE return from most of the render functions.
552  *
553  * On successful completion, the old buffer is no longer used by the
554  * library.  The new buffer is owned by the library until
555  * dns_message_renderend() is called.
556  *
557  * Requires:
558  *
559  *\li	'msg' be valid.
560  *
561  *\li	dns_message_renderbegin() was called.
562  *
563  *\li	buffer != NULL.
564  *
565  * Returns:
566  *\li	#ISC_R_NOSPACE		-- new buffer is too small
567  *\li	#ISC_R_SUCCESS		-- all is well.
568  */
569 
570 isc_result_t
571 dns_message_renderreserve(dns_message_t *msg, unsigned int space);
572 /*%<
573  * XXXMLG should use size_t rather than unsigned int once the buffer
574  * API is cleaned up
575  *
576  * Reserve "space" bytes in the given buffer.
577  *
578  * Requires:
579  *
580  *\li	'msg' be valid.
581  *
582  *\li	dns_message_renderbegin() was called.
583  *
584  * Returns:
585  *\li	#ISC_R_SUCCESS		-- all is well.
586  *\li	#ISC_R_NOSPACE		-- not enough free space in the buffer.
587  */
588 
589 void
590 dns_message_renderrelease(dns_message_t *msg, unsigned int space);
591 /*%<
592  * XXXMLG should use size_t rather than unsigned int once the buffer
593  * API is cleaned up
594  *
595  * Release "space" bytes in the given buffer that was previously reserved.
596  *
597  * Requires:
598  *
599  *\li	'msg' be valid.
600  *
601  *\li	'space' is less than or equal to the total amount of space reserved
602  *	via prior calls to dns_message_renderreserve().
603  *
604  *\li	dns_message_renderbegin() was called.
605  */
606 
607 isc_result_t
608 dns_message_rendersection(dns_message_t *msg, dns_section_t section,
609 			  unsigned int options);
610 /*%<
611  * Render all names, rdatalists, etc from the given section at the
612  * specified priority or higher.
613  *
614  * Requires:
615  *\li	'msg' be valid.
616  *
617  *\li	'section' be a valid section.
618  *
619  *\li	dns_message_renderbegin() was called.
620  *
621  * Returns:
622  *\li	#ISC_R_SUCCESS		-- all records were written, and there are
623  *				   no more records for this section.
624  *\li	#ISC_R_NOSPACE		-- Not enough room in the buffer to write
625  *				   all records requested.
626  *\li	#DNS_R_MOREDATA		-- All requested records written, and there
627  *				   are records remaining for this section.
628  */
629 
630 void
631 dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
632 /*%<
633  * Render the message header.  This is implicitly called by
634  * dns_message_renderend().
635  *
636  * Requires:
637  *
638  *\li	'msg' be a valid message.
639  *
640  *\li	dns_message_renderbegin() was called.
641  *
642  *\li	'target' is a valid buffer with enough space to hold a message header
643  */
644 
645 isc_result_t
646 dns_message_renderend(dns_message_t *msg);
647 /*%<
648  * Finish rendering to the buffer.  Note that more data can be in the
649  * 'msg' structure.  Destroying the structure will free this, or in a multi-
650  * part EDNS1 message this data can be rendered to another buffer later.
651  *
652  * Requires:
653  *
654  *\li	'msg' be a valid message.
655  *
656  *\li	dns_message_renderbegin() was called.
657  *
658  * Returns:
659  *\li	#ISC_R_SUCCESS		-- all is well.
660  */
661 
662 void
663 dns_message_renderreset(dns_message_t *msg);
664 /*%<
665  * Reset the message so that it may be rendered again.
666  *
667  * Notes:
668  *
669  *\li	If dns_message_renderbegin() has been called, dns_message_renderend()
670  *	must be called before calling this function.
671  *
672  * Requires:
673  *
674  *\li	'msg' be a valid message with rendering intent.
675  */
676 
677 isc_result_t
678 dns_message_firstname(dns_message_t *msg, dns_section_t section);
679 /*%<
680  * Set internal per-section name pointer to the beginning of the section.
681  *
682  * The functions dns_message_firstname() and dns_message_nextname() may
683  * be used for iterating over the owner names in a section.
684  *
685  * Requires:
686  *
687  *\li   	'msg' be valid.
688  *
689  *\li	'section' be a valid section.
690  *
691  * Returns:
692  *\li	#ISC_R_SUCCESS		-- All is well.
693  *\li	#ISC_R_NOMORE		-- No names on given section.
694  */
695 
696 isc_result_t
697 dns_message_nextname(dns_message_t *msg, dns_section_t section);
698 /*%<
699  * Sets the internal per-section name pointer to point to the next name
700  * in that section.
701  *
702  * Requires:
703  *
704  * \li  	'msg' be valid.
705  *
706  *\li	'section' be a valid section.
707  *
708  *\li	dns_message_firstname() must have been called on this section,
709  *	and the result was ISC_R_SUCCESS.
710  *
711  * Returns:
712  *\li	#ISC_R_SUCCESS		-- All is well.
713  *\li	#ISC_R_NOMORE		-- No more names in given section.
714  */
715 
716 void
717 dns_message_currentname(dns_message_t *msg, dns_section_t section,
718 			dns_name_t **name);
719 /*%<
720  * Sets 'name' to point to the name where the per-section internal name
721  * pointer is currently set.
722  *
723  * This function returns the name in the database, so any data associated
724  * with it (via the name's "list" member) contains the actual rdatasets.
725  *
726  * Requires:
727  *
728  *\li	'msg' be valid.
729  *
730  *\li	'name' be non-NULL, and *name be NULL.
731  *
732  *\li	'section' be a valid section.
733  *
734  *\li	dns_message_firstname() must have been called on this section,
735  *	and the result of it and any dns_message_nextname() calls was
736  *	#ISC_R_SUCCESS.
737  */
738 
739 isc_result_t
740 dns_message_findname(dns_message_t *msg, dns_section_t section,
741 		     const dns_name_t *target, dns_rdatatype_t type,
742 		     dns_rdatatype_t covers, dns_name_t **foundname,
743 		     dns_rdataset_t **rdataset);
744 /*%<
745  * Search for a name in the specified section.  If it is found, *name is
746  * set to point to the name, and *rdataset is set to point to the found
747  * rdataset (if type is specified as other than dns_rdatatype_any).
748  *
749  * Requires:
750  *\li	'msg' be valid.
751  *
752  *\li	'section' be a valid section.
753  *
754  *\li	If a pointer to the name is desired, 'foundname' should be non-NULL.
755  *	If it is non-NULL, '*foundname' MUST be NULL.
756  *
757  *\li	If a type other than dns_datatype_any is searched for, 'rdataset'
758  *	may be non-NULL, '*rdataset' be NULL, and will point at the found
759  *	rdataset.  If the type is dns_datatype_any, 'rdataset' must be NULL.
760  *
761  *\li	'target' be a valid name.
762  *
763  *\li	'type' be a valid type.
764  *
765  *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
766  *	Otherwise it should be 0.
767  *
768  * Returns:
769  *\li	#ISC_R_SUCCESS		-- all is well.
770  *\li	#DNS_R_NXDOMAIN		-- name does not exist in that section.
771  *\li	#DNS_R_NXRRSET		-- The name does exist, but the desired
772  *				   type does not.
773  */
774 
775 isc_result_t
776 dns_message_findtype(const dns_name_t *name, dns_rdatatype_t type,
777 		     dns_rdatatype_t covers, dns_rdataset_t **rdataset);
778 /*%<
779  * Search the name for the specified type.  If it is found, *rdataset is
780  * filled in with a pointer to that rdataset.
781  *
782  * Requires:
783  *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
784  *
785  *\li	'type' be a valid type, and NOT dns_rdatatype_any.
786  *
787  *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
788  *	Otherwise it should be 0.
789  *
790  * Returns:
791  *\li	#ISC_R_SUCCESS		-- all is well.
792  *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
793  */
794 
795 isc_result_t
796 dns_message_find(const dns_name_t *name, dns_rdataclass_t rdclass,
797 		 dns_rdatatype_t type, dns_rdatatype_t covers,
798 		 dns_rdataset_t **rdataset);
799 /*%<
800  * Search the name for the specified rdclass and type.  If it is found,
801  * *rdataset is filled in with a pointer to that rdataset.
802  *
803  * Requires:
804  *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
805  *
806  *\li	'type' be a valid type, and NOT dns_rdatatype_any.
807  *
808  *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
809  *	Otherwise it should be 0.
810  *
811  * Returns:
812  *\li	#ISC_R_SUCCESS		-- all is well.
813  *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
814  */
815 
816 void
817 dns_message_movename(dns_message_t *msg, dns_name_t *name,
818 		     dns_section_t fromsection, dns_section_t tosection);
819 /*%<
820  * Move a name from one section to another.
821  *
822  * Requires:
823  *
824  *\li	'msg' be valid.
825  *
826  *\li	'name' must be a name already in 'fromsection'.
827  *
828  *\li	'fromsection' must be a valid section.
829  *
830  *\li	'tosection' must be a valid section.
831  */
832 
833 void
834 dns_message_addname(dns_message_t *msg, dns_name_t *name,
835 		    dns_section_t section);
836 /*%<
837  * Adds the name to the given section.
838  *
839  * It is the caller's responsibility to enforce any unique name requirements
840  * in a section.
841  *
842  * Requires:
843  *
844  *\li	'msg' be valid, and be a renderable message.
845  *
846  *\li	'name' be a valid absolute name.
847  *
848  *\li	'section' be a named section.
849  */
850 
851 void
852 dns_message_removename(dns_message_t *msg, dns_name_t *name,
853 		       dns_section_t section);
854 /*%<
855  * Remove a existing name from a given section.
856  *
857  * It is the caller's responsibility to ensure the name is part of the
858  * given section.
859  *
860  * Requires:
861  *
862  *\li	'msg' be valid, and be a renderable message.
863  *
864  *\li	'name' be a valid absolute name.
865  *
866  *\li	'section' be a named section.
867  */
868 
869 /*
870  * LOANOUT FUNCTIONS
871  *
872  * Each of these functions loan a particular type of data to the caller.
873  * The storage for these will vanish when the message is destroyed or
874  * reset, and must NOT be used after these operations.
875  */
876 
877 isc_result_t
878 dns_message_gettempname(dns_message_t *msg, dns_name_t **item);
879 /*%<
880  * Return a name that can be used for any temporary purpose, including
881  * inserting into the message's linked lists.  The name must be returned
882  * to the message code using dns_message_puttempname() or inserted into
883  * one of the message's sections before the message is destroyed.
884  *
885  * It is the caller's responsibility to initialize this name.
886  *
887  * Requires:
888  *\li	msg be a valid message
889  *
890  *\li	item != NULL && *item == NULL
891  *
892  * Returns:
893  *\li	#ISC_R_SUCCESS		-- All is well.
894  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
895  */
896 
897 isc_result_t
898 dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item);
899 /*%<
900  * Return an offsets array that can be used for any temporary purpose,
901  * such as attaching to a temporary name.  The offsets will be freed
902  * when the message is destroyed or reset.
903  *
904  * Requires:
905  *\li	msg be a valid message
906  *
907  *\li	item != NULL && *item == NULL
908  *
909  * Returns:
910  *\li	#ISC_R_SUCCESS		-- All is well.
911  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
912  */
913 
914 isc_result_t
915 dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
916 /*%<
917  * Return a rdata that can be used for any temporary purpose, including
918  * inserting into the message's linked lists.  The rdata will be freed
919  * when the message is destroyed or reset.
920  *
921  * Requires:
922  *\li	msg be a valid message
923  *
924  *\li	item != NULL && *item == NULL
925  *
926  * Returns:
927  *\li	#ISC_R_SUCCESS		-- All is well.
928  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
929  */
930 
931 isc_result_t
932 dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item);
933 /*%<
934  * Return a rdataset that can be used for any temporary purpose, including
935  * inserting into the message's linked lists. The name must be returned
936  * to the message code using dns_message_puttempname() or inserted into
937  * one of the message's sections before the message is destroyed.
938  *
939  * Requires:
940  *\li	msg be a valid message
941  *
942  *\li	item != NULL && *item == NULL
943  *
944  * Returns:
945  *\li	#ISC_R_SUCCESS		-- All is well.
946  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
947  */
948 
949 isc_result_t
950 dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
951 /*%<
952  * Return a rdatalist that can be used for any temporary purpose, including
953  * inserting into the message's linked lists.  The rdatalist will be
954  * destroyed when the message is destroyed or reset.
955  *
956  * Requires:
957  *\li	msg be a valid message
958  *
959  *\li	item != NULL && *item == NULL
960  *
961  * Returns:
962  *\li	#ISC_R_SUCCESS		-- All is well.
963  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
964  */
965 
966 void
967 dns_message_puttempname(dns_message_t *msg, dns_name_t **item);
968 /*%<
969  * Return a borrowed name to the message's name free list.
970  *
971  * Requires:
972  *\li	msg be a valid message
973  *
974  *\li	item != NULL && *item point to a name returned by
975  *	dns_message_gettempname()
976  *
977  * Ensures:
978  *\li	*item == NULL
979  */
980 
981 void
982 dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item);
983 /*%<
984  * Return a borrowed rdata to the message's rdata free list.
985  *
986  * Requires:
987  *\li	msg be a valid message
988  *
989  *\li	item != NULL && *item point to a rdata returned by
990  *	dns_message_gettemprdata()
991  *
992  * Ensures:
993  *\li	*item == NULL
994  */
995 
996 void
997 dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item);
998 /*%<
999  * Return a borrowed rdataset to the message's rdataset free list.
1000  *
1001  * Requires:
1002  *\li	msg be a valid message
1003  *
1004  *\li	item != NULL && *item point to a rdataset returned by
1005  *	dns_message_gettemprdataset()
1006  *
1007  * Ensures:
1008  *\li	*item == NULL
1009  */
1010 
1011 void
1012 dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
1013 /*%<
1014  * Return a borrowed rdatalist to the message's rdatalist free list.
1015  *
1016  * Requires:
1017  *\li	msg be a valid message
1018  *
1019  *\li	item != NULL && *item point to a rdatalist returned by
1020  *	dns_message_gettemprdatalist()
1021  *
1022  * Ensures:
1023  *\li	*item == NULL
1024  */
1025 
1026 isc_result_t
1027 dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
1028 		       unsigned int *flagsp);
1029 /*%<
1030  * Assume the remaining region of "source" is a DNS message.  Peek into
1031  * it and fill in "*idp" with the message id, and "*flagsp" with the flags.
1032  *
1033  * Requires:
1034  *
1035  *\li	source != NULL
1036  *
1037  * Ensures:
1038  *
1039  *\li	if (idp != NULL) *idp == message id.
1040  *
1041  *\li	if (flagsp != NULL) *flagsp == message flags.
1042  *
1043  * Returns:
1044  *
1045  *\li	#ISC_R_SUCCESS		-- all is well.
1046  *
1047  *\li	#ISC_R_UNEXPECTEDEND	-- buffer doesn't contain enough for a header.
1048  */
1049 
1050 isc_result_t
1051 dns_message_reply(dns_message_t *msg, bool want_question_section);
1052 /*%<
1053  * Start formatting a reply to the query in 'msg'.
1054  *
1055  * Requires:
1056  *
1057  *\li	'msg' is a valid message with parsing intent, and contains a query.
1058  *
1059  * Ensures:
1060  *
1061  *\li	The message will have a rendering intent.  If 'want_question_section'
1062  *	is true, the message opcode is query or notify, and the question
1063  *	section is present and properly formatted, then the question section
1064  *	will be included in the reply.  All other sections will be cleared.
1065  *	The QR flag will be set, the RD flag will be preserved, and all other
1066  *	flags will be cleared.
1067  *
1068  * Returns:
1069  *
1070  *\li	#ISC_R_SUCCESS		-- all is well.
1071  *
1072  *\li	#DNS_R_FORMERR		-- the header or question section of the
1073  *				   message is invalid, replying is impossible.
1074  *				   If DNS_R_FORMERR is returned when
1075  *				   want_question_section is false, then
1076  *				   it's the header section that's bad;
1077  *				   otherwise either of the header or question
1078  *				   sections may be bad.
1079  */
1080 
1081 dns_rdataset_t *
1082 dns_message_getopt(dns_message_t *msg);
1083 /*%<
1084  * Get the OPT record for 'msg'.
1085  *
1086  * Requires:
1087  *
1088  *\li	'msg' is a valid message.
1089  *
1090  * Returns:
1091  *
1092  *\li	The OPT rdataset of 'msg', or NULL if there isn't one.
1093  */
1094 
1095 isc_result_t
1096 dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
1097 /*%<
1098  * Set the OPT record for 'msg'.
1099  *
1100  * Requires:
1101  *
1102  *\li	'msg' is a valid message with rendering intent
1103  *	and no sections have been rendered.
1104  *
1105  *\li	'opt' is a valid OPT record.
1106  *
1107  * Ensures:
1108  *
1109  *\li	The OPT record has either been freed or ownership of it has
1110  *	been transferred to the message.
1111  *
1112  *\li	If ISC_R_SUCCESS was returned, the OPT record will be rendered
1113  *	when dns_message_renderend() is called.
1114  *
1115  * Returns:
1116  *
1117  *\li	#ISC_R_SUCCESS		-- all is well.
1118  *
1119  *\li	#ISC_R_NOSPACE		-- there is no space for the OPT record.
1120  */
1121 
1122 dns_rdataset_t *
1123 dns_message_gettsig(dns_message_t *msg, const dns_name_t **owner);
1124 /*%<
1125  * Get the TSIG record and owner for 'msg'.
1126  *
1127  * Requires:
1128  *
1129  *\li	'msg' is a valid message.
1130  *\li	'owner' is NULL or *owner is NULL.
1131  *
1132  * Returns:
1133  *
1134  *\li	The TSIG rdataset of 'msg', or NULL if there isn't one.
1135  *
1136  * Ensures:
1137  *
1138  * \li	If 'owner' is not NULL, it will point to the owner name.
1139  */
1140 
1141 isc_result_t
1142 dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
1143 /*%<
1144  * Set the tsig key for 'msg'.  This is only necessary for when rendering a
1145  * query or parsing a response.  The key (if non-NULL) is attached to, and
1146  * will be detached when the message is destroyed.
1147  *
1148  * Requires:
1149  *
1150  *\li	'msg' is a valid message with rendering intent,
1151  *	dns_message_renderbegin() has been called, and no sections have been
1152  *	rendered.
1153  *\li	'key' is a valid tsig key or NULL.
1154  *
1155  * Returns:
1156  *
1157  *\li	#ISC_R_SUCCESS		-- all is well.
1158  *
1159  *\li	#ISC_R_NOSPACE		-- there is no space for the TSIG record.
1160  */
1161 
1162 dns_tsigkey_t *
1163 dns_message_gettsigkey(dns_message_t *msg);
1164 /*%<
1165  * Gets the tsig key for 'msg'.
1166  *
1167  * Requires:
1168  *
1169  *\li	'msg' is a valid message
1170  */
1171 
1172 isc_result_t
1173 dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
1174 /*%<
1175  * Indicates that 'querytsig' is the TSIG from the signed query for which
1176  * 'msg' is the response.  This is also used for chained TSIGs in TCP
1177  * responses.
1178  *
1179  * Requires:
1180  *
1181  *\li	'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
1182  *	or NULL
1183  *
1184  *\li	'msg' is a valid message
1185  *
1186  * Returns:
1187  *
1188  *\li	#ISC_R_SUCCESS
1189  *\li	#ISC_R_NOMEMORY
1190  */
1191 
1192 isc_result_t
1193 dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
1194 			 isc_buffer_t **querytsig);
1195 /*%<
1196  * Gets the tsig from the TSIG from the signed query 'msg'.  This is also used
1197  * for chained TSIGs in TCP responses.  Unlike dns_message_gettsig, this makes
1198  * a copy of the data, so can be used if the message is destroyed.
1199  *
1200  * Requires:
1201  *
1202  *\li	'msg' is a valid signed message
1203  *\li	'mctx' is a valid memory context
1204  *\li	querytsig != NULL && *querytsig == NULL
1205  *
1206  * Returns:
1207  *
1208  *\li	#ISC_R_SUCCESS
1209  *\li	#ISC_R_NOMEMORY
1210  *
1211  * Ensures:
1212  *\li 	'tsig' points to NULL or an allocated buffer which must be freed
1213  * 	by the caller.
1214  */
1215 
1216 dns_rdataset_t *
1217 dns_message_getsig0(dns_message_t *msg, const dns_name_t **owner);
1218 /*%<
1219  * Get the SIG(0) record and owner for 'msg'.
1220  *
1221  * Requires:
1222  *
1223  *\li	'msg' is a valid message.
1224  *\li	'owner' is NULL or *owner is NULL.
1225  *
1226  * Returns:
1227  *
1228  *\li	The SIG(0) rdataset of 'msg', or NULL if there isn't one.
1229  *
1230  * Ensures:
1231  *
1232  * \li	If 'owner' is not NULL, it will point to the owner name.
1233  */
1234 
1235 isc_result_t
1236 dns_message_setsig0key(dns_message_t *msg, dst_key_t *key);
1237 /*%<
1238  * Set the SIG(0) key for 'msg'.
1239  *
1240  * Requires:
1241  *
1242  *\li	'msg' is a valid message with rendering intent,
1243  *	dns_message_renderbegin() has been called, and no sections have been
1244  *	rendered.
1245  *\li	'key' is a valid sig key or NULL.
1246  *
1247  * Returns:
1248  *
1249  *\li	#ISC_R_SUCCESS		-- all is well.
1250  *
1251  *\li	#ISC_R_NOSPACE		-- there is no space for the SIG(0) record.
1252  */
1253 
1254 dst_key_t *
1255 dns_message_getsig0key(dns_message_t *msg);
1256 /*%<
1257  * Gets the SIG(0) key for 'msg'.
1258  *
1259  * Requires:
1260  *
1261  *\li	'msg' is a valid message
1262  */
1263 
1264 void
1265 dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
1266 /*%<
1267  * Give the *buffer to the message code to clean up when it is no
1268  * longer needed.  This is usually when the message is reset or
1269  * destroyed.
1270  *
1271  * Requires:
1272  *
1273  *\li	msg be a valid message.
1274  *
1275  *\li	buffer != NULL && *buffer is a valid isc_buffer_t, which was
1276  *	dynamically allocated via isc_buffer_allocate().
1277  */
1278 
1279 isc_result_t
1280 dns_message_signer(dns_message_t *msg, dns_name_t *signer);
1281 /*%<
1282  * If this message was signed, return the identity of the signer.
1283  * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the
1284  * key that signed the message.
1285  *
1286  * Requires:
1287  *
1288  *\li	msg is a valid parsed message.
1289  *\li	signer is a valid name
1290  *
1291  * Returns:
1292  *
1293  *\li	#ISC_R_SUCCESS		- the message was signed, and *signer
1294  *				  contains the signing identity
1295  *
1296  *\li	#ISC_R_NOTFOUND		- no TSIG or SIG(0) record is present in the
1297  *				  message
1298  *
1299  *\li	#DNS_R_TSIGVERIFYFAILURE	- the message was signed by a TSIG, but
1300  * the signature failed to verify
1301  *
1302  *\li	#DNS_R_TSIGERRORSET	- the message was signed by a TSIG and
1303  *				  verified, but the query was rejected by
1304  *				  the server
1305  *
1306  *\li	#DNS_R_NOIDENTITY	- the message was signed by a TSIG and
1307  *				  verified, but the key has no identity since
1308  *				  it was generated by an unsigned TKEY process
1309  *
1310  *\li	#DNS_R_SIGINVALID	- the message was signed by a SIG(0), but
1311  *				  the signature failed to verify
1312  *
1313  *\li	#DNS_R_NOTVERIFIEDYET	- the message was signed by a TSIG or SIG(0),
1314  *				  but the signature has not been verified yet
1315  */
1316 
1317 isc_result_t
1318 dns_message_checksig(dns_message_t *msg, dns_view_t *view);
1319 /*%<
1320  * If this message was signed, verify the signature.
1321  *
1322  * Requires:
1323  *
1324  *\li	msg is a valid parsed message.
1325  *\li	view is a valid view or NULL
1326  *
1327  * Returns:
1328  *
1329  *\li	#ISC_R_SUCCESS		- the message was unsigned, or the message
1330  *				  was signed correctly.
1331  *
1332  *\li	#DNS_R_EXPECTEDTSIG	- A TSIG was expected, but not seen
1333  *\li	#DNS_R_UNEXPECTEDTSIG	- A TSIG was seen but not expected
1334  *\li	#DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
1335  */
1336 
1337 isc_result_t
1338 dns_message_rechecksig(dns_message_t *msg, dns_view_t *view);
1339 /*%<
1340  * Reset the signature state and then if the message was signed,
1341  * verify the message.
1342  *
1343  * Requires:
1344  *
1345  *\li	msg is a valid parsed message.
1346  *\li	view is a valid view or NULL
1347  *
1348  * Returns:
1349  *
1350  *\li	#ISC_R_SUCCESS		- the message was unsigned, or the message
1351  *				  was signed correctly.
1352  *
1353  *\li	#DNS_R_EXPECTEDTSIG	- A TSIG was expected, but not seen
1354  *\li	#DNS_R_UNEXPECTEDTSIG	- A TSIG was seen but not expected
1355  *\li	#DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
1356  */
1357 
1358 void
1359 dns_message_resetsig(dns_message_t *msg);
1360 /*%<
1361  * Reset the signature state.
1362  *
1363  * Requires:
1364  *\li	'msg' is a valid parsed message.
1365  */
1366 
1367 isc_region_t *
1368 dns_message_getrawmessage(dns_message_t *msg);
1369 /*%<
1370  * Retrieve the raw message in compressed wire format.  The message must
1371  * have been successfully parsed for it to have been saved.
1372  *
1373  * Requires:
1374  *\li	msg is a valid parsed message.
1375  *
1376  * Returns:
1377  *\li	NULL	if there is no saved message.
1378  *	a pointer to a region which refers the dns message.
1379  */
1380 
1381 void
1382 dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
1383 			 dns_aclenv_t *env, const dns_acl_t *acl,
1384 			 const dns_aclelement_t *element);
1385 /*%<
1386  * Define the order in which RR sets get rendered by
1387  * dns_message_rendersection() to be the ascending order
1388  * defined by the integer value returned by 'order' when
1389  * given each RR and a ns_sortlist_arg_t constructed from 'env',
1390  * 'acl', and 'element' as arguments.
1391  *
1392  * If 'order' is NULL, a default order is used.
1393  *
1394  * Requires:
1395  *\li	msg be a valid message.
1396  *\li	If 'env' is NULL, 'order' must be NULL.
1397  *\li	If 'env' is not NULL, 'order' must not be NULL and at least one of
1398  *	'acl' and 'element' must also not be NULL.
1399  */
1400 
1401 void
1402 dns_message_settimeadjust(dns_message_t *msg, int timeadjust);
1403 /*%<
1404  * Adjust the time used to sign/verify a message by timeadjust.
1405  * Currently only TSIG.
1406  *
1407  * Requires:
1408  *\li	msg be a valid message.
1409  */
1410 
1411 int
1412 dns_message_gettimeadjust(dns_message_t *msg);
1413 /*%<
1414  * Return the current time adjustment.
1415  *
1416  * Requires:
1417  *\li	msg be a valid message.
1418  */
1419 
1420 void
1421 dns_message_logpacket(dns_message_t *message, const char *description,
1422 		      const isc_sockaddr_t *address,
1423 		      isc_logcategory_t *category, isc_logmodule_t *module,
1424 		      int level, isc_mem_t *mctx);
1425 
1426 void
1427 dns_message_logfmtpacket(dns_message_t *message, const char *description,
1428 			 const isc_sockaddr_t *address,
1429 			 isc_logcategory_t *category, isc_logmodule_t *module,
1430 			 const dns_master_style_t *style, int level,
1431 			 isc_mem_t *mctx);
1432 /*%<
1433  * Log 'message' at the specified logging parameters.
1434  *
1435  * For dns_message_logpacket and dns_message_logfmtpacket expect the
1436  * 'description' to end in a newline.
1437  *
1438  * For dns_message_logpacket2 and dns_message_logfmtpacket2
1439  * 'description' will be emitted at the start of the message followed
1440  * by the formatted address and a newline.
1441  *
1442  * Requires:
1443  * \li   message be a valid.
1444  * \li   description to be non NULL.
1445  * \li   address to be non NULL.
1446  * \li   category to be valid.
1447  * \li   module to be valid.
1448  * \li   style to be valid.
1449  * \li   mctx to be a valid.
1450  */
1451 
1452 isc_result_t
1453 dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt,
1454 		     unsigned int version, uint16_t udpsize, unsigned int flags,
1455 		     dns_ednsopt_t *ednsopts, size_t count);
1456 /*%<
1457  * Built a opt record.
1458  *
1459  * Requires:
1460  * \li   msg be a valid message.
1461  * \li   opt to be a non NULL and *opt to be NULL.
1462  *
1463  * Returns:
1464  * \li	 ISC_R_SUCCESS on success.
1465  * \li	 ISC_R_NOMEMORY
1466  * \li	 ISC_R_NOSPACE
1467  * \li	 other.
1468  */
1469 
1470 void
1471 dns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass);
1472 /*%<
1473  * Set the expected class of records in the response.
1474  *
1475  * Requires:
1476  * \li   msg be a valid message with parsing intent.
1477  */
1478 
1479 void
1480 dns_message_setpadding(dns_message_t *msg, uint16_t padding);
1481 /*%<
1482  * Set the padding block size in the response.
1483  * 0 means no padding (default).
1484  *
1485  * Requires:
1486  * \li	msg be a valid message.
1487  */
1488 
1489 ISC_LANG_ENDDECLS
1490 
1491 #endif /* DNS_MESSAGE_H */
1492