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