xref: /openbsd-src/usr.bin/dig/lib/dns/include/dns/message.h (revision a0747c9f67a4ae71ccb71e62a28d1ea19e06a63c)
1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef DNS_MESSAGE_H
18 #define DNS_MESSAGE_H 1
19 
20 /***
21  ***	Imports
22  ***/
23 
24 #include <dns/compress.h>
25 #include <dns/masterdump.h>
26 #include <dns/types.h>
27 
28 #include <dst/dst.h>
29 
30 /*! \file dns/message.h
31  * \brief Message Handling Module
32  *
33  * How this beast works:
34  *
35  * When a dns message is received in a buffer, dns_message_parse() is called
36  * on the memory region.  Various items are checked including the format
37  * of the message (if counts are right, if counts consume the entire sections,
38  * and if sections consume the entire message) and known pseudo-RRs in the
39  * additional data section are analyzed and removed.
40  *
41  * TSIG checking is also done at this layer, and any DNSSEC transaction
42  * signatures should also be checked here.
43  *
44  * Notes on using the gettemp*() and puttemp*() functions:
45  *
46  * These functions return items (names, rdatasets, etc) allocated from some
47  * internal state of the dns_message_t.
48  *
49  * Names and rdatasets must be put back into the dns_message_t in
50  * one of two ways.  Assume a name was allocated via
51  * dns_message_gettempname():
52  *
53  *\li	(1) insert it into a section, using dns_message_addname().
54  *
55  *\li	(2) return it to the message using dns_message_puttempname().
56  *
57  * The same applies to rdatasets.
58  *
59  * On the other hand, offsets, rdatalists and rdatas allocated using
60  * dns_message_gettemp*() will always be freed automatically
61  * when the message is reset or destroyed; calling dns_message_puttemp*()
62  * on rdatalists and rdatas is optional and serves only to enable the item
63  * to be reused multiple times during the lifetime of the message; offsets
64  * cannot be reused.
65  *
66  * Buffers allocated using isc_buffer_allocate() can be automatically freed
67  * as well by giving the buffer to the message using dns_message_takebuffer().
68  * Doing this will cause the buffer to be freed using isc_buffer_free()
69  * when the section lists are cleared, such as in a reset or in a destroy.
70  * Since the buffer itself exists until the message is destroyed, this sort
71  * of code can be written:
72  *
73  * \code
74  *	buffer = isc_buffer_allocate(mctx, 512);
75  *	name = NULL;
76  *	name = dns_message_gettempname(message, &name);
77  *	dns_name_init(name, NULL);
78  *	result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer);
79  *	dns_message_takebuffer(message, &buffer);
80  * \endcode
81  *
82  *
83  * TODO:
84  *
85  * XXX Needed:  ways to set and retrieve EDNS information, add rdata to a
86  * section, move rdata from one section to another, remove rdata, etc.
87  */
88 
89 #define DNS_MESSAGEFLAG_QR		0x8000U
90 #define DNS_MESSAGEFLAG_AA		0x0400U
91 #define DNS_MESSAGEFLAG_TC		0x0200U
92 #define DNS_MESSAGEFLAG_RD		0x0100U
93 #define DNS_MESSAGEFLAG_RA		0x0080U
94 #define DNS_MESSAGEFLAG_AD		0x0020U
95 #define DNS_MESSAGEFLAG_CD		0x0010U
96 
97 /*%< EDNS0 extended message flags */
98 #define DNS_MESSAGEEXTFLAG_DO		0x8000U
99 
100 /*%< EDNS0 extended OPT codes */
101 #define DNS_OPT_NSID		3		/*%< NSID opt code */
102 #define DNS_OPT_CLIENT_SUBNET	8		/*%< client subnet opt code */
103 #define DNS_OPT_EXPIRE		9		/*%< EXPIRE opt code */
104 #define DNS_OPT_COOKIE		10		/*%< COOKIE opt code */
105 #define DNS_OPT_PAD		12		/*%< PAD opt code */
106 #define DNS_OPT_KEY_TAG		14		/*%< Key tag opt code */
107 #define DNS_OPT_EDE		15		/* RFC 8914 */
108 
109 /*%< The number of EDNS options we know about. */
110 #define DNS_EDNSOPTIONS	4
111 
112 #define DNS_MESSAGE_REPLYPRESERVE	(DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD)
113 #define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
114 
115 #define DNS_MESSAGE_HEADERLEN		12 /*%< 6 uint16_t's */
116 
117 /*
118  * Ordering here matters.  DNS_SECTION_ANY must be the lowest and negative,
119  * and DNS_SECTION_MAX must be one greater than the last used section.
120  */
121 typedef int dns_section_t;
122 #define DNS_SECTION_ANY			(-1)
123 #define DNS_SECTION_QUESTION		0
124 #define DNS_SECTION_ANSWER		1
125 #define DNS_SECTION_AUTHORITY		2
126 #define DNS_SECTION_ADDITIONAL		3
127 #define DNS_SECTION_MAX			4
128 
129 typedef int dns_pseudosection_t;
130 #define DNS_PSEUDOSECTION_ANY		(-1)
131 #define DNS_PSEUDOSECTION_OPT           0
132 #define DNS_PSEUDOSECTION_TSIG          1
133 #define DNS_PSEUDOSECTION_SIG0          2
134 #define DNS_PSEUDOSECTION_MAX           3
135 
136 typedef int dns_messagetextflag_t;
137 #define DNS_MESSAGETEXTFLAG_NOCOMMENTS	0x0001
138 #define DNS_MESSAGETEXTFLAG_NOHEADERS	0x0002
139 #define DNS_MESSAGETEXTFLAG_ONESOA	0x0004
140 #define DNS_MESSAGETEXTFLAG_OMITSOA	0x0008
141 
142 /*
143  * Dynamic update names for these sections.
144  */
145 #define DNS_SECTION_ZONE		DNS_SECTION_QUESTION
146 #define DNS_SECTION_PREREQUISITE	DNS_SECTION_ANSWER
147 #define DNS_SECTION_UPDATE		DNS_SECTION_AUTHORITY
148 
149 /*
150  * These tell the message library how the created dns_message_t will be used.
151  */
152 #define DNS_MESSAGE_INTENTUNKNOWN	0 /*%< internal use only */
153 #define DNS_MESSAGE_INTENTPARSE		1 /*%< parsing messages */
154 #define DNS_MESSAGE_INTENTRENDER	2 /*%< rendering */
155 
156 /*
157  * Control behavior of parsing
158  */
159 #define DNS_MESSAGEPARSE_BESTEFFORT	0x0002	/*%< return a message if a
160 						   recoverable parse error
161 						   occurs */
162 #define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< truncation errors are
163 						  * not fatal. */
164 
165 typedef struct dns_msgblock dns_msgblock_t;
166 
167 struct dns_message {
168 	/* public from here down */
169 	dns_messageid_t			id;
170 	unsigned int			flags;
171 	dns_rcode_t			rcode;
172 	dns_opcode_t			opcode;
173 	dns_rdataclass_t		rdclass;
174 
175 	/* 4 real, 1 pseudo */
176 	unsigned int			counts[DNS_SECTION_MAX];
177 
178 	/* private from here down */
179 	dns_namelist_t			sections[DNS_SECTION_MAX];
180 	dns_name_t		       *cursors[DNS_SECTION_MAX];
181 	dns_rdataset_t		       *opt;
182 	dns_rdataset_t		       *sig0;
183 	dns_rdataset_t		       *tsig;
184 
185 	int				state;
186 	unsigned int			from_to_wire : 2;
187 	unsigned int			header_ok : 1;
188 	unsigned int			question_ok : 1;
189 	unsigned int			tcp_continuation : 1;
190 	unsigned int			verified_sig : 1;
191 	unsigned int			verify_attempted : 1;
192 	unsigned int			free_query : 1;
193 	unsigned int			free_saved : 1;
194 	unsigned int			sitok : 1;
195 	unsigned int			sitbad : 1;
196 	unsigned int			tkey : 1;
197 	unsigned int			rdclass_set : 1;
198 
199 	unsigned int			opt_reserved;
200 	unsigned int			sig_reserved;
201 	unsigned int			reserved; /* reserved space (render) */
202 
203 	isc_buffer_t		       *buffer;
204 	dns_compress_t		       *cctx;
205 
206 	isc_bufferlist_t		scratchpad;
207 	isc_bufferlist_t		cleanup;
208 
209 	ISC_LIST(dns_msgblock_t)	rdatas;
210 	ISC_LIST(dns_msgblock_t)	rdatalists;
211 	ISC_LIST(dns_msgblock_t)	offsets;
212 
213 	ISC_LIST(dns_rdata_t)		freerdata;
214 	ISC_LIST(dns_rdatalist_t)	freerdatalist;
215 
216 	dns_rcode_t			tsigstatus;
217 	dns_rcode_t			querytsigstatus;
218 	dns_name_t		       *tsigname; /* Owner name of TSIG, if any */
219 	dns_rdataset_t		       *querytsig;
220 	dns_tsigkey_t		       *tsigkey;
221 	dst_context_t		       *tsigctx;
222 	int				sigstart;
223 	int				timeadjust;
224 
225 	dns_name_t		       *sig0name; /* Owner name of SIG0, if any */
226 	dns_rcode_t			sig0status;
227 	isc_region_t			query;
228 	isc_region_t			saved;
229 
230 	dns_rdatasetorderfunc_t		order;
231 	const void *			order_arg;
232 };
233 
234 struct dns_ednsopt {
235 	uint16_t			code;
236 	uint16_t			length;
237 	unsigned char			*value;
238 };
239 
240 /***
241  *** Functions
242  ***/
243 
244 isc_result_t
245 dns_message_create(unsigned int intent, dns_message_t **msgp);
246 
247 /*%<
248  * Create msg structure.
249  *
250  * This function will allocate some internal blocks of memory that are
251  * expected to be needed for parsing or rendering nearly any type of message.
252  *
253  * Requires:
254  *\li	'mctx' be a valid memory context.
255  *
256  *\li	'msgp' be non-null and '*msg' be NULL.
257  *
258  *\li	'intent' must be one of DNS_MESSAGE_INTENTPARSE or
259  *	#DNS_MESSAGE_INTENTRENDER.
260  *
261  * Ensures:
262  *\li	The data in "*msg" is set to indicate an unused and empty msg
263  *	structure.
264  *
265  * Returns:
266  *\li	#ISC_R_NOMEMORY		-- out of memory
267  *\li	#ISC_R_SUCCESS		-- success
268  */
269 
270 void
271 dns_message_destroy(dns_message_t **msgp);
272 /*%<
273  * Destroy all state in the message.
274  *
275  * Requires:
276  *
277  *\li	'msgp' be valid.
278  *
279  * Ensures:
280  *\li	'*msgp' == NULL
281  */
282 
283 isc_result_t
284 dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
285 			  const dns_master_style_t *style,
286 			  dns_messagetextflag_t flags,
287 			  isc_buffer_t *target);
288 
289 isc_result_t
290 dns_message_pseudosectiontotext(dns_message_t *msg,
291 				dns_pseudosection_t section,
292 				const dns_master_style_t *style,
293 				dns_messagetextflag_t flags,
294 				isc_buffer_t *target);
295 /*%<
296  * Convert section 'section' or 'pseudosection' of message 'msg' to
297  * a cleartext representation
298  *
299  * Notes:
300  *     \li See dns_message_totext for meanings of flags.
301  *
302  * Requires:
303  *
304  *\li	'msg' is a valid message.
305  *
306  *\li	'style' is a valid master dump style.
307  *
308  *\li	'target' is a valid buffer.
309  *
310  *\li	'section' is a valid section label.
311  *
312  * Ensures:
313  *
314  *\li	If the result is success:
315  *		The used space in 'target' is updated.
316  *
317  * Returns:
318  *
319  *\li	#ISC_R_SUCCESS
320  *\li	#ISC_R_NOSPACE
321  *\li	#ISC_R_NOMORE
322  *
323  *\li	Note: On error return, *target may be partially filled with data.
324 */
325 
326 isc_result_t
327 dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
328 		  unsigned int options);
329 /*%<
330  * Parse raw wire data in 'source' as a DNS message.
331  *
332  * OPT records are detected and stored in the pseudo-section "opt".
333  * TSIGs are detected and stored in the pseudo-section "tsig".
334  *
335  * A separate dns_name_t object will be created for each RR in the
336  * message.  Each such dns_name_t will have a single rdataset containing the
337  * single RR, and the order of the RRs in the message is preserved.
338  *
339  * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
340  * not be considered FORMERRs.  If the entire message can be parsed, it
341  * will be returned and DNS_R_RECOVERABLE will be returned.
342  *
343  * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
344  * RR's as possible, DNS_R_RECOVERABLE will be returned.
345  *
346  *
347  * Requires:
348  *\li	"msg" be valid.
349  *
350  *\li	"buffer" be a wire format buffer.
351  *
352  * Ensures:
353  *\li	The buffer's data format is correct.
354  *
355  *\li	The buffer's contents verify as correct regarding header bits, buffer
356  * 	and rdata sizes, etc.
357  *
358  * Returns:
359  *\li	#ISC_R_SUCCESS		-- all is well
360  *\li	#ISC_R_NOMEMORY		-- no memory
361  *\li	#DNS_R_RECOVERABLE	-- the message parsed properly, but contained
362  *				   errors.
363  *\li	Many other errors possible XXXMLG
364  */
365 
366 isc_result_t
367 dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
368 			isc_buffer_t *buffer);
369 /*%<
370  * Begin rendering on a message.  Only one call can be made to this function
371  * per message.
372  *
373  * The compression context is "owned" by the message library until
374  * dns_message_renderend() is called.  It must be invalidated by the caller.
375  *
376  * The buffer is "owned" by the message library until dns_message_renderend()
377  * is called.
378  *
379  * Requires:
380  *
381  *\li	'msg' be valid.
382  *
383  *\li	'cctx' be valid.
384  *
385  *\li	'buffer' is a valid buffer.
386  *
387  * Side Effects:
388  *
389  *\li	The buffer is cleared before it is used.
390  *
391  * Returns:
392  *\li	#ISC_R_SUCCESS		-- all is well
393  *\li	#ISC_R_NOSPACE		-- output buffer is too small
394  */
395 
396 isc_result_t
397 dns_message_renderreserve(dns_message_t *msg, unsigned int space);
398 /*%<
399  * XXXMLG should use size_t rather than unsigned int once the buffer
400  * API is cleaned up
401  *
402  * Reserve "space" bytes in the given buffer.
403  *
404  * Requires:
405  *
406  *\li	'msg' be valid.
407  *
408  *\li	dns_message_renderbegin() was called.
409  *
410  * Returns:
411  *\li	#ISC_R_SUCCESS		-- all is well.
412  *\li	#ISC_R_NOSPACE		-- not enough free space in the buffer.
413  */
414 
415 void
416 dns_message_renderrelease(dns_message_t *msg, unsigned int space);
417 /*%<
418  * XXXMLG should use size_t rather than unsigned int once the buffer
419  * API is cleaned up
420  *
421  * Release "space" bytes in the given buffer that was previously reserved.
422  *
423  * Requires:
424  *
425  *\li	'msg' be valid.
426  *
427  *\li	'space' is less than or equal to the total amount of space reserved
428  *	via prior calls to dns_message_renderreserve().
429  *
430  *\li	dns_message_renderbegin() was called.
431  */
432 
433 isc_result_t
434 dns_message_rendersection(dns_message_t *msg, dns_section_t section);
435 /*%<
436  * Render all names, rdatalists, etc from the given section at the
437  * specified priority or higher.
438  *
439  * Requires:
440  *\li	'msg' be valid.
441  *
442  *\li	'section' be a valid section.
443  *
444  *\li	dns_message_renderbegin() was called.
445  *
446  * Returns:
447  *\li	#ISC_R_SUCCESS		-- all records were written, and there are
448  *				   no more records for this section.
449  *\li	#ISC_R_NOSPACE		-- Not enough room in the buffer to write
450  *				   all records requested.
451  *\li	#DNS_R_MOREDATA		-- All requested records written, and there
452  *				   are records remaining for this section.
453  */
454 
455 void
456 dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
457 /*%<
458  * Render the message header.  This is implicitly called by
459  * dns_message_renderend().
460  *
461  * Requires:
462  *
463  *\li	'msg' be a valid message.
464  *
465  *\li	dns_message_renderbegin() was called.
466  *
467  *\li	'target' is a valid buffer with enough space to hold a message header
468  */
469 
470 isc_result_t
471 dns_message_renderend(dns_message_t *msg);
472 /*%<
473  * Finish rendering to the buffer.  Note that more data can be in the
474  * 'msg' structure.  Destroying the structure will free this, or in a multi-
475  * part EDNS1 message this data can be rendered to another buffer later.
476  *
477  * Requires:
478  *
479  *\li	'msg' be a valid message.
480  *
481  *\li	dns_message_renderbegin() was called.
482  *
483  * Returns:
484  *\li	#ISC_R_SUCCESS		-- all is well.
485  */
486 
487 void
488 dns_message_renderreset(dns_message_t *msg);
489 /*%<
490  * Reset the message so that it may be rendered again.
491  *
492  * Notes:
493  *
494  *\li	If dns_message_renderbegin() has been called, dns_message_renderend()
495  *	must be called before calling this function.
496  *
497  * Requires:
498  *
499  *\li	'msg' be a valid message with rendering intent.
500  */
501 
502 isc_result_t
503 dns_message_firstname(dns_message_t *msg, dns_section_t section);
504 /*%<
505  * Set internal per-section name pointer to the beginning of the section.
506  *
507  * The functions dns_message_firstname() and dns_message_nextname() may
508  * be used for iterating over the owner names in a section.
509  *
510  * Requires:
511  *
512  *\li   	'msg' be valid.
513  *
514  *\li	'section' be a valid section.
515  *
516  * Returns:
517  *\li	#ISC_R_SUCCESS		-- All is well.
518  *\li	#ISC_R_NOMORE		-- No names on given section.
519  */
520 
521 isc_result_t
522 dns_message_nextname(dns_message_t *msg, dns_section_t section);
523 /*%<
524  * Sets the internal per-section name pointer to point to the next name
525  * in that section.
526  *
527  * Requires:
528  *
529  * \li  	'msg' be valid.
530  *
531  *\li	'section' be a valid section.
532  *
533  *\li	dns_message_firstname() must have been called on this section,
534  *	and the result was ISC_R_SUCCESS.
535  *
536  * Returns:
537  *\li	#ISC_R_SUCCESS		-- All is well.
538  *\li	#ISC_R_NOMORE		-- No more names in given section.
539  */
540 
541 void
542 dns_message_currentname(dns_message_t *msg, dns_section_t section,
543 			dns_name_t **name);
544 /*%<
545  * Sets 'name' to point to the name where the per-section internal name
546  * pointer is currently set.
547  *
548  * This function returns the name in the database, so any data associated
549  * with it (via the name's "list" member) contains the actual rdatasets.
550  *
551  * Requires:
552  *
553  *\li	'msg' be valid.
554  *
555  *\li	'name' be non-NULL, and *name be NULL.
556  *
557  *\li	'section' be a valid section.
558  *
559  *\li	dns_message_firstname() must have been called on this section,
560  *	and the result of it and any dns_message_nextname() calls was
561  *	#ISC_R_SUCCESS.
562  */
563 
564 isc_result_t
565 dns_message_findname(dns_message_t *msg, dns_section_t section,
566 		     dns_name_t *target, dns_rdatatype_t type,
567 		     dns_rdatatype_t covers, dns_name_t **foundname,
568 		     dns_rdataset_t **rdataset);
569 /*%<
570  * Search for a name in the specified section.  If it is found, *name is
571  * set to point to the name, and *rdataset is set to point to the found
572  * rdataset (if type is specified as other than dns_rdatatype_any).
573  *
574  * Requires:
575  *\li	'msg' be valid.
576  *
577  *\li	'section' be a valid section.
578  *
579  *\li	If a pointer to the name is desired, 'foundname' should be non-NULL.
580  *	If it is non-NULL, '*foundname' MUST be NULL.
581  *
582  *\li	If a type other than dns_datatype_any is searched for, 'rdataset'
583  *	may be non-NULL, '*rdataset' be NULL, and will point at the found
584  *	rdataset.  If the type is dns_datatype_any, 'rdataset' must be NULL.
585  *
586  *\li	'target' be a valid name.
587  *
588  *\li	'type' be a valid type.
589  *
590  *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
591  *	Otherwise it should be 0.
592  *
593  * Returns:
594  *\li	#ISC_R_SUCCESS		-- all is well.
595  *\li	#DNS_R_NXDOMAIN		-- name does not exist in that section.
596  *\li	#DNS_R_NXRRSET		-- The name does exist, but the desired
597  *				   type does not.
598  */
599 
600 isc_result_t
601 dns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
602 		     dns_rdatatype_t covers, dns_rdataset_t **rdataset);
603 /*%<
604  * Search the name for the specified type.  If it is found, *rdataset is
605  * filled in with a pointer to that rdataset.
606  *
607  * Requires:
608  *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
609  *
610  *\li	'type' be a valid type, and NOT dns_rdatatype_any.
611  *
612  *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
613  *	Otherwise it should be 0.
614  *
615  * Returns:
616  *\li	#ISC_R_SUCCESS		-- all is well.
617  *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
618  */
619 
620 isc_result_t
621 dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
622 		 dns_rdatatype_t type, dns_rdatatype_t covers,
623 		 dns_rdataset_t **rdataset);
624 /*%<
625  * Search the name for the specified rdclass and type.  If it is found,
626  * *rdataset is filled in with a pointer to that rdataset.
627  *
628  * Requires:
629  *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
630  *
631  *\li	'type' be a valid type, and NOT dns_rdatatype_any.
632  *
633  *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
634  *	Otherwise it should be 0.
635  *
636  * Returns:
637  *\li	#ISC_R_SUCCESS		-- all is well.
638  *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
639  */
640 
641 void
642 dns_message_addname(dns_message_t *msg, dns_name_t *name,
643 		    dns_section_t section);
644 /*%<
645  * Adds the name to the given section.
646  *
647  * It is the caller's responsibility to enforce any unique name requirements
648  * in a section.
649  *
650  * Requires:
651  *
652  *\li	'msg' be valid, and be a renderable message.
653  *
654  *\li	'name' be a valid absolute name.
655  *
656  *\li	'section' be a named section.
657  */
658 
659 /*
660  * LOANOUT FUNCTIONS
661  *
662  * Each of these functions loan a particular type of data to the caller.
663  * The storage for these will vanish when the message is destroyed or
664  * reset, and must NOT be used after these operations.
665  */
666 
667 isc_result_t
668 dns_message_gettempname(dns_message_t *msg, dns_name_t **item);
669 /*%<
670  * Return a name that can be used for any temporary purpose, including
671  * inserting into the message's linked lists.  The name must be returned
672  * to the message code using dns_message_puttempname() or inserted into
673  * one of the message's sections before the message is destroyed.
674  *
675  * It is the caller's responsibility to initialize this name.
676  *
677  * Requires:
678  *\li	msg be a valid message
679  *
680  *\li	item != NULL && *item == NULL
681  *
682  * Returns:
683  *\li	#ISC_R_SUCCESS		-- All is well.
684  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
685  */
686 
687 isc_result_t
688 dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
689 /*%<
690  * Return a rdata that can be used for any temporary purpose, including
691  * inserting into the message's linked lists.  The rdata will be freed
692  * when the message is destroyed or reset.
693  *
694  * Requires:
695  *\li	msg be a valid message
696  *
697  *\li	item != NULL && *item == NULL
698  *
699  * Returns:
700  *\li	#ISC_R_SUCCESS		-- All is well.
701  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
702  */
703 
704 isc_result_t
705 dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item);
706 /*%<
707  * Return a rdataset that can be used for any temporary purpose, including
708  * inserting into the message's linked lists. The name must be returned
709  * to the message code using dns_message_puttempname() or inserted into
710  * one of the message's sections before the message is destroyed.
711  *
712  * Requires:
713  *\li	msg be a valid message
714  *
715  *\li	item != NULL && *item == NULL
716  *
717  * Returns:
718  *\li	#ISC_R_SUCCESS		-- All is well.
719  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
720  */
721 
722 isc_result_t
723 dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
724 /*%<
725  * Return a rdatalist that can be used for any temporary purpose, including
726  * inserting into the message's linked lists.  The rdatalist will be
727  * destroyed when the message is destroyed or reset.
728  *
729  * Requires:
730  *\li	msg be a valid message
731  *
732  *\li	item != NULL && *item == NULL
733  *
734  * Returns:
735  *\li	#ISC_R_SUCCESS		-- All is well.
736  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
737  */
738 
739 void
740 dns_message_puttempname(dns_message_t *msg, dns_name_t **item);
741 /*%<
742  * Return a borrowed name to the message's name free list.
743  *
744  * Requires:
745  *\li	msg be a valid message
746  *
747  *\li	item != NULL && *item point to a name returned by
748  *	dns_message_gettempname()
749  *
750  * Ensures:
751  *\li	*item == NULL
752  */
753 
754 void
755 dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item);
756 /*%<
757  * Return a borrowed rdata to the message's rdata free list.
758  *
759  * Requires:
760  *\li	msg be a valid message
761  *
762  *\li	item != NULL && *item point to a rdata returned by
763  *	dns_message_gettemprdata()
764  *
765  * Ensures:
766  *\li	*item == NULL
767  */
768 
769 void
770 dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item);
771 /*%<
772  * Return a borrowed rdataset to the message's rdataset free list.
773  *
774  * Requires:
775  *\li	msg be a valid message
776  *
777  *\li	item != NULL && *item point to a rdataset returned by
778  *	dns_message_gettemprdataset()
779  *
780  * Ensures:
781  *\li	*item == NULL
782  */
783 
784 void
785 dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
786 /*%<
787  * Return a borrowed rdatalist to the message's rdatalist free list.
788  *
789  * Requires:
790  *\li	msg be a valid message
791  *
792  *\li	item != NULL && *item point to a rdatalist returned by
793  *	dns_message_gettemprdatalist()
794  *
795  * Ensures:
796  *\li	*item == NULL
797  */
798 
799 isc_result_t
800 dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
801 		       unsigned int *flagsp);
802 /*%<
803  * Assume the remaining region of "source" is a DNS message.  Peek into
804  * it and fill in "*idp" with the message id, and "*flagsp" with the flags.
805  *
806  * Requires:
807  *
808  *\li	source != NULL
809  *
810  * Ensures:
811  *
812  *\li	if (idp != NULL) *idp == message id.
813  *
814  *\li	if (flagsp != NULL) *flagsp == message flags.
815  *
816  * Returns:
817  *
818  *\li	#ISC_R_SUCCESS		-- all is well.
819  *
820  *\li	#ISC_R_UNEXPECTEDEND	-- buffer doesn't contain enough for a header.
821  */
822 
823 dns_rdataset_t *
824 dns_message_getopt(dns_message_t *msg);
825 /*%<
826  * Get the OPT record for 'msg'.
827  *
828  * Requires:
829  *
830  *\li	'msg' is a valid message.
831  *
832  * Returns:
833  *
834  *\li	The OPT rdataset of 'msg', or NULL if there isn't one.
835  */
836 
837 isc_result_t
838 dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
839 /*%<
840  * Set the OPT record for 'msg'.
841  *
842  * Requires:
843  *
844  *\li	'msg' is a valid message with rendering intent
845  *	and no sections have been rendered.
846  *
847  *\li	'opt' is a valid OPT record.
848  *
849  * Ensures:
850  *
851  *\li	The OPT record has either been freed or ownership of it has
852  *	been transferred to the message.
853  *
854  *\li	If ISC_R_SUCCESS was returned, the OPT record will be rendered
855  *	when dns_message_renderend() is called.
856  *
857  * Returns:
858  *
859  *\li	#ISC_R_SUCCESS		-- all is well.
860  *
861  *\li	#ISC_R_NOSPACE		-- there is no space for the OPT record.
862  */
863 
864 dns_rdataset_t *
865 dns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
866 /*%<
867  * Get the TSIG record and owner for 'msg'.
868  *
869  * Requires:
870  *
871  *\li	'msg' is a valid message.
872  *\li	'owner' is NULL or *owner is NULL.
873  *
874  * Returns:
875  *
876  *\li	The TSIG rdataset of 'msg', or NULL if there isn't one.
877  *
878  * Ensures:
879  *
880  * \li	If 'owner' is not NULL, it will point to the owner name.
881  */
882 
883 isc_result_t
884 dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
885 /*%<
886  * Set the tsig key for 'msg'.  This is only necessary for when rendering a
887  * query or parsing a response.  The key (if non-NULL) is attached to, and
888  * will be detached when the message is destroyed.
889  *
890  * Requires:
891  *
892  *\li	'msg' is a valid message with rendering intent,
893  *	dns_message_renderbegin() has been called, and no sections have been
894  *	rendered.
895  *\li	'key' is a valid tsig key or NULL.
896  *
897  * Returns:
898  *
899  *\li	#ISC_R_SUCCESS		-- all is well.
900  *
901  *\li	#ISC_R_NOSPACE		-- there is no space for the TSIG record.
902  */
903 
904 dns_tsigkey_t *
905 dns_message_gettsigkey(dns_message_t *msg);
906 /*%<
907  * Gets the tsig key for 'msg'.
908  *
909  * Requires:
910  *
911  *\li	'msg' is a valid message
912  */
913 
914 isc_result_t
915 dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
916 /*%<
917  * Indicates that 'querytsig' is the TSIG from the signed query for which
918  * 'msg' is the response.  This is also used for chained TSIGs in TCP
919  * responses.
920  *
921  * Requires:
922  *
923  *\li	'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
924  *	or NULL
925  *
926  *\li	'msg' is a valid message
927  *
928  * Returns:
929  *
930  *\li	#ISC_R_SUCCESS
931  *\li	#ISC_R_NOMEMORY
932  */
933 
934 isc_result_t
935 dns_message_getquerytsig(dns_message_t *msg, isc_buffer_t **querytsig);
936 /*%<
937  * Gets the tsig from the TSIG from the signed query 'msg'.  This is also used
938  * for chained TSIGs in TCP responses.  Unlike dns_message_gettsig, this makes
939  * a copy of the data, so can be used if the message is destroyed.
940  *
941  * Requires:
942  *
943  *\li	'msg' is a valid signed message
944  *\li	'mctx' is a valid memory context
945  *\li	querytsig != NULL && *querytsig == NULL
946  *
947  * Returns:
948  *
949  *\li	#ISC_R_SUCCESS
950  *\li	#ISC_R_NOMEMORY
951  *
952  * Ensures:
953  *\li 	'tsig' points to NULL or an allocated buffer which must be freed
954  * 	by the caller.
955  */
956 
957 dns_rdataset_t *
958 dns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
959 /*%<
960  * Get the SIG(0) record and owner for 'msg'.
961  *
962  * Requires:
963  *
964  *\li	'msg' is a valid message.
965  *\li	'owner' is NULL or *owner is NULL.
966  *
967  * Returns:
968  *
969  *\li	The SIG(0) rdataset of 'msg', or NULL if there isn't one.
970  *
971  * Ensures:
972  *
973  * \li	If 'owner' is not NULL, it will point to the owner name.
974  */
975 
976 void
977 dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
978 /*%<
979  * Give the *buffer to the message code to clean up when it is no
980  * longer needed.  This is usually when the message is reset or
981  * destroyed.
982  *
983  * Requires:
984  *
985  *\li	msg be a valid message.
986  *
987  *\li	buffer != NULL && *buffer is a valid isc_buffer_t, which was
988  *	dynamically allocated via isc_buffer_allocate().
989  */
990 
991 isc_result_t
992 dns_message_rechecksig(dns_message_t *msg, dns_view_t *view);
993 /*%<
994  * Reset the signature state and then if the message was signed,
995  * verify the message.
996  *
997  * Requires:
998  *
999  *\li	msg is a valid parsed message.
1000  *\li	view is a valid view or NULL
1001  *
1002  * Returns:
1003  *
1004  *\li	#ISC_R_SUCCESS		- the message was unsigned, or the message
1005  *				  was signed correctly.
1006  *
1007  *\li	#DNS_R_EXPECTEDTSIG	- A TSIG was expected, but not seen
1008  *\li	#DNS_R_UNEXPECTEDTSIG	- A TSIG was seen but not expected
1009  *\li	#DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
1010  */
1011 
1012 isc_result_t
1013 dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt,
1014 		     unsigned int version, uint16_t udpsize,
1015 		     unsigned int flags, dns_ednsopt_t *ednsopts, size_t count);
1016 /*%<
1017  * Built a opt record.
1018  *
1019  * Requires:
1020  * \li   msg be a valid message.
1021  * \li   opt to be a non NULL and *opt to be NULL.
1022  *
1023  * Returns:
1024  * \li	 ISC_R_SUCCESS on success.
1025  * \li	 ISC_R_NOMEMORY
1026  * \li	 ISC_R_NOSPACE
1027  * \li	 other.
1028  */
1029 
1030 #endif /* DNS_MESSAGE_H */
1031