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