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