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