xref: /openbsd-src/usr.bin/dig/lib/dns/include/dns/message.h (revision 9835a5e128ac1db1a0a5e36c27d1a17b7926c0b3)
15185a700Sflorian /*
25185a700Sflorian  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
35185a700Sflorian  *
45185a700Sflorian  * Permission to use, copy, modify, and/or distribute this software for any
55185a700Sflorian  * purpose with or without fee is hereby granted, provided that the above
65185a700Sflorian  * copyright notice and this permission notice appear in all copies.
75185a700Sflorian  *
85185a700Sflorian  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
95185a700Sflorian  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
105185a700Sflorian  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
115185a700Sflorian  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
125185a700Sflorian  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
135185a700Sflorian  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
145185a700Sflorian  * PERFORMANCE OF THIS SOFTWARE.
155185a700Sflorian  */
165185a700Sflorian 
175185a700Sflorian #ifndef DNS_MESSAGE_H
185185a700Sflorian #define DNS_MESSAGE_H 1
195185a700Sflorian 
205185a700Sflorian /***
215185a700Sflorian  ***	Imports
225185a700Sflorian  ***/
235185a700Sflorian 
245185a700Sflorian #include <dns/compress.h>
255185a700Sflorian #include <dns/masterdump.h>
265185a700Sflorian #include <dns/types.h>
275185a700Sflorian 
285185a700Sflorian #include <dst/dst.h>
295185a700Sflorian 
305185a700Sflorian /*! \file dns/message.h
315185a700Sflorian  * \brief Message Handling Module
325185a700Sflorian  *
335185a700Sflorian  * How this beast works:
345185a700Sflorian  *
355185a700Sflorian  * When a dns message is received in a buffer, dns_message_parse() is called
365185a700Sflorian  * on the memory region.  Various items are checked including the format
375185a700Sflorian  * of the message (if counts are right, if counts consume the entire sections,
385185a700Sflorian  * and if sections consume the entire message) and known pseudo-RRs in the
395185a700Sflorian  * additional data section are analyzed and removed.
405185a700Sflorian  *
415185a700Sflorian  * TSIG checking is also done at this layer, and any DNSSEC transaction
425185a700Sflorian  * signatures should also be checked here.
435185a700Sflorian  *
445185a700Sflorian  * Notes on using the gettemp*() and puttemp*() functions:
455185a700Sflorian  *
465185a700Sflorian  * These functions return items (names, rdatasets, etc) allocated from some
475185a700Sflorian  * internal state of the dns_message_t.
485185a700Sflorian  *
495185a700Sflorian  * Names and rdatasets must be put back into the dns_message_t in
505185a700Sflorian  * one of two ways.  Assume a name was allocated via
515185a700Sflorian  * dns_message_gettempname():
525185a700Sflorian  *
535185a700Sflorian  *\li	(1) insert it into a section, using dns_message_addname().
545185a700Sflorian  *
555185a700Sflorian  *\li	(2) return it to the message using dns_message_puttempname().
565185a700Sflorian  *
575185a700Sflorian  * The same applies to rdatasets.
585185a700Sflorian  *
595185a700Sflorian  * On the other hand, offsets, rdatalists and rdatas allocated using
605185a700Sflorian  * dns_message_gettemp*() will always be freed automatically
615185a700Sflorian  * when the message is reset or destroyed; calling dns_message_puttemp*()
625185a700Sflorian  * on rdatalists and rdatas is optional and serves only to enable the item
635185a700Sflorian  * to be reused multiple times during the lifetime of the message; offsets
645185a700Sflorian  * cannot be reused.
655185a700Sflorian  *
665185a700Sflorian  * Buffers allocated using isc_buffer_allocate() can be automatically freed
675185a700Sflorian  * as well by giving the buffer to the message using dns_message_takebuffer().
685185a700Sflorian  * Doing this will cause the buffer to be freed using isc_buffer_free()
695185a700Sflorian  * when the section lists are cleared, such as in a reset or in a destroy.
705185a700Sflorian  * Since the buffer itself exists until the message is destroyed, this sort
715185a700Sflorian  * of code can be written:
725185a700Sflorian  *
735185a700Sflorian  * \code
745185a700Sflorian  *	buffer = isc_buffer_allocate(mctx, 512);
755185a700Sflorian  *	name = NULL;
765185a700Sflorian  *	name = dns_message_gettempname(message, &name);
775185a700Sflorian  *	dns_name_init(name, NULL);
785185a700Sflorian  *	result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer);
795185a700Sflorian  *	dns_message_takebuffer(message, &buffer);
805185a700Sflorian  * \endcode
815185a700Sflorian  *
825185a700Sflorian  *
835185a700Sflorian  * TODO:
845185a700Sflorian  *
855185a700Sflorian  * XXX Needed:  ways to set and retrieve EDNS information, add rdata to a
865185a700Sflorian  * section, move rdata from one section to another, remove rdata, etc.
875185a700Sflorian  */
885185a700Sflorian 
895185a700Sflorian #define DNS_MESSAGEFLAG_QR		0x8000U
905185a700Sflorian #define DNS_MESSAGEFLAG_AA		0x0400U
915185a700Sflorian #define DNS_MESSAGEFLAG_TC		0x0200U
925185a700Sflorian #define DNS_MESSAGEFLAG_RD		0x0100U
935185a700Sflorian #define DNS_MESSAGEFLAG_RA		0x0080U
945185a700Sflorian #define DNS_MESSAGEFLAG_AD		0x0020U
955185a700Sflorian #define DNS_MESSAGEFLAG_CD		0x0010U
965185a700Sflorian 
975185a700Sflorian /*%< EDNS0 extended message flags */
985185a700Sflorian #define DNS_MESSAGEEXTFLAG_DO		0x8000U
995185a700Sflorian 
1005185a700Sflorian /*%< EDNS0 extended OPT codes */
1015185a700Sflorian #define DNS_OPT_NSID		3		/*%< NSID opt code */
1025185a700Sflorian #define DNS_OPT_CLIENT_SUBNET	8		/*%< client subnet opt code */
1035185a700Sflorian #define DNS_OPT_EXPIRE		9		/*%< EXPIRE opt code */
1045185a700Sflorian #define DNS_OPT_COOKIE		10		/*%< COOKIE opt code */
1055185a700Sflorian #define DNS_OPT_PAD		12		/*%< PAD opt code */
1065185a700Sflorian #define DNS_OPT_KEY_TAG		14		/*%< Key tag opt code */
107fabbbca0Sflorian #define DNS_OPT_EDE		15		/* RFC 8914 */
108*9835a5e1Sflorian #define DNS_OPT_ZONEVERSION	19		/* RFC 9660 */
1095185a700Sflorian 
1105185a700Sflorian /*%< The number of EDNS options we know about. */
1115185a700Sflorian #define DNS_EDNSOPTIONS	4
1125185a700Sflorian 
1135185a700Sflorian #define DNS_MESSAGE_REPLYPRESERVE	(DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD)
1145185a700Sflorian #define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
1155185a700Sflorian 
1165185a700Sflorian #define DNS_MESSAGE_HEADERLEN		12 /*%< 6 uint16_t's */
1175185a700Sflorian 
1185185a700Sflorian /*
1195185a700Sflorian  * Ordering here matters.  DNS_SECTION_ANY must be the lowest and negative,
1205185a700Sflorian  * and DNS_SECTION_MAX must be one greater than the last used section.
1215185a700Sflorian  */
1225185a700Sflorian typedef int dns_section_t;
1235185a700Sflorian #define DNS_SECTION_ANY			(-1)
1245185a700Sflorian #define DNS_SECTION_QUESTION		0
1255185a700Sflorian #define DNS_SECTION_ANSWER		1
1265185a700Sflorian #define DNS_SECTION_AUTHORITY		2
1275185a700Sflorian #define DNS_SECTION_ADDITIONAL		3
1285185a700Sflorian #define DNS_SECTION_MAX			4
1295185a700Sflorian 
1305185a700Sflorian typedef int dns_pseudosection_t;
1315185a700Sflorian #define DNS_PSEUDOSECTION_ANY		(-1)
1325185a700Sflorian #define DNS_PSEUDOSECTION_OPT           0
1335185a700Sflorian #define DNS_PSEUDOSECTION_TSIG          1
1345185a700Sflorian #define DNS_PSEUDOSECTION_SIG0          2
1355185a700Sflorian #define DNS_PSEUDOSECTION_MAX           3
1365185a700Sflorian 
1375185a700Sflorian typedef int dns_messagetextflag_t;
1385185a700Sflorian #define DNS_MESSAGETEXTFLAG_NOCOMMENTS	0x0001
1395185a700Sflorian #define DNS_MESSAGETEXTFLAG_NOHEADERS	0x0002
1405185a700Sflorian #define DNS_MESSAGETEXTFLAG_ONESOA	0x0004
1415185a700Sflorian #define DNS_MESSAGETEXTFLAG_OMITSOA	0x0008
1425185a700Sflorian 
1435185a700Sflorian /*
1445185a700Sflorian  * Dynamic update names for these sections.
1455185a700Sflorian  */
1465185a700Sflorian #define DNS_SECTION_ZONE		DNS_SECTION_QUESTION
1475185a700Sflorian #define DNS_SECTION_PREREQUISITE	DNS_SECTION_ANSWER
1485185a700Sflorian #define DNS_SECTION_UPDATE		DNS_SECTION_AUTHORITY
1495185a700Sflorian 
1505185a700Sflorian /*
1515185a700Sflorian  * These tell the message library how the created dns_message_t will be used.
1525185a700Sflorian  */
1535185a700Sflorian #define DNS_MESSAGE_INTENTUNKNOWN	0 /*%< internal use only */
1545185a700Sflorian #define DNS_MESSAGE_INTENTPARSE		1 /*%< parsing messages */
1555185a700Sflorian #define DNS_MESSAGE_INTENTRENDER	2 /*%< rendering */
1565185a700Sflorian 
1575185a700Sflorian /*
1585185a700Sflorian  * Control behavior of parsing
1595185a700Sflorian  */
1605185a700Sflorian #define DNS_MESSAGEPARSE_BESTEFFORT	0x0002	/*%< return a message if a
1615185a700Sflorian 						   recoverable parse error
1625185a700Sflorian 						   occurs */
1635185a700Sflorian #define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< truncation errors are
1645185a700Sflorian 						  * not fatal. */
1655185a700Sflorian 
1665185a700Sflorian typedef struct dns_msgblock dns_msgblock_t;
1675185a700Sflorian 
1685185a700Sflorian struct dns_message {
1695185a700Sflorian 	/* public from here down */
1705185a700Sflorian 	dns_messageid_t			id;
1715185a700Sflorian 	unsigned int			flags;
1725185a700Sflorian 	dns_rcode_t			rcode;
1735185a700Sflorian 	dns_opcode_t			opcode;
1745185a700Sflorian 	dns_rdataclass_t		rdclass;
1755185a700Sflorian 
1765185a700Sflorian 	/* 4 real, 1 pseudo */
1775185a700Sflorian 	unsigned int			counts[DNS_SECTION_MAX];
1785185a700Sflorian 
1795185a700Sflorian 	/* private from here down */
1805185a700Sflorian 	dns_namelist_t			sections[DNS_SECTION_MAX];
1815185a700Sflorian 	dns_name_t		       *cursors[DNS_SECTION_MAX];
1825185a700Sflorian 	dns_rdataset_t		       *opt;
1835185a700Sflorian 	dns_rdataset_t		       *sig0;
1845185a700Sflorian 	dns_rdataset_t		       *tsig;
1855185a700Sflorian 
1865185a700Sflorian 	int				state;
1875185a700Sflorian 	unsigned int			from_to_wire : 2;
1885185a700Sflorian 	unsigned int			header_ok : 1;
1895185a700Sflorian 	unsigned int			question_ok : 1;
1905185a700Sflorian 	unsigned int			tcp_continuation : 1;
1915185a700Sflorian 	unsigned int			verified_sig : 1;
1925185a700Sflorian 	unsigned int			verify_attempted : 1;
1935185a700Sflorian 	unsigned int			free_query : 1;
1945185a700Sflorian 	unsigned int			free_saved : 1;
1955185a700Sflorian 	unsigned int			sitok : 1;
1965185a700Sflorian 	unsigned int			sitbad : 1;
1975185a700Sflorian 	unsigned int			tkey : 1;
1985185a700Sflorian 	unsigned int			rdclass_set : 1;
1995185a700Sflorian 
2005185a700Sflorian 	unsigned int			opt_reserved;
2015185a700Sflorian 	unsigned int			sig_reserved;
2025185a700Sflorian 	unsigned int			reserved; /* reserved space (render) */
2035185a700Sflorian 
2045185a700Sflorian 	isc_buffer_t		       *buffer;
2055185a700Sflorian 	dns_compress_t		       *cctx;
2065185a700Sflorian 
2075185a700Sflorian 	isc_bufferlist_t		scratchpad;
2085185a700Sflorian 	isc_bufferlist_t		cleanup;
2095185a700Sflorian 
2105185a700Sflorian 	ISC_LIST(dns_msgblock_t)	rdatas;
2115185a700Sflorian 	ISC_LIST(dns_msgblock_t)	rdatalists;
2125185a700Sflorian 	ISC_LIST(dns_msgblock_t)	offsets;
2135185a700Sflorian 
2145185a700Sflorian 	ISC_LIST(dns_rdata_t)		freerdata;
2155185a700Sflorian 	ISC_LIST(dns_rdatalist_t)	freerdatalist;
2165185a700Sflorian 
2175185a700Sflorian 	dns_rcode_t			tsigstatus;
2185185a700Sflorian 	dns_rcode_t			querytsigstatus;
2195185a700Sflorian 	dns_name_t		       *tsigname; /* Owner name of TSIG, if any */
2205185a700Sflorian 	dns_rdataset_t		       *querytsig;
2215185a700Sflorian 	dns_tsigkey_t		       *tsigkey;
2225185a700Sflorian 	dst_context_t		       *tsigctx;
2235185a700Sflorian 	int				sigstart;
2245185a700Sflorian 	int				timeadjust;
2255185a700Sflorian 
2265185a700Sflorian 	dns_name_t		       *sig0name; /* Owner name of SIG0, if any */
2275185a700Sflorian 	dns_rcode_t			sig0status;
2285185a700Sflorian 	isc_region_t			query;
2295185a700Sflorian 	isc_region_t			saved;
2305185a700Sflorian };
2315185a700Sflorian 
2325185a700Sflorian struct dns_ednsopt {
2335185a700Sflorian 	uint16_t			code;
2345185a700Sflorian 	uint16_t			length;
2355185a700Sflorian 	unsigned char			*value;
2365185a700Sflorian };
2375185a700Sflorian 
2385185a700Sflorian /***
2395185a700Sflorian  *** Functions
2405185a700Sflorian  ***/
2415185a700Sflorian 
2425185a700Sflorian isc_result_t
2435185a700Sflorian dns_message_create(unsigned int intent, dns_message_t **msgp);
2445185a700Sflorian 
2455185a700Sflorian /*%<
2465185a700Sflorian  * Create msg structure.
2475185a700Sflorian  *
2485185a700Sflorian  * This function will allocate some internal blocks of memory that are
2495185a700Sflorian  * expected to be needed for parsing or rendering nearly any type of message.
2505185a700Sflorian  *
2515185a700Sflorian  * Requires:
2525185a700Sflorian  *\li	'mctx' be a valid memory context.
2535185a700Sflorian  *
2545185a700Sflorian  *\li	'msgp' be non-null and '*msg' be NULL.
2555185a700Sflorian  *
2565185a700Sflorian  *\li	'intent' must be one of DNS_MESSAGE_INTENTPARSE or
2575185a700Sflorian  *	#DNS_MESSAGE_INTENTRENDER.
2585185a700Sflorian  *
2595185a700Sflorian  * Ensures:
2605185a700Sflorian  *\li	The data in "*msg" is set to indicate an unused and empty msg
2615185a700Sflorian  *	structure.
2625185a700Sflorian  *
2635185a700Sflorian  * Returns:
2645185a700Sflorian  *\li	#ISC_R_NOMEMORY		-- out of memory
2655185a700Sflorian  *\li	#ISC_R_SUCCESS		-- success
2665185a700Sflorian  */
2675185a700Sflorian 
2685185a700Sflorian void
2695185a700Sflorian dns_message_destroy(dns_message_t **msgp);
2705185a700Sflorian /*%<
2715185a700Sflorian  * Destroy all state in the message.
2725185a700Sflorian  *
2735185a700Sflorian  * Requires:
2745185a700Sflorian  *
2755185a700Sflorian  *\li	'msgp' be valid.
2765185a700Sflorian  *
2775185a700Sflorian  * Ensures:
2785185a700Sflorian  *\li	'*msgp' == NULL
2795185a700Sflorian  */
2805185a700Sflorian 
2815185a700Sflorian isc_result_t
2825185a700Sflorian dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
2835185a700Sflorian 			  const dns_master_style_t *style,
2845185a700Sflorian 			  dns_messagetextflag_t flags,
2855185a700Sflorian 			  isc_buffer_t *target);
2865185a700Sflorian 
2875185a700Sflorian isc_result_t
2885185a700Sflorian dns_message_pseudosectiontotext(dns_message_t *msg,
2895185a700Sflorian 				dns_pseudosection_t section,
2905185a700Sflorian 				const dns_master_style_t *style,
2915185a700Sflorian 				dns_messagetextflag_t flags,
292*9835a5e1Sflorian 				const char *textname,
2935185a700Sflorian 				isc_buffer_t *target);
2945185a700Sflorian /*%<
2955185a700Sflorian  * Convert section 'section' or 'pseudosection' of message 'msg' to
2965185a700Sflorian  * a cleartext representation
2975185a700Sflorian  *
2985185a700Sflorian  * Notes:
2995185a700Sflorian  *     \li See dns_message_totext for meanings of flags.
3005185a700Sflorian  *
3015185a700Sflorian  * Requires:
3025185a700Sflorian  *
3035185a700Sflorian  *\li	'msg' is a valid message.
3045185a700Sflorian  *
3055185a700Sflorian  *\li	'style' is a valid master dump style.
3065185a700Sflorian  *
3075185a700Sflorian  *\li	'target' is a valid buffer.
3085185a700Sflorian  *
3095185a700Sflorian  *\li	'section' is a valid section label.
3105185a700Sflorian  *
3115185a700Sflorian  * Ensures:
3125185a700Sflorian  *
3135185a700Sflorian  *\li	If the result is success:
3145185a700Sflorian  *		The used space in 'target' is updated.
3155185a700Sflorian  *
3165185a700Sflorian  * Returns:
3175185a700Sflorian  *
3185185a700Sflorian  *\li	#ISC_R_SUCCESS
3195185a700Sflorian  *\li	#ISC_R_NOSPACE
3205185a700Sflorian  *\li	#ISC_R_NOMORE
3215185a700Sflorian  *
3225185a700Sflorian  *\li	Note: On error return, *target may be partially filled with data.
3235185a700Sflorian */
3245185a700Sflorian 
3255185a700Sflorian isc_result_t
3265185a700Sflorian dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
3275185a700Sflorian 		  unsigned int options);
3285185a700Sflorian /*%<
3295185a700Sflorian  * Parse raw wire data in 'source' as a DNS message.
3305185a700Sflorian  *
3315185a700Sflorian  * OPT records are detected and stored in the pseudo-section "opt".
3325185a700Sflorian  * TSIGs are detected and stored in the pseudo-section "tsig".
3335185a700Sflorian  *
334a9a8f5b3Sflorian  * A separate dns_name_t object will be created for each RR in the
3355185a700Sflorian  * message.  Each such dns_name_t will have a single rdataset containing the
3365185a700Sflorian  * single RR, and the order of the RRs in the message is preserved.
3375185a700Sflorian  *
3385185a700Sflorian  * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
3395185a700Sflorian  * not be considered FORMERRs.  If the entire message can be parsed, it
3405185a700Sflorian  * will be returned and DNS_R_RECOVERABLE will be returned.
3415185a700Sflorian  *
3425185a700Sflorian  * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
3435185a700Sflorian  * RR's as possible, DNS_R_RECOVERABLE will be returned.
3445185a700Sflorian  *
3455185a700Sflorian  *
3465185a700Sflorian  * Requires:
3475185a700Sflorian  *\li	"msg" be valid.
3485185a700Sflorian  *
3495185a700Sflorian  *\li	"buffer" be a wire format buffer.
3505185a700Sflorian  *
3515185a700Sflorian  * Ensures:
3525185a700Sflorian  *\li	The buffer's data format is correct.
3535185a700Sflorian  *
3545185a700Sflorian  *\li	The buffer's contents verify as correct regarding header bits, buffer
3555185a700Sflorian  * 	and rdata sizes, etc.
3565185a700Sflorian  *
3575185a700Sflorian  * Returns:
3585185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all is well
3595185a700Sflorian  *\li	#ISC_R_NOMEMORY		-- no memory
3605185a700Sflorian  *\li	#DNS_R_RECOVERABLE	-- the message parsed properly, but contained
3615185a700Sflorian  *				   errors.
3625185a700Sflorian  *\li	Many other errors possible XXXMLG
3635185a700Sflorian  */
3645185a700Sflorian 
3655185a700Sflorian isc_result_t
3665185a700Sflorian dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
3675185a700Sflorian 			isc_buffer_t *buffer);
3685185a700Sflorian /*%<
3695185a700Sflorian  * Begin rendering on a message.  Only one call can be made to this function
3705185a700Sflorian  * per message.
3715185a700Sflorian  *
3725185a700Sflorian  * The compression context is "owned" by the message library until
3735185a700Sflorian  * dns_message_renderend() is called.  It must be invalidated by the caller.
3745185a700Sflorian  *
3755185a700Sflorian  * The buffer is "owned" by the message library until dns_message_renderend()
3765185a700Sflorian  * is called.
3775185a700Sflorian  *
3785185a700Sflorian  * Requires:
3795185a700Sflorian  *
3805185a700Sflorian  *\li	'msg' be valid.
3815185a700Sflorian  *
3825185a700Sflorian  *\li	'cctx' be valid.
3835185a700Sflorian  *
3845185a700Sflorian  *\li	'buffer' is a valid buffer.
3855185a700Sflorian  *
3865185a700Sflorian  * Side Effects:
3875185a700Sflorian  *
3885185a700Sflorian  *\li	The buffer is cleared before it is used.
3895185a700Sflorian  *
3905185a700Sflorian  * Returns:
3915185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all is well
3925185a700Sflorian  *\li	#ISC_R_NOSPACE		-- output buffer is too small
3935185a700Sflorian  */
3945185a700Sflorian 
3955185a700Sflorian isc_result_t
3965185a700Sflorian dns_message_renderreserve(dns_message_t *msg, unsigned int space);
3975185a700Sflorian /*%<
3985185a700Sflorian  * XXXMLG should use size_t rather than unsigned int once the buffer
3995185a700Sflorian  * API is cleaned up
4005185a700Sflorian  *
4015185a700Sflorian  * Reserve "space" bytes in the given buffer.
4025185a700Sflorian  *
4035185a700Sflorian  * Requires:
4045185a700Sflorian  *
4055185a700Sflorian  *\li	'msg' be valid.
4065185a700Sflorian  *
4075185a700Sflorian  *\li	dns_message_renderbegin() was called.
4085185a700Sflorian  *
4095185a700Sflorian  * Returns:
4105185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all is well.
4115185a700Sflorian  *\li	#ISC_R_NOSPACE		-- not enough free space in the buffer.
4125185a700Sflorian  */
4135185a700Sflorian 
4145185a700Sflorian void
4155185a700Sflorian dns_message_renderrelease(dns_message_t *msg, unsigned int space);
4165185a700Sflorian /*%<
4175185a700Sflorian  * XXXMLG should use size_t rather than unsigned int once the buffer
4185185a700Sflorian  * API is cleaned up
4195185a700Sflorian  *
4205185a700Sflorian  * Release "space" bytes in the given buffer that was previously reserved.
4215185a700Sflorian  *
4225185a700Sflorian  * Requires:
4235185a700Sflorian  *
4245185a700Sflorian  *\li	'msg' be valid.
4255185a700Sflorian  *
4265185a700Sflorian  *\li	'space' is less than or equal to the total amount of space reserved
4275185a700Sflorian  *	via prior calls to dns_message_renderreserve().
4285185a700Sflorian  *
4295185a700Sflorian  *\li	dns_message_renderbegin() was called.
4305185a700Sflorian  */
4315185a700Sflorian 
4325185a700Sflorian isc_result_t
4337d5fc286Sflorian dns_message_rendersection(dns_message_t *msg, dns_section_t section);
4345185a700Sflorian /*%<
4355185a700Sflorian  * Render all names, rdatalists, etc from the given section at the
4365185a700Sflorian  * specified priority or higher.
4375185a700Sflorian  *
4385185a700Sflorian  * Requires:
4395185a700Sflorian  *\li	'msg' be valid.
4405185a700Sflorian  *
4415185a700Sflorian  *\li	'section' be a valid section.
4425185a700Sflorian  *
4435185a700Sflorian  *\li	dns_message_renderbegin() was called.
4445185a700Sflorian  *
4455185a700Sflorian  * Returns:
4465185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all records were written, and there are
4475185a700Sflorian  *				   no more records for this section.
4485185a700Sflorian  *\li	#ISC_R_NOSPACE		-- Not enough room in the buffer to write
4495185a700Sflorian  *				   all records requested.
4505185a700Sflorian  *\li	#DNS_R_MOREDATA		-- All requested records written, and there
4515185a700Sflorian  *				   are records remaining for this section.
4525185a700Sflorian  */
4535185a700Sflorian 
4545185a700Sflorian void
4555185a700Sflorian dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
4565185a700Sflorian /*%<
4575185a700Sflorian  * Render the message header.  This is implicitly called by
4585185a700Sflorian  * dns_message_renderend().
4595185a700Sflorian  *
4605185a700Sflorian  * Requires:
4615185a700Sflorian  *
4625185a700Sflorian  *\li	'msg' be a valid message.
4635185a700Sflorian  *
4645185a700Sflorian  *\li	dns_message_renderbegin() was called.
4655185a700Sflorian  *
4665185a700Sflorian  *\li	'target' is a valid buffer with enough space to hold a message header
4675185a700Sflorian  */
4685185a700Sflorian 
4695185a700Sflorian isc_result_t
4705185a700Sflorian dns_message_renderend(dns_message_t *msg);
4715185a700Sflorian /*%<
4725185a700Sflorian  * Finish rendering to the buffer.  Note that more data can be in the
4735185a700Sflorian  * 'msg' structure.  Destroying the structure will free this, or in a multi-
4745185a700Sflorian  * part EDNS1 message this data can be rendered to another buffer later.
4755185a700Sflorian  *
4765185a700Sflorian  * Requires:
4775185a700Sflorian  *
4785185a700Sflorian  *\li	'msg' be a valid message.
4795185a700Sflorian  *
4805185a700Sflorian  *\li	dns_message_renderbegin() was called.
4815185a700Sflorian  *
4825185a700Sflorian  * Returns:
4835185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all is well.
4845185a700Sflorian  */
4855185a700Sflorian 
4865185a700Sflorian void
4875185a700Sflorian dns_message_renderreset(dns_message_t *msg);
4885185a700Sflorian /*%<
4895185a700Sflorian  * Reset the message so that it may be rendered again.
4905185a700Sflorian  *
4915185a700Sflorian  * Notes:
4925185a700Sflorian  *
4935185a700Sflorian  *\li	If dns_message_renderbegin() has been called, dns_message_renderend()
4945185a700Sflorian  *	must be called before calling this function.
4955185a700Sflorian  *
4965185a700Sflorian  * Requires:
4975185a700Sflorian  *
4985185a700Sflorian  *\li	'msg' be a valid message with rendering intent.
4995185a700Sflorian  */
5005185a700Sflorian 
5015185a700Sflorian isc_result_t
5025185a700Sflorian dns_message_firstname(dns_message_t *msg, dns_section_t section);
5035185a700Sflorian /*%<
5045185a700Sflorian  * Set internal per-section name pointer to the beginning of the section.
5055185a700Sflorian  *
5065185a700Sflorian  * The functions dns_message_firstname() and dns_message_nextname() may
5075185a700Sflorian  * be used for iterating over the owner names in a section.
5085185a700Sflorian  *
5095185a700Sflorian  * Requires:
5105185a700Sflorian  *
5115185a700Sflorian  *\li   	'msg' be valid.
5125185a700Sflorian  *
5135185a700Sflorian  *\li	'section' be a valid section.
5145185a700Sflorian  *
5155185a700Sflorian  * Returns:
5165185a700Sflorian  *\li	#ISC_R_SUCCESS		-- All is well.
5175185a700Sflorian  *\li	#ISC_R_NOMORE		-- No names on given section.
5185185a700Sflorian  */
5195185a700Sflorian 
5205185a700Sflorian isc_result_t
5215185a700Sflorian dns_message_nextname(dns_message_t *msg, dns_section_t section);
5225185a700Sflorian /*%<
5235185a700Sflorian  * Sets the internal per-section name pointer to point to the next name
5245185a700Sflorian  * in that section.
5255185a700Sflorian  *
5265185a700Sflorian  * Requires:
5275185a700Sflorian  *
5285185a700Sflorian  * \li  	'msg' be valid.
5295185a700Sflorian  *
5305185a700Sflorian  *\li	'section' be a valid section.
5315185a700Sflorian  *
5325185a700Sflorian  *\li	dns_message_firstname() must have been called on this section,
5335185a700Sflorian  *	and the result was ISC_R_SUCCESS.
5345185a700Sflorian  *
5355185a700Sflorian  * Returns:
5365185a700Sflorian  *\li	#ISC_R_SUCCESS		-- All is well.
5375185a700Sflorian  *\li	#ISC_R_NOMORE		-- No more names in given section.
5385185a700Sflorian  */
5395185a700Sflorian 
5405185a700Sflorian void
5415185a700Sflorian dns_message_currentname(dns_message_t *msg, dns_section_t section,
5425185a700Sflorian 			dns_name_t **name);
5435185a700Sflorian /*%<
5445185a700Sflorian  * Sets 'name' to point to the name where the per-section internal name
5455185a700Sflorian  * pointer is currently set.
5465185a700Sflorian  *
5475185a700Sflorian  * This function returns the name in the database, so any data associated
5485185a700Sflorian  * with it (via the name's "list" member) contains the actual rdatasets.
5495185a700Sflorian  *
5505185a700Sflorian  * Requires:
5515185a700Sflorian  *
5525185a700Sflorian  *\li	'msg' be valid.
5535185a700Sflorian  *
5545185a700Sflorian  *\li	'name' be non-NULL, and *name be NULL.
5555185a700Sflorian  *
5565185a700Sflorian  *\li	'section' be a valid section.
5575185a700Sflorian  *
5585185a700Sflorian  *\li	dns_message_firstname() must have been called on this section,
5595185a700Sflorian  *	and the result of it and any dns_message_nextname() calls was
5605185a700Sflorian  *	#ISC_R_SUCCESS.
5615185a700Sflorian  */
5625185a700Sflorian 
5635185a700Sflorian isc_result_t
5645185a700Sflorian dns_message_findname(dns_message_t *msg, dns_section_t section,
5655185a700Sflorian 		     dns_name_t *target, dns_rdatatype_t type,
5665185a700Sflorian 		     dns_rdatatype_t covers, dns_name_t **foundname,
5675185a700Sflorian 		     dns_rdataset_t **rdataset);
5685185a700Sflorian /*%<
5695185a700Sflorian  * Search for a name in the specified section.  If it is found, *name is
5705185a700Sflorian  * set to point to the name, and *rdataset is set to point to the found
5715185a700Sflorian  * rdataset (if type is specified as other than dns_rdatatype_any).
5725185a700Sflorian  *
5735185a700Sflorian  * Requires:
5745185a700Sflorian  *\li	'msg' be valid.
5755185a700Sflorian  *
5765185a700Sflorian  *\li	'section' be a valid section.
5775185a700Sflorian  *
5785185a700Sflorian  *\li	If a pointer to the name is desired, 'foundname' should be non-NULL.
5795185a700Sflorian  *	If it is non-NULL, '*foundname' MUST be NULL.
5805185a700Sflorian  *
5815185a700Sflorian  *\li	If a type other than dns_datatype_any is searched for, 'rdataset'
5825185a700Sflorian  *	may be non-NULL, '*rdataset' be NULL, and will point at the found
5835185a700Sflorian  *	rdataset.  If the type is dns_datatype_any, 'rdataset' must be NULL.
5845185a700Sflorian  *
5855185a700Sflorian  *\li	'target' be a valid name.
5865185a700Sflorian  *
5875185a700Sflorian  *\li	'type' be a valid type.
5885185a700Sflorian  *
5895185a700Sflorian  *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
5905185a700Sflorian  *	Otherwise it should be 0.
5915185a700Sflorian  *
5925185a700Sflorian  * Returns:
5935185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all is well.
5945185a700Sflorian  *\li	#DNS_R_NXDOMAIN		-- name does not exist in that section.
5955185a700Sflorian  *\li	#DNS_R_NXRRSET		-- The name does exist, but the desired
5965185a700Sflorian  *				   type does not.
5975185a700Sflorian  */
5985185a700Sflorian 
5995185a700Sflorian isc_result_t
6005185a700Sflorian dns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
6015185a700Sflorian 		     dns_rdatatype_t covers, dns_rdataset_t **rdataset);
6025185a700Sflorian /*%<
6035185a700Sflorian  * Search the name for the specified type.  If it is found, *rdataset is
6045185a700Sflorian  * filled in with a pointer to that rdataset.
6055185a700Sflorian  *
6065185a700Sflorian  * Requires:
6075185a700Sflorian  *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
6085185a700Sflorian  *
6095185a700Sflorian  *\li	'type' be a valid type, and NOT dns_rdatatype_any.
6105185a700Sflorian  *
6115185a700Sflorian  *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
6125185a700Sflorian  *	Otherwise it should be 0.
6135185a700Sflorian  *
6145185a700Sflorian  * Returns:
6155185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all is well.
6165185a700Sflorian  *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
6175185a700Sflorian  */
6185185a700Sflorian 
6195185a700Sflorian isc_result_t
6205185a700Sflorian dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
6215185a700Sflorian 		 dns_rdatatype_t type, dns_rdatatype_t covers,
6225185a700Sflorian 		 dns_rdataset_t **rdataset);
6235185a700Sflorian /*%<
6245185a700Sflorian  * Search the name for the specified rdclass and type.  If it is found,
6255185a700Sflorian  * *rdataset is filled in with a pointer to that rdataset.
6265185a700Sflorian  *
6275185a700Sflorian  * Requires:
6285185a700Sflorian  *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
6295185a700Sflorian  *
6305185a700Sflorian  *\li	'type' be a valid type, and NOT dns_rdatatype_any.
6315185a700Sflorian  *
6325185a700Sflorian  *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
6335185a700Sflorian  *	Otherwise it should be 0.
6345185a700Sflorian  *
6355185a700Sflorian  * Returns:
6365185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all is well.
6375185a700Sflorian  *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
6385185a700Sflorian  */
6395185a700Sflorian 
6405185a700Sflorian void
6415185a700Sflorian dns_message_addname(dns_message_t *msg, dns_name_t *name,
6425185a700Sflorian 		    dns_section_t section);
6435185a700Sflorian /*%<
6445185a700Sflorian  * Adds the name to the given section.
6455185a700Sflorian  *
6465185a700Sflorian  * It is the caller's responsibility to enforce any unique name requirements
6475185a700Sflorian  * in a section.
6485185a700Sflorian  *
6495185a700Sflorian  * Requires:
6505185a700Sflorian  *
6515185a700Sflorian  *\li	'msg' be valid, and be a renderable message.
6525185a700Sflorian  *
6535185a700Sflorian  *\li	'name' be a valid absolute name.
6545185a700Sflorian  *
6555185a700Sflorian  *\li	'section' be a named section.
6565185a700Sflorian  */
6575185a700Sflorian 
6585185a700Sflorian /*
6595185a700Sflorian  * LOANOUT FUNCTIONS
6605185a700Sflorian  *
6615185a700Sflorian  * Each of these functions loan a particular type of data to the caller.
6625185a700Sflorian  * The storage for these will vanish when the message is destroyed or
6635185a700Sflorian  * reset, and must NOT be used after these operations.
6645185a700Sflorian  */
6655185a700Sflorian 
6665185a700Sflorian isc_result_t
6675185a700Sflorian dns_message_gettempname(dns_message_t *msg, dns_name_t **item);
6685185a700Sflorian /*%<
6695185a700Sflorian  * Return a name that can be used for any temporary purpose, including
6705185a700Sflorian  * inserting into the message's linked lists.  The name must be returned
6715185a700Sflorian  * to the message code using dns_message_puttempname() or inserted into
6725185a700Sflorian  * one of the message's sections before the message is destroyed.
6735185a700Sflorian  *
6745185a700Sflorian  * It is the caller's responsibility to initialize this name.
6755185a700Sflorian  *
6765185a700Sflorian  * Requires:
6775185a700Sflorian  *\li	msg be a valid message
6785185a700Sflorian  *
6795185a700Sflorian  *\li	item != NULL && *item == NULL
6805185a700Sflorian  *
6815185a700Sflorian  * Returns:
6825185a700Sflorian  *\li	#ISC_R_SUCCESS		-- All is well.
6835185a700Sflorian  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
6845185a700Sflorian  */
6855185a700Sflorian 
6865185a700Sflorian isc_result_t
6875185a700Sflorian dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
6885185a700Sflorian /*%<
6895185a700Sflorian  * Return a rdata that can be used for any temporary purpose, including
6905185a700Sflorian  * inserting into the message's linked lists.  The rdata will be freed
6915185a700Sflorian  * when the message is destroyed or reset.
6925185a700Sflorian  *
6935185a700Sflorian  * Requires:
6945185a700Sflorian  *\li	msg be a valid message
6955185a700Sflorian  *
6965185a700Sflorian  *\li	item != NULL && *item == NULL
6975185a700Sflorian  *
6985185a700Sflorian  * Returns:
6995185a700Sflorian  *\li	#ISC_R_SUCCESS		-- All is well.
7005185a700Sflorian  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
7015185a700Sflorian  */
7025185a700Sflorian 
7035185a700Sflorian isc_result_t
7045185a700Sflorian dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item);
7055185a700Sflorian /*%<
7065185a700Sflorian  * Return a rdataset that can be used for any temporary purpose, including
7075185a700Sflorian  * inserting into the message's linked lists. The name must be returned
7085185a700Sflorian  * to the message code using dns_message_puttempname() or inserted into
7095185a700Sflorian  * one of the message's sections before the message is destroyed.
7105185a700Sflorian  *
7115185a700Sflorian  * Requires:
7125185a700Sflorian  *\li	msg be a valid message
7135185a700Sflorian  *
7145185a700Sflorian  *\li	item != NULL && *item == NULL
7155185a700Sflorian  *
7165185a700Sflorian  * Returns:
7175185a700Sflorian  *\li	#ISC_R_SUCCESS		-- All is well.
7185185a700Sflorian  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
7195185a700Sflorian  */
7205185a700Sflorian 
7215185a700Sflorian isc_result_t
7225185a700Sflorian dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
7235185a700Sflorian /*%<
7245185a700Sflorian  * Return a rdatalist that can be used for any temporary purpose, including
7255185a700Sflorian  * inserting into the message's linked lists.  The rdatalist will be
7265185a700Sflorian  * destroyed when the message is destroyed or reset.
7275185a700Sflorian  *
7285185a700Sflorian  * Requires:
7295185a700Sflorian  *\li	msg be a valid message
7305185a700Sflorian  *
7315185a700Sflorian  *\li	item != NULL && *item == NULL
7325185a700Sflorian  *
7335185a700Sflorian  * Returns:
7345185a700Sflorian  *\li	#ISC_R_SUCCESS		-- All is well.
7355185a700Sflorian  *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
7365185a700Sflorian  */
7375185a700Sflorian 
7385185a700Sflorian void
7395185a700Sflorian dns_message_puttempname(dns_message_t *msg, dns_name_t **item);
7405185a700Sflorian /*%<
7415185a700Sflorian  * Return a borrowed name to the message's name free list.
7425185a700Sflorian  *
7435185a700Sflorian  * Requires:
7445185a700Sflorian  *\li	msg be a valid message
7455185a700Sflorian  *
7465185a700Sflorian  *\li	item != NULL && *item point to a name returned by
7475185a700Sflorian  *	dns_message_gettempname()
7485185a700Sflorian  *
7495185a700Sflorian  * Ensures:
7505185a700Sflorian  *\li	*item == NULL
7515185a700Sflorian  */
7525185a700Sflorian 
7535185a700Sflorian void
7545185a700Sflorian dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item);
7555185a700Sflorian /*%<
7565185a700Sflorian  * Return a borrowed rdata to the message's rdata free list.
7575185a700Sflorian  *
7585185a700Sflorian  * Requires:
7595185a700Sflorian  *\li	msg be a valid message
7605185a700Sflorian  *
7615185a700Sflorian  *\li	item != NULL && *item point to a rdata returned by
7625185a700Sflorian  *	dns_message_gettemprdata()
7635185a700Sflorian  *
7645185a700Sflorian  * Ensures:
7655185a700Sflorian  *\li	*item == NULL
7665185a700Sflorian  */
7675185a700Sflorian 
7685185a700Sflorian void
7695185a700Sflorian dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item);
7705185a700Sflorian /*%<
7715185a700Sflorian  * Return a borrowed rdataset to the message's rdataset free list.
7725185a700Sflorian  *
7735185a700Sflorian  * Requires:
7745185a700Sflorian  *\li	msg be a valid message
7755185a700Sflorian  *
7765185a700Sflorian  *\li	item != NULL && *item point to a rdataset returned by
7775185a700Sflorian  *	dns_message_gettemprdataset()
7785185a700Sflorian  *
7795185a700Sflorian  * Ensures:
7805185a700Sflorian  *\li	*item == NULL
7815185a700Sflorian  */
7825185a700Sflorian 
7835185a700Sflorian void
7845185a700Sflorian dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
7855185a700Sflorian /*%<
7865185a700Sflorian  * Return a borrowed rdatalist to the message's rdatalist free list.
7875185a700Sflorian  *
7885185a700Sflorian  * Requires:
7895185a700Sflorian  *\li	msg be a valid message
7905185a700Sflorian  *
7915185a700Sflorian  *\li	item != NULL && *item point to a rdatalist returned by
7925185a700Sflorian  *	dns_message_gettemprdatalist()
7935185a700Sflorian  *
7945185a700Sflorian  * Ensures:
7955185a700Sflorian  *\li	*item == NULL
7965185a700Sflorian  */
7975185a700Sflorian 
7985185a700Sflorian isc_result_t
7995185a700Sflorian dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
8005185a700Sflorian 		       unsigned int *flagsp);
8015185a700Sflorian /*%<
8025185a700Sflorian  * Assume the remaining region of "source" is a DNS message.  Peek into
8035185a700Sflorian  * it and fill in "*idp" with the message id, and "*flagsp" with the flags.
8045185a700Sflorian  *
8055185a700Sflorian  * Requires:
8065185a700Sflorian  *
8075185a700Sflorian  *\li	source != NULL
8085185a700Sflorian  *
8095185a700Sflorian  * Ensures:
8105185a700Sflorian  *
8115185a700Sflorian  *\li	if (idp != NULL) *idp == message id.
8125185a700Sflorian  *
8135185a700Sflorian  *\li	if (flagsp != NULL) *flagsp == message flags.
8145185a700Sflorian  *
8155185a700Sflorian  * Returns:
8165185a700Sflorian  *
8175185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all is well.
8185185a700Sflorian  *
8195185a700Sflorian  *\li	#ISC_R_UNEXPECTEDEND	-- buffer doesn't contain enough for a header.
8205185a700Sflorian  */
8215185a700Sflorian 
8225185a700Sflorian dns_rdataset_t *
8235185a700Sflorian dns_message_getopt(dns_message_t *msg);
8245185a700Sflorian /*%<
8255185a700Sflorian  * Get the OPT record for 'msg'.
8265185a700Sflorian  *
8275185a700Sflorian  * Requires:
8285185a700Sflorian  *
8295185a700Sflorian  *\li	'msg' is a valid message.
8305185a700Sflorian  *
8315185a700Sflorian  * Returns:
8325185a700Sflorian  *
8335185a700Sflorian  *\li	The OPT rdataset of 'msg', or NULL if there isn't one.
8345185a700Sflorian  */
8355185a700Sflorian 
8365185a700Sflorian isc_result_t
8375185a700Sflorian dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
8385185a700Sflorian /*%<
8395185a700Sflorian  * Set the OPT record for 'msg'.
8405185a700Sflorian  *
8415185a700Sflorian  * Requires:
8425185a700Sflorian  *
8435185a700Sflorian  *\li	'msg' is a valid message with rendering intent
8445185a700Sflorian  *	and no sections have been rendered.
8455185a700Sflorian  *
8465185a700Sflorian  *\li	'opt' is a valid OPT record.
8475185a700Sflorian  *
8485185a700Sflorian  * Ensures:
8495185a700Sflorian  *
8505185a700Sflorian  *\li	The OPT record has either been freed or ownership of it has
8515185a700Sflorian  *	been transferred to the message.
8525185a700Sflorian  *
8535185a700Sflorian  *\li	If ISC_R_SUCCESS was returned, the OPT record will be rendered
8545185a700Sflorian  *	when dns_message_renderend() is called.
8555185a700Sflorian  *
8565185a700Sflorian  * Returns:
8575185a700Sflorian  *
8585185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all is well.
8595185a700Sflorian  *
8605185a700Sflorian  *\li	#ISC_R_NOSPACE		-- there is no space for the OPT record.
8615185a700Sflorian  */
8625185a700Sflorian 
8635185a700Sflorian dns_rdataset_t *
8645185a700Sflorian dns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
8655185a700Sflorian /*%<
8665185a700Sflorian  * Get the TSIG record and owner for 'msg'.
8675185a700Sflorian  *
8685185a700Sflorian  * Requires:
8695185a700Sflorian  *
8705185a700Sflorian  *\li	'msg' is a valid message.
8715185a700Sflorian  *\li	'owner' is NULL or *owner is NULL.
8725185a700Sflorian  *
8735185a700Sflorian  * Returns:
8745185a700Sflorian  *
8755185a700Sflorian  *\li	The TSIG rdataset of 'msg', or NULL if there isn't one.
8765185a700Sflorian  *
8775185a700Sflorian  * Ensures:
8785185a700Sflorian  *
8795185a700Sflorian  * \li	If 'owner' is not NULL, it will point to the owner name.
8805185a700Sflorian  */
8815185a700Sflorian 
8825185a700Sflorian isc_result_t
8835185a700Sflorian dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
8845185a700Sflorian /*%<
8855185a700Sflorian  * Set the tsig key for 'msg'.  This is only necessary for when rendering a
8865185a700Sflorian  * query or parsing a response.  The key (if non-NULL) is attached to, and
8875185a700Sflorian  * will be detached when the message is destroyed.
8885185a700Sflorian  *
8895185a700Sflorian  * Requires:
8905185a700Sflorian  *
8915185a700Sflorian  *\li	'msg' is a valid message with rendering intent,
8925185a700Sflorian  *	dns_message_renderbegin() has been called, and no sections have been
8935185a700Sflorian  *	rendered.
8945185a700Sflorian  *\li	'key' is a valid tsig key or NULL.
8955185a700Sflorian  *
8965185a700Sflorian  * Returns:
8975185a700Sflorian  *
8985185a700Sflorian  *\li	#ISC_R_SUCCESS		-- all is well.
8995185a700Sflorian  *
9005185a700Sflorian  *\li	#ISC_R_NOSPACE		-- there is no space for the TSIG record.
9015185a700Sflorian  */
9025185a700Sflorian 
9035185a700Sflorian dns_tsigkey_t *
9045185a700Sflorian dns_message_gettsigkey(dns_message_t *msg);
9055185a700Sflorian /*%<
9065185a700Sflorian  * Gets the tsig key for 'msg'.
9075185a700Sflorian  *
9085185a700Sflorian  * Requires:
9095185a700Sflorian  *
9105185a700Sflorian  *\li	'msg' is a valid message
9115185a700Sflorian  */
9125185a700Sflorian 
9135185a700Sflorian isc_result_t
9145185a700Sflorian dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
9155185a700Sflorian /*%<
9165185a700Sflorian  * Indicates that 'querytsig' is the TSIG from the signed query for which
9175185a700Sflorian  * 'msg' is the response.  This is also used for chained TSIGs in TCP
9185185a700Sflorian  * responses.
9195185a700Sflorian  *
9205185a700Sflorian  * Requires:
9215185a700Sflorian  *
9225185a700Sflorian  *\li	'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
9235185a700Sflorian  *	or NULL
9245185a700Sflorian  *
9255185a700Sflorian  *\li	'msg' is a valid message
9265185a700Sflorian  *
9275185a700Sflorian  * Returns:
9285185a700Sflorian  *
9295185a700Sflorian  *\li	#ISC_R_SUCCESS
9305185a700Sflorian  *\li	#ISC_R_NOMEMORY
9315185a700Sflorian  */
9325185a700Sflorian 
9335185a700Sflorian isc_result_t
9345185a700Sflorian dns_message_getquerytsig(dns_message_t *msg, isc_buffer_t **querytsig);
9355185a700Sflorian /*%<
9365185a700Sflorian  * Gets the tsig from the TSIG from the signed query 'msg'.  This is also used
9375185a700Sflorian  * for chained TSIGs in TCP responses.  Unlike dns_message_gettsig, this makes
9385185a700Sflorian  * a copy of the data, so can be used if the message is destroyed.
9395185a700Sflorian  *
9405185a700Sflorian  * Requires:
9415185a700Sflorian  *
9425185a700Sflorian  *\li	'msg' is a valid signed message
9435185a700Sflorian  *\li	'mctx' is a valid memory context
9445185a700Sflorian  *\li	querytsig != NULL && *querytsig == NULL
9455185a700Sflorian  *
9465185a700Sflorian  * Returns:
9475185a700Sflorian  *
9485185a700Sflorian  *\li	#ISC_R_SUCCESS
9495185a700Sflorian  *\li	#ISC_R_NOMEMORY
9505185a700Sflorian  *
9515185a700Sflorian  * Ensures:
9525185a700Sflorian  *\li 	'tsig' points to NULL or an allocated buffer which must be freed
9535185a700Sflorian  * 	by the caller.
9545185a700Sflorian  */
9555185a700Sflorian 
9565185a700Sflorian dns_rdataset_t *
9575185a700Sflorian dns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
9585185a700Sflorian /*%<
9595185a700Sflorian  * Get the SIG(0) record and owner for 'msg'.
9605185a700Sflorian  *
9615185a700Sflorian  * Requires:
9625185a700Sflorian  *
9635185a700Sflorian  *\li	'msg' is a valid message.
9645185a700Sflorian  *\li	'owner' is NULL or *owner is NULL.
9655185a700Sflorian  *
9665185a700Sflorian  * Returns:
9675185a700Sflorian  *
9685185a700Sflorian  *\li	The SIG(0) rdataset of 'msg', or NULL if there isn't one.
9695185a700Sflorian  *
9705185a700Sflorian  * Ensures:
9715185a700Sflorian  *
9725185a700Sflorian  * \li	If 'owner' is not NULL, it will point to the owner name.
9735185a700Sflorian  */
9745185a700Sflorian 
9755185a700Sflorian void
9765185a700Sflorian dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
9775185a700Sflorian /*%<
9785185a700Sflorian  * Give the *buffer to the message code to clean up when it is no
9795185a700Sflorian  * longer needed.  This is usually when the message is reset or
9805185a700Sflorian  * destroyed.
9815185a700Sflorian  *
9825185a700Sflorian  * Requires:
9835185a700Sflorian  *
9845185a700Sflorian  *\li	msg be a valid message.
9855185a700Sflorian  *
9865185a700Sflorian  *\li	buffer != NULL && *buffer is a valid isc_buffer_t, which was
9875185a700Sflorian  *	dynamically allocated via isc_buffer_allocate().
9885185a700Sflorian  */
9895185a700Sflorian 
9905185a700Sflorian isc_result_t
9915185a700Sflorian dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt,
9925185a700Sflorian 		     unsigned int version, uint16_t udpsize,
9935185a700Sflorian 		     unsigned int flags, dns_ednsopt_t *ednsopts, size_t count);
9945185a700Sflorian /*%<
9955185a700Sflorian  * Built a opt record.
9965185a700Sflorian  *
9975185a700Sflorian  * Requires:
9985185a700Sflorian  * \li   msg be a valid message.
9995185a700Sflorian  * \li   opt to be a non NULL and *opt to be NULL.
10005185a700Sflorian  *
10015185a700Sflorian  * Returns:
10025185a700Sflorian  * \li	 ISC_R_SUCCESS on success.
10035185a700Sflorian  * \li	 ISC_R_NOMEMORY
10045185a700Sflorian  * \li	 ISC_R_NOSPACE
10055185a700Sflorian  * \li	 other.
10065185a700Sflorian  */
10075185a700Sflorian 
10085185a700Sflorian #endif /* DNS_MESSAGE_H */
1009