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