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