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