message.h revision 193149
1135446Strhodes/*
2193149Sdougb * Copyright (C) 2004-2009  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 1999-2003  Internet Software Consortium.
4135446Strhodes *
5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any
6135446Strhodes * purpose with or without fee is hereby granted, provided that the above
7135446Strhodes * copyright notice and this permission notice appear in all copies.
8135446Strhodes *
9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11135446Strhodes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15135446Strhodes * PERFORMANCE OF THIS SOFTWARE.
16135446Strhodes */
17135446Strhodes
18193149Sdougb/* $Id: message.h,v 1.125.118.2 2009/01/18 23:47:41 tbox Exp $ */
19135446Strhodes
20135446Strhodes#ifndef DNS_MESSAGE_H
21135446Strhodes#define DNS_MESSAGE_H 1
22135446Strhodes
23135446Strhodes/***
24135446Strhodes ***	Imports
25135446Strhodes ***/
26135446Strhodes
27135446Strhodes#include <isc/lang.h>
28135446Strhodes#include <isc/magic.h>
29135446Strhodes
30135446Strhodes#include <dns/compress.h>
31135446Strhodes#include <dns/masterdump.h>
32135446Strhodes#include <dns/types.h>
33135446Strhodes
34135446Strhodes#include <dst/dst.h>
35135446Strhodes
36193149Sdougb/*! \file dns/message.h
37170222Sdougb * \brief Message Handling Module
38170222Sdougb *
39135446Strhodes * How this beast works:
40135446Strhodes *
41135446Strhodes * When a dns message is received in a buffer, dns_message_fromwire() is called
42135446Strhodes * on the memory region.  Various items are checked including the format
43135446Strhodes * of the message (if counts are right, if counts consume the entire sections,
44135446Strhodes * and if sections consume the entire message) and known pseudo-RRs in the
45135446Strhodes * additional data section are analyzed and removed.
46135446Strhodes *
47135446Strhodes * TSIG checking is also done at this layer, and any DNSSEC transaction
48135446Strhodes * signatures should also be checked here.
49135446Strhodes *
50135446Strhodes * Notes on using the gettemp*() and puttemp*() functions:
51135446Strhodes *
52135446Strhodes * These functions return items (names, rdatasets, etc) allocated from some
53135446Strhodes * internal state of the dns_message_t.
54135446Strhodes *
55135446Strhodes * Names and rdatasets must be put back into the dns_message_t in
56135446Strhodes * one of two ways.  Assume a name was allocated via
57135446Strhodes * dns_message_gettempname():
58135446Strhodes *
59170222Sdougb *\li	(1) insert it into a section, using dns_message_addname().
60135446Strhodes *
61170222Sdougb *\li	(2) return it to the message using dns_message_puttempname().
62135446Strhodes *
63135446Strhodes * The same applies to rdatasets.
64135446Strhodes *
65135446Strhodes * On the other hand, offsets, rdatalists and rdatas allocated using
66135446Strhodes * dns_message_gettemp*() will always be freed automatically
67135446Strhodes * when the message is reset or destroyed; calling dns_message_puttemp*()
68135446Strhodes * on rdatalists and rdatas is optional and serves only to enable the item
69135446Strhodes * to be reused multiple times during the lifetime of the message; offsets
70135446Strhodes * cannot be reused.
71135446Strhodes *
72135446Strhodes * Buffers allocated using isc_buffer_allocate() can be automatically freed
73135446Strhodes * as well by giving the buffer to the message using dns_message_takebuffer().
74135446Strhodes * Doing this will cause the buffer to be freed using isc_buffer_free()
75135446Strhodes * when the section lists are cleared, such as in a reset or in a destroy.
76135446Strhodes * Since the buffer itself exists until the message is destroyed, this sort
77135446Strhodes * of code can be written:
78135446Strhodes *
79170222Sdougb * \code
80135446Strhodes *	buffer = isc_buffer_allocate(mctx, 512);
81135446Strhodes *	name = NULL;
82135446Strhodes *	name = dns_message_gettempname(message, &name);
83135446Strhodes *	dns_name_init(name, NULL);
84135446Strhodes *	result = dns_name_fromtext(name, &source, dns_rootname, ISC_FALSE,
85135446Strhodes *				   buffer);
86135446Strhodes *	dns_message_takebuffer(message, &buffer);
87170222Sdougb * \endcode
88135446Strhodes *
89135446Strhodes *
90135446Strhodes * TODO:
91135446Strhodes *
92135446Strhodes * XXX Needed:  ways to set and retrieve EDNS information, add rdata to a
93135446Strhodes * section, move rdata from one section to another, remove rdata, etc.
94135446Strhodes */
95135446Strhodes
96135446Strhodes#define DNS_MESSAGEFLAG_QR		0x8000U
97135446Strhodes#define DNS_MESSAGEFLAG_AA		0x0400U
98135446Strhodes#define DNS_MESSAGEFLAG_TC		0x0200U
99135446Strhodes#define DNS_MESSAGEFLAG_RD		0x0100U
100135446Strhodes#define DNS_MESSAGEFLAG_RA		0x0080U
101135446Strhodes#define DNS_MESSAGEFLAG_AD		0x0020U
102135446Strhodes#define DNS_MESSAGEFLAG_CD		0x0010U
103135446Strhodes
104193149Sdougb/*%< EDNS0 extended message flags */
105135446Strhodes#define DNS_MESSAGEEXTFLAG_DO		0x8000U
106135446Strhodes
107193149Sdougb/*%< EDNS0 extended OPT codes */
108193149Sdougb#define DNS_OPT_NSID		0x0003		/*%< NSID opt code */
109193149Sdougb
110135446Strhodes#define DNS_MESSAGE_REPLYPRESERVE	(DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD)
111135446Strhodes#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
112135446Strhodes
113170222Sdougb#define DNS_MESSAGE_HEADERLEN		12 /*%< 6 isc_uint16_t's */
114135446Strhodes
115135446Strhodes#define DNS_MESSAGE_MAGIC		ISC_MAGIC('M','S','G','@')
116135446Strhodes#define DNS_MESSAGE_VALID(msg)		ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC)
117135446Strhodes
118135446Strhodes/*
119135446Strhodes * Ordering here matters.  DNS_SECTION_ANY must be the lowest and negative,
120135446Strhodes * and DNS_SECTION_MAX must be one greater than the last used section.
121135446Strhodes */
122135446Strhodestypedef int dns_section_t;
123135446Strhodes#define DNS_SECTION_ANY			(-1)
124135446Strhodes#define DNS_SECTION_QUESTION		0
125135446Strhodes#define DNS_SECTION_ANSWER		1
126135446Strhodes#define DNS_SECTION_AUTHORITY		2
127135446Strhodes#define DNS_SECTION_ADDITIONAL		3
128135446Strhodes#define DNS_SECTION_MAX			4
129135446Strhodes
130135446Strhodestypedef int dns_pseudosection_t;
131135446Strhodes#define DNS_PSEUDOSECTION_ANY		(-1)
132135446Strhodes#define DNS_PSEUDOSECTION_OPT           0
133135446Strhodes#define DNS_PSEUDOSECTION_TSIG          1
134135446Strhodes#define DNS_PSEUDOSECTION_SIG0          2
135135446Strhodes#define DNS_PSEUDOSECTION_MAX           3
136135446Strhodes
137135446Strhodestypedef int dns_messagetextflag_t;
138135446Strhodes#define DNS_MESSAGETEXTFLAG_NOCOMMENTS	0x0001
139135446Strhodes#define DNS_MESSAGETEXTFLAG_NOHEADERS	0x0002
140135446Strhodes
141135446Strhodes/*
142135446Strhodes * Dynamic update names for these sections.
143135446Strhodes */
144135446Strhodes#define DNS_SECTION_ZONE		DNS_SECTION_QUESTION
145135446Strhodes#define DNS_SECTION_PREREQUISITE	DNS_SECTION_ANSWER
146135446Strhodes#define DNS_SECTION_UPDATE		DNS_SECTION_AUTHORITY
147135446Strhodes
148135446Strhodes/*
149135446Strhodes * These tell the message library how the created dns_message_t will be used.
150135446Strhodes */
151170222Sdougb#define DNS_MESSAGE_INTENTUNKNOWN	0 /*%< internal use only */
152170222Sdougb#define DNS_MESSAGE_INTENTPARSE		1 /*%< parsing messages */
153170222Sdougb#define DNS_MESSAGE_INTENTRENDER	2 /*%< rendering */
154135446Strhodes
155135446Strhodes/*
156135446Strhodes * Control behavior of parsing
157135446Strhodes */
158170222Sdougb#define DNS_MESSAGEPARSE_PRESERVEORDER	0x0001	/*%< preserve rdata order */
159170222Sdougb#define DNS_MESSAGEPARSE_BESTEFFORT	0x0002	/*%< return a message if a
160135446Strhodes						   recoverable parse error
161135446Strhodes						   occurs */
162170222Sdougb#define DNS_MESSAGEPARSE_CLONEBUFFER	0x0004	/*%< save a copy of the
163135446Strhodes						   source buffer */
164193149Sdougb#define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< truncation errors are
165135446Strhodes						  * not fatal. */
166135446Strhodes
167135446Strhodes/*
168135446Strhodes * Control behavior of rendering
169135446Strhodes */
170170222Sdougb#define DNS_MESSAGERENDER_ORDERED	0x0001	/*%< don't change order */
171170222Sdougb#define DNS_MESSAGERENDER_PARTIAL	0x0002	/*%< allow a partial rdataset */
172170222Sdougb#define DNS_MESSAGERENDER_OMITDNSSEC	0x0004	/*%< omit DNSSEC records */
173170222Sdougb#define DNS_MESSAGERENDER_PREFER_A	0x0008	/*%< prefer A records in
174170222Sdougb						      additional section. */
175170222Sdougb#define DNS_MESSAGERENDER_PREFER_AAAA	0x0010	/*%< prefer AAAA records in
176170222Sdougb						  additional section. */
177135446Strhodes
178135446Strhodestypedef struct dns_msgblock dns_msgblock_t;
179135446Strhodes
180135446Strhodesstruct dns_message {
181135446Strhodes	/* public from here down */
182135446Strhodes	unsigned int			magic;
183135446Strhodes
184135446Strhodes	dns_messageid_t			id;
185135446Strhodes	unsigned int			flags;
186135446Strhodes	dns_rcode_t			rcode;
187135446Strhodes	unsigned int			opcode;
188135446Strhodes	dns_rdataclass_t		rdclass;
189135446Strhodes
190135446Strhodes	/* 4 real, 1 pseudo */
191135446Strhodes	unsigned int			counts[DNS_SECTION_MAX];
192135446Strhodes
193135446Strhodes	/* private from here down */
194135446Strhodes	dns_namelist_t			sections[DNS_SECTION_MAX];
195135446Strhodes	dns_name_t		       *cursors[DNS_SECTION_MAX];
196135446Strhodes	dns_rdataset_t		       *opt;
197135446Strhodes	dns_rdataset_t		       *sig0;
198135446Strhodes	dns_rdataset_t		       *tsig;
199135446Strhodes
200135446Strhodes	int				state;
201135446Strhodes	unsigned int			from_to_wire : 2;
202135446Strhodes	unsigned int			header_ok : 1;
203135446Strhodes	unsigned int			question_ok : 1;
204135446Strhodes	unsigned int			tcp_continuation : 1;
205135446Strhodes	unsigned int			verified_sig : 1;
206135446Strhodes	unsigned int			verify_attempted : 1;
207135446Strhodes	unsigned int			free_query : 1;
208135446Strhodes	unsigned int			free_saved : 1;
209135446Strhodes
210135446Strhodes	unsigned int			opt_reserved;
211135446Strhodes	unsigned int			sig_reserved;
212135446Strhodes	unsigned int			reserved; /* reserved space (render) */
213135446Strhodes
214135446Strhodes	isc_buffer_t		       *buffer;
215135446Strhodes	dns_compress_t		       *cctx;
216135446Strhodes
217135446Strhodes	isc_mem_t		       *mctx;
218135446Strhodes	isc_mempool_t		       *namepool;
219135446Strhodes	isc_mempool_t		       *rdspool;
220135446Strhodes
221135446Strhodes	isc_bufferlist_t		scratchpad;
222135446Strhodes	isc_bufferlist_t		cleanup;
223135446Strhodes
224135446Strhodes	ISC_LIST(dns_msgblock_t)	rdatas;
225135446Strhodes	ISC_LIST(dns_msgblock_t)	rdatalists;
226135446Strhodes	ISC_LIST(dns_msgblock_t)	offsets;
227135446Strhodes
228135446Strhodes	ISC_LIST(dns_rdata_t)		freerdata;
229135446Strhodes	ISC_LIST(dns_rdatalist_t)	freerdatalist;
230135446Strhodes
231135446Strhodes	dns_rcode_t			tsigstatus;
232135446Strhodes	dns_rcode_t			querytsigstatus;
233135446Strhodes	dns_name_t		       *tsigname; /* Owner name of TSIG, if any */
234135446Strhodes	dns_rdataset_t		       *querytsig;
235135446Strhodes	dns_tsigkey_t		       *tsigkey;
236135446Strhodes	dst_context_t		       *tsigctx;
237135446Strhodes	int				sigstart;
238135446Strhodes	int				timeadjust;
239135446Strhodes
240135446Strhodes	dns_name_t		       *sig0name; /* Owner name of SIG0, if any */
241135446Strhodes	dst_key_t		       *sig0key;
242135446Strhodes	dns_rcode_t			sig0status;
243135446Strhodes	isc_region_t			query;
244135446Strhodes	isc_region_t			saved;
245135446Strhodes
246135446Strhodes	dns_rdatasetorderfunc_t		order;
247165071Sdougb	const void *			order_arg;
248135446Strhodes};
249135446Strhodes
250135446Strhodes/***
251135446Strhodes *** Functions
252135446Strhodes ***/
253135446Strhodes
254135446StrhodesISC_LANG_BEGINDECLS
255135446Strhodes
256135446Strhodesisc_result_t
257135446Strhodesdns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp);
258135446Strhodes
259170222Sdougb/*%<
260135446Strhodes * Create msg structure.
261135446Strhodes *
262135446Strhodes * This function will allocate some internal blocks of memory that are
263135446Strhodes * expected to be needed for parsing or rendering nearly any type of message.
264135446Strhodes *
265135446Strhodes * Requires:
266170222Sdougb *\li	'mctx' be a valid memory context.
267135446Strhodes *
268170222Sdougb *\li	'msgp' be non-null and '*msg' be NULL.
269135446Strhodes *
270170222Sdougb *\li	'intent' must be one of DNS_MESSAGE_INTENTPARSE or
271170222Sdougb *	#DNS_MESSAGE_INTENTRENDER.
272135446Strhodes *
273135446Strhodes * Ensures:
274170222Sdougb *\li	The data in "*msg" is set to indicate an unused and empty msg
275135446Strhodes *	structure.
276135446Strhodes *
277135446Strhodes * Returns:
278170222Sdougb *\li	#ISC_R_NOMEMORY		-- out of memory
279170222Sdougb *\li	#ISC_R_SUCCESS		-- success
280135446Strhodes */
281135446Strhodes
282135446Strhodesvoid
283135446Strhodesdns_message_reset(dns_message_t *msg, unsigned int intent);
284170222Sdougb/*%<
285135446Strhodes * Reset a message structure to default state.  All internal lists are freed
286135446Strhodes * or reset to a default state as well.  This is simply a more efficient
287135446Strhodes * way to call dns_message_destroy() followed by dns_message_allocate(),
288135446Strhodes * since it avoid many memory allocations.
289135446Strhodes *
290135446Strhodes * If any data loanouts (buffers, names, rdatas, etc) were requested,
291135446Strhodes * the caller must no longer use them after this call.
292135446Strhodes *
293135446Strhodes * The intended next use of the message will be 'intent'.
294135446Strhodes *
295135446Strhodes * Requires:
296135446Strhodes *
297170222Sdougb *\li	'msg' be valid.
298135446Strhodes *
299170222Sdougb *\li	'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER
300135446Strhodes */
301135446Strhodes
302135446Strhodesvoid
303135446Strhodesdns_message_destroy(dns_message_t **msgp);
304170222Sdougb/*%<
305135446Strhodes * Destroy all state in the message.
306135446Strhodes *
307135446Strhodes * Requires:
308135446Strhodes *
309170222Sdougb *\li	'msgp' be valid.
310135446Strhodes *
311135446Strhodes * Ensures:
312170222Sdougb *\li	'*msgp' == NULL
313135446Strhodes */
314135446Strhodes
315135446Strhodesisc_result_t
316135446Strhodesdns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
317135446Strhodes			  const dns_master_style_t *style,
318135446Strhodes			  dns_messagetextflag_t flags,
319135446Strhodes			  isc_buffer_t *target);
320135446Strhodes
321135446Strhodesisc_result_t
322135446Strhodesdns_message_pseudosectiontotext(dns_message_t *msg,
323135446Strhodes				dns_pseudosection_t section,
324135446Strhodes				const dns_master_style_t *style,
325135446Strhodes				dns_messagetextflag_t flags,
326135446Strhodes				isc_buffer_t *target);
327170222Sdougb/*%<
328135446Strhodes * Convert section 'section' or 'pseudosection' of message 'msg' to
329135446Strhodes * a cleartext representation
330135446Strhodes *
331135446Strhodes * Notes:
332170222Sdougb *     \li See dns_message_totext for meanings of flags.
333135446Strhodes *
334135446Strhodes * Requires:
335135446Strhodes *
336170222Sdougb *\li	'msg' is a valid message.
337135446Strhodes *
338170222Sdougb *\li	'style' is a valid master dump style.
339135446Strhodes *
340170222Sdougb *\li	'target' is a valid buffer.
341135446Strhodes *
342170222Sdougb *\li	'section' is a valid section label.
343135446Strhodes *
344135446Strhodes * Ensures:
345135446Strhodes *
346170222Sdougb *\li	If the result is success:
347135446Strhodes *		The used space in 'target' is updated.
348135446Strhodes *
349135446Strhodes * Returns:
350135446Strhodes *
351170222Sdougb *\li	#ISC_R_SUCCESS
352170222Sdougb *\li	#ISC_R_NOSPACE
353170222Sdougb *\li	#ISC_R_NOMORE
354135446Strhodes *
355170222Sdougb *\li	Note: On error return, *target may be partially filled with data.
356135446Strhodes*/
357135446Strhodes
358135446Strhodesisc_result_t
359135446Strhodesdns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
360135446Strhodes		   dns_messagetextflag_t flags, isc_buffer_t *target);
361170222Sdougb/*%<
362135446Strhodes * Convert all sections of message 'msg' to a cleartext representation
363135446Strhodes *
364135446Strhodes * Notes:
365170222Sdougb * \li     In flags, If #DNS_MESSAGETEXTFLAG_OMITDOT is set, then the
366135446Strhodes *      final '.' in absolute names will not be emitted.  If
367170222Sdougb *      #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning
368135446Strhodes *      with ";;" will be emitted indicating section name.  If
369170222Sdougb *      #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will
370135446Strhodes *      be emitted.
371135446Strhodes *
372135446Strhodes * Requires:
373135446Strhodes *
374170222Sdougb *\li	'msg' is a valid message.
375135446Strhodes *
376170222Sdougb *\li	'style' is a valid master dump style.
377135446Strhodes *
378170222Sdougb *\li	'target' is a valid buffer.
379135446Strhodes *
380135446Strhodes * Ensures:
381135446Strhodes *
382170222Sdougb *\li	If the result is success:
383135446Strhodes *		The used space in 'target' is updated.
384135446Strhodes *
385135446Strhodes * Returns:
386135446Strhodes *
387170222Sdougb *\li	#ISC_R_SUCCESS
388170222Sdougb *\li	#ISC_R_NOSPACE
389170222Sdougb *\li	#ISC_R_NOMORE
390135446Strhodes *
391170222Sdougb *\li	Note: On error return, *target may be partially filled with data.
392135446Strhodes */
393135446Strhodes
394135446Strhodesisc_result_t
395135446Strhodesdns_message_parse(dns_message_t *msg, isc_buffer_t *source,
396135446Strhodes		  unsigned int options);
397170222Sdougb/*%<
398135446Strhodes * Parse raw wire data in 'source' as a DNS message.
399135446Strhodes *
400135446Strhodes * OPT records are detected and stored in the pseudo-section "opt".
401135446Strhodes * TSIGs are detected and stored in the pseudo-section "tsig".
402135446Strhodes *
403170222Sdougb * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message
404135446Strhodes * is UPDATE, a separate dns_name_t object will be created for each RR in the
405135446Strhodes * message.  Each such dns_name_t will have a single rdataset containing the
406135446Strhodes * single RR, and the order of the RRs in the message is preserved.
407135446Strhodes * Otherwise, only one dns_name_t object will be created for each unique
408135446Strhodes * owner name in the section, and each such dns_name_t will have a list
409135446Strhodes * of rdatasets.  To access the names and their data, use
410135446Strhodes * dns_message_firstname() and dns_message_nextname().
411135446Strhodes *
412170222Sdougb * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
413135446Strhodes * not be considered FORMERRs.  If the entire message can be parsed, it
414135446Strhodes * will be returned and DNS_R_RECOVERABLE will be returned.
415135446Strhodes *
416170222Sdougb * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
417135446Strhodes * RR's as possible, DNS_R_RECOVERABLE will be returned.
418135446Strhodes *
419135446Strhodes * OPT and TSIG records are always handled specially, regardless of the
420135446Strhodes * 'preserve_order' setting.
421135446Strhodes *
422135446Strhodes * Requires:
423170222Sdougb *\li	"msg" be valid.
424135446Strhodes *
425170222Sdougb *\li	"buffer" be a wire format buffer.
426135446Strhodes *
427135446Strhodes * Ensures:
428170222Sdougb *\li	The buffer's data format is correct.
429135446Strhodes *
430170222Sdougb *\li	The buffer's contents verify as correct regarding header bits, buffer
431135446Strhodes * 	and rdata sizes, etc.
432135446Strhodes *
433135446Strhodes * Returns:
434170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well
435170222Sdougb *\li	#ISC_R_NOMEMORY		-- no memory
436170222Sdougb *\li	#DNS_R_RECOVERABLE	-- the message parsed properly, but contained
437135446Strhodes *				   errors.
438170222Sdougb *\li	Many other errors possible XXXMLG
439135446Strhodes */
440135446Strhodes
441135446Strhodesisc_result_t
442135446Strhodesdns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
443135446Strhodes			isc_buffer_t *buffer);
444170222Sdougb/*%<
445135446Strhodes * Begin rendering on a message.  Only one call can be made to this function
446135446Strhodes * per message.
447135446Strhodes *
448135446Strhodes * The compression context is "owned" by the message library until
449135446Strhodes * dns_message_renderend() is called.  It must be invalidated by the caller.
450135446Strhodes *
451135446Strhodes * The buffer is "owned" by the message library until dns_message_renderend()
452135446Strhodes * is called.
453135446Strhodes *
454135446Strhodes * Requires:
455135446Strhodes *
456170222Sdougb *\li	'msg' be valid.
457135446Strhodes *
458170222Sdougb *\li	'cctx' be valid.
459135446Strhodes *
460170222Sdougb *\li	'buffer' is a valid buffer.
461135446Strhodes *
462135446Strhodes * Side Effects:
463135446Strhodes *
464170222Sdougb *\li	The buffer is cleared before it is used.
465135446Strhodes *
466135446Strhodes * Returns:
467170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well
468170222Sdougb *\li	#ISC_R_NOSPACE		-- output buffer is too small
469135446Strhodes */
470135446Strhodes
471135446Strhodesisc_result_t
472135446Strhodesdns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
473170222Sdougb/*%<
474135446Strhodes * Reset the buffer.  This can be used after growing the old buffer
475135446Strhodes * on a ISC_R_NOSPACE return from most of the render functions.
476135446Strhodes *
477135446Strhodes * On successful completion, the old buffer is no longer used by the
478135446Strhodes * library.  The new buffer is owned by the library until
479135446Strhodes * dns_message_renderend() is called.
480135446Strhodes *
481135446Strhodes * Requires:
482135446Strhodes *
483170222Sdougb *\li	'msg' be valid.
484135446Strhodes *
485170222Sdougb *\li	dns_message_renderbegin() was called.
486135446Strhodes *
487170222Sdougb *\li	buffer != NULL.
488135446Strhodes *
489135446Strhodes * Returns:
490170222Sdougb *\li	#ISC_R_NOSPACE		-- new buffer is too small
491170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
492135446Strhodes */
493135446Strhodes
494135446Strhodesisc_result_t
495135446Strhodesdns_message_renderreserve(dns_message_t *msg, unsigned int space);
496170222Sdougb/*%<
497135446Strhodes * XXXMLG should use size_t rather than unsigned int once the buffer
498135446Strhodes * API is cleaned up
499135446Strhodes *
500135446Strhodes * Reserve "space" bytes in the given buffer.
501135446Strhodes *
502135446Strhodes * Requires:
503135446Strhodes *
504170222Sdougb *\li	'msg' be valid.
505135446Strhodes *
506170222Sdougb *\li	dns_message_renderbegin() was called.
507135446Strhodes *
508135446Strhodes * Returns:
509170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
510170222Sdougb *\li	#ISC_R_NOSPACE		-- not enough free space in the buffer.
511135446Strhodes */
512135446Strhodes
513135446Strhodesvoid
514135446Strhodesdns_message_renderrelease(dns_message_t *msg, unsigned int space);
515170222Sdougb/*%<
516135446Strhodes * XXXMLG should use size_t rather than unsigned int once the buffer
517135446Strhodes * API is cleaned up
518135446Strhodes *
519135446Strhodes * Release "space" bytes in the given buffer that was previously reserved.
520135446Strhodes *
521135446Strhodes * Requires:
522135446Strhodes *
523170222Sdougb *\li	'msg' be valid.
524135446Strhodes *
525170222Sdougb *\li	'space' is less than or equal to the total amount of space reserved
526135446Strhodes *	via prior calls to dns_message_renderreserve().
527135446Strhodes *
528170222Sdougb *\li	dns_message_renderbegin() was called.
529135446Strhodes */
530135446Strhodes
531135446Strhodesisc_result_t
532135446Strhodesdns_message_rendersection(dns_message_t *msg, dns_section_t section,
533135446Strhodes			  unsigned int options);
534170222Sdougb/*%<
535135446Strhodes * Render all names, rdatalists, etc from the given section at the
536135446Strhodes * specified priority or higher.
537135446Strhodes *
538135446Strhodes * Requires:
539170222Sdougb *\li	'msg' be valid.
540135446Strhodes *
541170222Sdougb *\li	'section' be a valid section.
542135446Strhodes *
543170222Sdougb *\li	dns_message_renderbegin() was called.
544135446Strhodes *
545135446Strhodes * Returns:
546170222Sdougb *\li	#ISC_R_SUCCESS		-- all records were written, and there are
547135446Strhodes *				   no more records for this section.
548170222Sdougb *\li	#ISC_R_NOSPACE		-- Not enough room in the buffer to write
549135446Strhodes *				   all records requested.
550170222Sdougb *\li	#DNS_R_MOREDATA		-- All requested records written, and there
551135446Strhodes *				   are records remaining for this section.
552135446Strhodes */
553135446Strhodes
554135446Strhodesvoid
555135446Strhodesdns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
556170222Sdougb/*%<
557135446Strhodes * Render the message header.  This is implicitly called by
558135446Strhodes * dns_message_renderend().
559135446Strhodes *
560135446Strhodes * Requires:
561135446Strhodes *
562170222Sdougb *\li	'msg' be a valid message.
563135446Strhodes *
564170222Sdougb *\li	dns_message_renderbegin() was called.
565135446Strhodes *
566170222Sdougb *\li	'target' is a valid buffer with enough space to hold a message header
567135446Strhodes */
568135446Strhodes
569135446Strhodesisc_result_t
570135446Strhodesdns_message_renderend(dns_message_t *msg);
571170222Sdougb/*%<
572135446Strhodes * Finish rendering to the buffer.  Note that more data can be in the
573135446Strhodes * 'msg' structure.  Destroying the structure will free this, or in a multi-
574135446Strhodes * part EDNS1 message this data can be rendered to another buffer later.
575135446Strhodes *
576135446Strhodes * Requires:
577135446Strhodes *
578170222Sdougb *\li	'msg' be a valid message.
579135446Strhodes *
580170222Sdougb *\li	dns_message_renderbegin() was called.
581135446Strhodes *
582135446Strhodes * Returns:
583170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
584135446Strhodes */
585135446Strhodes
586135446Strhodesvoid
587135446Strhodesdns_message_renderreset(dns_message_t *msg);
588170222Sdougb/*%<
589135446Strhodes * Reset the message so that it may be rendered again.
590135446Strhodes *
591135446Strhodes * Notes:
592135446Strhodes *
593170222Sdougb *\li	If dns_message_renderbegin() has been called, dns_message_renderend()
594135446Strhodes *	must be called before calling this function.
595135446Strhodes *
596135446Strhodes * Requires:
597135446Strhodes *
598170222Sdougb *\li	'msg' be a valid message with rendering intent.
599135446Strhodes */
600135446Strhodes
601135446Strhodesisc_result_t
602135446Strhodesdns_message_firstname(dns_message_t *msg, dns_section_t section);
603170222Sdougb/*%<
604135446Strhodes * Set internal per-section name pointer to the beginning of the section.
605135446Strhodes *
606135446Strhodes * The functions dns_message_firstname() and dns_message_nextname() may
607135446Strhodes * be used for iterating over the owner names in a section.
608135446Strhodes *
609135446Strhodes * Requires:
610135446Strhodes *
611170222Sdougb *\li   	'msg' be valid.
612135446Strhodes *
613170222Sdougb *\li	'section' be a valid section.
614135446Strhodes *
615135446Strhodes * Returns:
616170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
617170222Sdougb *\li	#ISC_R_NOMORE		-- No names on given section.
618135446Strhodes */
619135446Strhodes
620135446Strhodesisc_result_t
621135446Strhodesdns_message_nextname(dns_message_t *msg, dns_section_t section);
622170222Sdougb/*%<
623135446Strhodes * Sets the internal per-section name pointer to point to the next name
624135446Strhodes * in that section.
625135446Strhodes *
626135446Strhodes * Requires:
627135446Strhodes *
628170222Sdougb * \li  	'msg' be valid.
629135446Strhodes *
630170222Sdougb *\li	'section' be a valid section.
631135446Strhodes *
632170222Sdougb *\li	dns_message_firstname() must have been called on this section,
633135446Strhodes *	and the result was ISC_R_SUCCESS.
634135446Strhodes *
635135446Strhodes * Returns:
636170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
637170222Sdougb *\li	#ISC_R_NOMORE		-- No more names in given section.
638135446Strhodes */
639135446Strhodes
640135446Strhodesvoid
641135446Strhodesdns_message_currentname(dns_message_t *msg, dns_section_t section,
642135446Strhodes			dns_name_t **name);
643170222Sdougb/*%<
644135446Strhodes * Sets 'name' to point to the name where the per-section internal name
645135446Strhodes * pointer is currently set.
646135446Strhodes *
647135446Strhodes * This function returns the name in the database, so any data associated
648135446Strhodes * with it (via the name's "list" member) contains the actual rdatasets.
649135446Strhodes *
650135446Strhodes * Requires:
651135446Strhodes *
652170222Sdougb *\li	'msg' be valid.
653135446Strhodes *
654170222Sdougb *\li	'name' be non-NULL, and *name be NULL.
655135446Strhodes *
656170222Sdougb *\li	'section' be a valid section.
657135446Strhodes *
658170222Sdougb *\li	dns_message_firstname() must have been called on this section,
659135446Strhodes *	and the result of it and any dns_message_nextname() calls was
660170222Sdougb *	#ISC_R_SUCCESS.
661135446Strhodes */
662135446Strhodes
663135446Strhodesisc_result_t
664135446Strhodesdns_message_findname(dns_message_t *msg, dns_section_t section,
665135446Strhodes		     dns_name_t *target, dns_rdatatype_t type,
666135446Strhodes		     dns_rdatatype_t covers, dns_name_t **foundname,
667135446Strhodes		     dns_rdataset_t **rdataset);
668170222Sdougb/*%<
669135446Strhodes * Search for a name in the specified section.  If it is found, *name is
670135446Strhodes * set to point to the name, and *rdataset is set to point to the found
671135446Strhodes * rdataset (if type is specified as other than dns_rdatatype_any).
672135446Strhodes *
673135446Strhodes * Requires:
674170222Sdougb *\li	'msg' be valid.
675135446Strhodes *
676170222Sdougb *\li	'section' be a valid section.
677135446Strhodes *
678170222Sdougb *\li	If a pointer to the name is desired, 'foundname' should be non-NULL.
679135446Strhodes *	If it is non-NULL, '*foundname' MUST be NULL.
680135446Strhodes *
681170222Sdougb *\li	If a type other than dns_datatype_any is searched for, 'rdataset'
682135446Strhodes *	may be non-NULL, '*rdataset' be NULL, and will point at the found
683135446Strhodes *	rdataset.  If the type is dns_datatype_any, 'rdataset' must be NULL.
684135446Strhodes *
685170222Sdougb *\li	'target' be a valid name.
686135446Strhodes *
687170222Sdougb *\li	'type' be a valid type.
688135446Strhodes *
689170222Sdougb *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
690135446Strhodes *	Otherwise it should be 0.
691135446Strhodes *
692135446Strhodes * Returns:
693170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
694170222Sdougb *\li	#DNS_R_NXDOMAIN		-- name does not exist in that section.
695170222Sdougb *\li	#DNS_R_NXRRSET		-- The name does exist, but the desired
696135446Strhodes *				   type does not.
697135446Strhodes */
698135446Strhodes
699135446Strhodesisc_result_t
700135446Strhodesdns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
701135446Strhodes		     dns_rdatatype_t covers, dns_rdataset_t **rdataset);
702170222Sdougb/*%<
703135446Strhodes * Search the name for the specified type.  If it is found, *rdataset is
704135446Strhodes * filled in with a pointer to that rdataset.
705135446Strhodes *
706135446Strhodes * Requires:
707170222Sdougb *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
708135446Strhodes *
709170222Sdougb *\li	'type' be a valid type, and NOT dns_rdatatype_any.
710135446Strhodes *
711170222Sdougb *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
712135446Strhodes *	Otherwise it should be 0.
713135446Strhodes *
714135446Strhodes * Returns:
715170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
716170222Sdougb *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
717135446Strhodes */
718135446Strhodes
719165071Sdougbisc_result_t
720165071Sdougbdns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
721165071Sdougb		 dns_rdatatype_t type, dns_rdatatype_t covers,
722165071Sdougb		 dns_rdataset_t **rdataset);
723165071Sdougb/*%<
724165071Sdougb * Search the name for the specified rdclass and type.  If it is found,
725165071Sdougb * *rdataset is filled in with a pointer to that rdataset.
726165071Sdougb *
727165071Sdougb * Requires:
728165071Sdougb *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
729165071Sdougb *
730165071Sdougb *\li	'type' be a valid type, and NOT dns_rdatatype_any.
731165071Sdougb *
732165071Sdougb *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
733165071Sdougb *	Otherwise it should be 0.
734165071Sdougb *
735165071Sdougb * Returns:
736165071Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
737165071Sdougb *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
738165071Sdougb */
739165071Sdougb
740135446Strhodesvoid
741135446Strhodesdns_message_movename(dns_message_t *msg, dns_name_t *name,
742135446Strhodes		     dns_section_t fromsection,
743135446Strhodes		     dns_section_t tosection);
744170222Sdougb/*%<
745135446Strhodes * Move a name from one section to another.
746135446Strhodes *
747135446Strhodes * Requires:
748135446Strhodes *
749170222Sdougb *\li	'msg' be valid.
750135446Strhodes *
751170222Sdougb *\li	'name' must be a name already in 'fromsection'.
752135446Strhodes *
753170222Sdougb *\li	'fromsection' must be a valid section.
754135446Strhodes *
755170222Sdougb *\li	'tosection' must be a valid section.
756135446Strhodes */
757135446Strhodes
758135446Strhodesvoid
759135446Strhodesdns_message_addname(dns_message_t *msg, dns_name_t *name,
760135446Strhodes		    dns_section_t section);
761170222Sdougb/*%<
762135446Strhodes * Adds the name to the given section.
763135446Strhodes *
764135446Strhodes * It is the caller's responsibility to enforce any unique name requirements
765135446Strhodes * in a section.
766135446Strhodes *
767135446Strhodes * Requires:
768135446Strhodes *
769170222Sdougb *\li	'msg' be valid, and be a renderable message.
770135446Strhodes *
771170222Sdougb *\li	'name' be a valid absolute name.
772135446Strhodes *
773170222Sdougb *\li	'section' be a named section.
774135446Strhodes */
775135446Strhodes
776170222Sdougbvoid
777170222Sdougbdns_message_removename(dns_message_t *msg, dns_name_t *name,
778193149Sdougb		       dns_section_t section);
779170222Sdougb/*%<
780170222Sdougb * Remove a existing name from a given section.
781170222Sdougb *
782170222Sdougb * It is the caller's responsibility to ensure the name is part of the
783170222Sdougb * given section.
784170222Sdougb *
785170222Sdougb * Requires:
786170222Sdougb *
787170222Sdougb *\li	'msg' be valid, and be a renderable message.
788170222Sdougb *
789170222Sdougb *\li	'name' be a valid absolute name.
790170222Sdougb *
791170222Sdougb *\li	'section' be a named section.
792170222Sdougb */
793170222Sdougb
794170222Sdougb
795135446Strhodes/*
796135446Strhodes * LOANOUT FUNCTIONS
797135446Strhodes *
798135446Strhodes * Each of these functions loan a particular type of data to the caller.
799135446Strhodes * The storage for these will vanish when the message is destroyed or
800135446Strhodes * reset, and must NOT be used after these operations.
801135446Strhodes */
802135446Strhodes
803135446Strhodesisc_result_t
804135446Strhodesdns_message_gettempname(dns_message_t *msg, dns_name_t **item);
805170222Sdougb/*%<
806135446Strhodes * Return a name that can be used for any temporary purpose, including
807135446Strhodes * inserting into the message's linked lists.  The name must be returned
808135446Strhodes * to the message code using dns_message_puttempname() or inserted into
809135446Strhodes * one of the message's sections before the message is destroyed.
810135446Strhodes *
811135446Strhodes * It is the caller's responsibility to initialize this name.
812135446Strhodes *
813135446Strhodes * Requires:
814170222Sdougb *\li	msg be a valid message
815135446Strhodes *
816170222Sdougb *\li	item != NULL && *item == NULL
817135446Strhodes *
818135446Strhodes * Returns:
819170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
820170222Sdougb *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
821135446Strhodes */
822135446Strhodes
823135446Strhodesisc_result_t
824135446Strhodesdns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item);
825170222Sdougb/*%<
826135446Strhodes * Return an offsets array that can be used for any temporary purpose,
827135446Strhodes * such as attaching to a temporary name.  The offsets will be freed
828135446Strhodes * when the message is destroyed or reset.
829135446Strhodes *
830135446Strhodes * Requires:
831170222Sdougb *\li	msg be a valid message
832135446Strhodes *
833170222Sdougb *\li	item != NULL && *item == NULL
834135446Strhodes *
835135446Strhodes * Returns:
836170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
837170222Sdougb *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
838135446Strhodes */
839135446Strhodes
840135446Strhodesisc_result_t
841135446Strhodesdns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
842170222Sdougb/*%<
843135446Strhodes * Return a rdata that can be used for any temporary purpose, including
844135446Strhodes * inserting into the message's linked lists.  The rdata will be freed
845135446Strhodes * when the message is destroyed or reset.
846135446Strhodes *
847135446Strhodes * Requires:
848170222Sdougb *\li	msg be a valid message
849135446Strhodes *
850170222Sdougb *\li	item != NULL && *item == NULL
851135446Strhodes *
852135446Strhodes * Returns:
853170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
854170222Sdougb *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
855135446Strhodes */
856135446Strhodes
857135446Strhodesisc_result_t
858135446Strhodesdns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item);
859170222Sdougb/*%<
860135446Strhodes * Return a rdataset that can be used for any temporary purpose, including
861135446Strhodes * inserting into the message's linked lists. The name must be returned
862135446Strhodes * to the message code using dns_message_puttempname() or inserted into
863135446Strhodes * one of the message's sections before the message is destroyed.
864135446Strhodes *
865135446Strhodes * Requires:
866170222Sdougb *\li	msg be a valid message
867135446Strhodes *
868170222Sdougb *\li	item != NULL && *item == NULL
869135446Strhodes *
870135446Strhodes * Returns:
871170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
872170222Sdougb *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
873135446Strhodes */
874135446Strhodes
875135446Strhodesisc_result_t
876135446Strhodesdns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
877170222Sdougb/*%<
878135446Strhodes * Return a rdatalist that can be used for any temporary purpose, including
879135446Strhodes * inserting into the message's linked lists.  The rdatalist will be
880135446Strhodes * destroyed when the message is destroyed or reset.
881135446Strhodes *
882135446Strhodes * Requires:
883170222Sdougb *\li	msg be a valid message
884135446Strhodes *
885170222Sdougb *\li	item != NULL && *item == NULL
886135446Strhodes *
887135446Strhodes * Returns:
888170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
889170222Sdougb *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
890135446Strhodes */
891135446Strhodes
892135446Strhodesvoid
893135446Strhodesdns_message_puttempname(dns_message_t *msg, dns_name_t **item);
894170222Sdougb/*%<
895135446Strhodes * Return a borrowed name to the message's name free list.
896135446Strhodes *
897135446Strhodes * Requires:
898170222Sdougb *\li	msg be a valid message
899135446Strhodes *
900170222Sdougb *\li	item != NULL && *item point to a name returned by
901135446Strhodes *	dns_message_gettempname()
902135446Strhodes *
903135446Strhodes * Ensures:
904170222Sdougb *\li	*item == NULL
905135446Strhodes */
906135446Strhodes
907135446Strhodesvoid
908135446Strhodesdns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item);
909170222Sdougb/*%<
910135446Strhodes * Return a borrowed rdata to the message's rdata free list.
911135446Strhodes *
912135446Strhodes * Requires:
913170222Sdougb *\li	msg be a valid message
914135446Strhodes *
915170222Sdougb *\li	item != NULL && *item point to a rdata returned by
916135446Strhodes *	dns_message_gettemprdata()
917135446Strhodes *
918135446Strhodes * Ensures:
919170222Sdougb *\li	*item == NULL
920135446Strhodes */
921135446Strhodes
922135446Strhodesvoid
923135446Strhodesdns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item);
924170222Sdougb/*%<
925135446Strhodes * Return a borrowed rdataset to the message's rdataset free list.
926135446Strhodes *
927135446Strhodes * Requires:
928170222Sdougb *\li	msg be a valid message
929135446Strhodes *
930170222Sdougb *\li	item != NULL && *item point to a rdataset returned by
931135446Strhodes *	dns_message_gettemprdataset()
932135446Strhodes *
933135446Strhodes * Ensures:
934170222Sdougb *\li	*item == NULL
935135446Strhodes */
936135446Strhodes
937135446Strhodesvoid
938135446Strhodesdns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
939170222Sdougb/*%<
940135446Strhodes * Return a borrowed rdatalist to the message's rdatalist free list.
941135446Strhodes *
942135446Strhodes * Requires:
943170222Sdougb *\li	msg be a valid message
944135446Strhodes *
945170222Sdougb *\li	item != NULL && *item point to a rdatalist returned by
946135446Strhodes *	dns_message_gettemprdatalist()
947135446Strhodes *
948135446Strhodes * Ensures:
949170222Sdougb *\li	*item == NULL
950135446Strhodes */
951135446Strhodes
952135446Strhodesisc_result_t
953135446Strhodesdns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
954135446Strhodes		       unsigned int *flagsp);
955170222Sdougb/*%<
956135446Strhodes * Assume the remaining region of "source" is a DNS message.  Peek into
957135446Strhodes * it and fill in "*idp" with the message id, and "*flagsp" with the flags.
958135446Strhodes *
959135446Strhodes * Requires:
960135446Strhodes *
961170222Sdougb *\li	source != NULL
962135446Strhodes *
963135446Strhodes * Ensures:
964135446Strhodes *
965170222Sdougb *\li	if (idp != NULL) *idp == message id.
966135446Strhodes *
967170222Sdougb *\li	if (flagsp != NULL) *flagsp == message flags.
968135446Strhodes *
969135446Strhodes * Returns:
970135446Strhodes *
971170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
972135446Strhodes *
973170222Sdougb *\li	#ISC_R_UNEXPECTEDEND	-- buffer doesn't contain enough for a header.
974135446Strhodes */
975135446Strhodes
976135446Strhodesisc_result_t
977135446Strhodesdns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section);
978170222Sdougb/*%<
979135446Strhodes * Start formatting a reply to the query in 'msg'.
980135446Strhodes *
981135446Strhodes * Requires:
982135446Strhodes *
983170222Sdougb *\li	'msg' is a valid message with parsing intent, and contains a query.
984135446Strhodes *
985135446Strhodes * Ensures:
986135446Strhodes *
987170222Sdougb *\li	The message will have a rendering intent.  If 'want_question_section'
988135446Strhodes *	is true, the message opcode is query or notify, and the question
989135446Strhodes *	section is present and properly formatted, then the question section
990135446Strhodes *	will be included in the reply.  All other sections will be cleared.
991135446Strhodes *	The QR flag will be set, the RD flag will be preserved, and all other
992135446Strhodes *	flags will be cleared.
993135446Strhodes *
994135446Strhodes * Returns:
995135446Strhodes *
996170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
997135446Strhodes *
998170222Sdougb *\li	#DNS_R_FORMERR		-- the header or question section of the
999135446Strhodes *				   message is invalid, replying is impossible.
1000135446Strhodes *				   If DNS_R_FORMERR is returned when
1001135446Strhodes *				   want_question_section is ISC_FALSE, then
1002135446Strhodes *				   it's the header section that's bad;
1003135446Strhodes *				   otherwise either of the header or question
1004135446Strhodes *				   sections may be bad.
1005135446Strhodes */
1006135446Strhodes
1007135446Strhodesdns_rdataset_t *
1008135446Strhodesdns_message_getopt(dns_message_t *msg);
1009170222Sdougb/*%<
1010135446Strhodes * Get the OPT record for 'msg'.
1011135446Strhodes *
1012135446Strhodes * Requires:
1013135446Strhodes *
1014170222Sdougb *\li	'msg' is a valid message.
1015135446Strhodes *
1016135446Strhodes * Returns:
1017135446Strhodes *
1018170222Sdougb *\li	The OPT rdataset of 'msg', or NULL if there isn't one.
1019135446Strhodes */
1020135446Strhodes
1021135446Strhodesisc_result_t
1022135446Strhodesdns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
1023170222Sdougb/*%<
1024135446Strhodes * Set the OPT record for 'msg'.
1025135446Strhodes *
1026135446Strhodes * Requires:
1027135446Strhodes *
1028170222Sdougb *\li	'msg' is a valid message with rendering intent
1029135446Strhodes *	and no sections have been rendered.
1030135446Strhodes *
1031170222Sdougb *\li	'opt' is a valid OPT record.
1032135446Strhodes *
1033135446Strhodes * Ensures:
1034135446Strhodes *
1035170222Sdougb *\li	The OPT record has either been freed or ownership of it has
1036135446Strhodes *	been transferred to the message.
1037135446Strhodes *
1038193149Sdougb *\li	If ISC_R_SUCCESS was returned, the OPT record will be rendered
1039135446Strhodes *	when dns_message_renderend() is called.
1040135446Strhodes *
1041135446Strhodes * Returns:
1042135446Strhodes *
1043170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
1044135446Strhodes *
1045170222Sdougb *\li	#ISC_R_NOSPACE		-- there is no space for the OPT record.
1046135446Strhodes */
1047135446Strhodes
1048135446Strhodesdns_rdataset_t *
1049135446Strhodesdns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
1050170222Sdougb/*%<
1051135446Strhodes * Get the TSIG record and owner for 'msg'.
1052135446Strhodes *
1053135446Strhodes * Requires:
1054135446Strhodes *
1055170222Sdougb *\li	'msg' is a valid message.
1056170222Sdougb *\li	'owner' is NULL or *owner is NULL.
1057135446Strhodes *
1058135446Strhodes * Returns:
1059135446Strhodes *
1060170222Sdougb *\li	The TSIG rdataset of 'msg', or NULL if there isn't one.
1061135446Strhodes *
1062135446Strhodes * Ensures:
1063135446Strhodes *
1064170222Sdougb * \li	If 'owner' is not NULL, it will point to the owner name.
1065135446Strhodes */
1066135446Strhodes
1067135446Strhodesisc_result_t
1068135446Strhodesdns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
1069170222Sdougb/*%<
1070135446Strhodes * Set the tsig key for 'msg'.  This is only necessary for when rendering a
1071135446Strhodes * query or parsing a response.  The key (if non-NULL) is attached to, and
1072135446Strhodes * will be detached when the message is destroyed.
1073135446Strhodes *
1074135446Strhodes * Requires:
1075135446Strhodes *
1076170222Sdougb *\li	'msg' is a valid message with rendering intent,
1077135446Strhodes *	dns_message_renderbegin() has been called, and no sections have been
1078135446Strhodes *	rendered.
1079170222Sdougb *\li	'key' is a valid tsig key or NULL.
1080135446Strhodes *
1081135446Strhodes * Returns:
1082135446Strhodes *
1083170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
1084135446Strhodes *
1085170222Sdougb *\li	#ISC_R_NOSPACE		-- there is no space for the TSIG record.
1086135446Strhodes */
1087135446Strhodes
1088135446Strhodesdns_tsigkey_t *
1089135446Strhodesdns_message_gettsigkey(dns_message_t *msg);
1090170222Sdougb/*%<
1091135446Strhodes * Gets the tsig key for 'msg'.
1092135446Strhodes *
1093135446Strhodes * Requires:
1094135446Strhodes *
1095170222Sdougb *\li	'msg' is a valid message
1096135446Strhodes */
1097135446Strhodes
1098135446Strhodesisc_result_t
1099135446Strhodesdns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
1100170222Sdougb/*%<
1101135446Strhodes * Indicates that 'querytsig' is the TSIG from the signed query for which
1102135446Strhodes * 'msg' is the response.  This is also used for chained TSIGs in TCP
1103135446Strhodes * responses.
1104135446Strhodes *
1105135446Strhodes * Requires:
1106135446Strhodes *
1107170222Sdougb *\li	'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
1108135446Strhodes *	or NULL
1109135446Strhodes *
1110170222Sdougb *\li	'msg' is a valid message
1111135446Strhodes *
1112135446Strhodes * Returns:
1113135446Strhodes *
1114170222Sdougb *\li	#ISC_R_SUCCESS
1115170222Sdougb *\li	#ISC_R_NOMEMORY
1116135446Strhodes */
1117135446Strhodes
1118135446Strhodesisc_result_t
1119135446Strhodesdns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
1120135446Strhodes			 isc_buffer_t **querytsig);
1121170222Sdougb/*%<
1122135446Strhodes * Gets the tsig from the TSIG from the signed query 'msg'.  This is also used
1123135446Strhodes * for chained TSIGs in TCP responses.  Unlike dns_message_gettsig, this makes
1124135446Strhodes * a copy of the data, so can be used if the message is destroyed.
1125135446Strhodes *
1126135446Strhodes * Requires:
1127135446Strhodes *
1128170222Sdougb *\li	'msg' is a valid signed message
1129170222Sdougb *\li	'mctx' is a valid memory context
1130170222Sdougb *\li	querytsig != NULL && *querytsig == NULL
1131135446Strhodes *
1132135446Strhodes * Returns:
1133135446Strhodes *
1134170222Sdougb *\li	#ISC_R_SUCCESS
1135170222Sdougb *\li	#ISC_R_NOMEMORY
1136135446Strhodes *
1137135446Strhodes * Ensures:
1138170222Sdougb *\li 	'tsig' points to NULL or an allocated buffer which must be freed
1139135446Strhodes * 	by the caller.
1140135446Strhodes */
1141135446Strhodes
1142135446Strhodesdns_rdataset_t *
1143135446Strhodesdns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
1144170222Sdougb/*%<
1145135446Strhodes * Get the SIG(0) record and owner for 'msg'.
1146135446Strhodes *
1147135446Strhodes * Requires:
1148135446Strhodes *
1149170222Sdougb *\li	'msg' is a valid message.
1150170222Sdougb *\li	'owner' is NULL or *owner is NULL.
1151135446Strhodes *
1152135446Strhodes * Returns:
1153135446Strhodes *
1154170222Sdougb *\li	The SIG(0) rdataset of 'msg', or NULL if there isn't one.
1155135446Strhodes *
1156135446Strhodes * Ensures:
1157135446Strhodes *
1158170222Sdougb * \li	If 'owner' is not NULL, it will point to the owner name.
1159135446Strhodes */
1160135446Strhodes
1161135446Strhodesisc_result_t
1162135446Strhodesdns_message_setsig0key(dns_message_t *msg, dst_key_t *key);
1163170222Sdougb/*%<
1164135446Strhodes * Set the SIG(0) key for 'msg'.
1165135446Strhodes *
1166135446Strhodes * Requires:
1167135446Strhodes *
1168170222Sdougb *\li	'msg' is a valid message with rendering intent,
1169135446Strhodes *	dns_message_renderbegin() has been called, and no sections have been
1170135446Strhodes *	rendered.
1171170222Sdougb *\li	'key' is a valid sig key or NULL.
1172135446Strhodes *
1173135446Strhodes * Returns:
1174135446Strhodes *
1175170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
1176135446Strhodes *
1177170222Sdougb *\li	#ISC_R_NOSPACE		-- there is no space for the SIG(0) record.
1178135446Strhodes */
1179135446Strhodes
1180135446Strhodesdst_key_t *
1181135446Strhodesdns_message_getsig0key(dns_message_t *msg);
1182170222Sdougb/*%<
1183135446Strhodes * Gets the SIG(0) key for 'msg'.
1184135446Strhodes *
1185135446Strhodes * Requires:
1186135446Strhodes *
1187170222Sdougb *\li	'msg' is a valid message
1188135446Strhodes */
1189135446Strhodes
1190135446Strhodesvoid
1191135446Strhodesdns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
1192170222Sdougb/*%<
1193135446Strhodes * Give the *buffer to the message code to clean up when it is no
1194135446Strhodes * longer needed.  This is usually when the message is reset or
1195135446Strhodes * destroyed.
1196135446Strhodes *
1197135446Strhodes * Requires:
1198135446Strhodes *
1199170222Sdougb *\li	msg be a valid message.
1200135446Strhodes *
1201170222Sdougb *\li	buffer != NULL && *buffer is a valid isc_buffer_t, which was
1202193149Sdougb *	dynamically allocated via isc_buffer_allocate().
1203135446Strhodes */
1204135446Strhodes
1205135446Strhodesisc_result_t
1206135446Strhodesdns_message_signer(dns_message_t *msg, dns_name_t *signer);
1207170222Sdougb/*%<
1208135446Strhodes * If this message was signed, return the identity of the signer.
1209135446Strhodes * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the
1210135446Strhodes * key that signed the message.
1211135446Strhodes *
1212135446Strhodes * Requires:
1213135446Strhodes *
1214170222Sdougb *\li	msg is a valid parsed message.
1215170222Sdougb *\li	signer is a valid name
1216135446Strhodes *
1217135446Strhodes * Returns:
1218135446Strhodes *
1219170222Sdougb *\li	#ISC_R_SUCCESS		- the message was signed, and *signer
1220135446Strhodes *				  contains the signing identity
1221135446Strhodes *
1222170222Sdougb *\li	#ISC_R_NOTFOUND		- no TSIG or SIG(0) record is present in the
1223135446Strhodes *				  message
1224135446Strhodes *
1225170222Sdougb *\li	#DNS_R_TSIGVERIFYFAILURE	- the message was signed by a TSIG, but the
1226135446Strhodes *				  signature failed to verify
1227135446Strhodes *
1228170222Sdougb *\li	#DNS_R_TSIGERRORSET	- the message was signed by a TSIG and
1229135446Strhodes *				  verified, but the query was rejected by
1230135446Strhodes *				  the server
1231135446Strhodes *
1232170222Sdougb *\li	#DNS_R_NOIDENTITY	- the message was signed by a TSIG and
1233135446Strhodes *				  verified, but the key has no identity since
1234135446Strhodes *				  it was generated by an unsigned TKEY process
1235135446Strhodes *
1236170222Sdougb *\li	#DNS_R_SIGINVALID	- the message was signed by a SIG(0), but
1237135446Strhodes *				  the signature failed to verify
1238135446Strhodes *
1239170222Sdougb *\li	#DNS_R_NOTVERIFIEDYET	- the message was signed by a TSIG or SIG(0),
1240135446Strhodes *				  but the signature has not been verified yet
1241135446Strhodes */
1242135446Strhodes
1243135446Strhodesisc_result_t
1244135446Strhodesdns_message_checksig(dns_message_t *msg, dns_view_t *view);
1245170222Sdougb/*%<
1246135446Strhodes * If this message was signed, verify the signature.
1247135446Strhodes *
1248135446Strhodes * Requires:
1249135446Strhodes *
1250170222Sdougb *\li	msg is a valid parsed message.
1251170222Sdougb *\li	view is a valid view or NULL
1252135446Strhodes *
1253135446Strhodes * Returns:
1254135446Strhodes *
1255170222Sdougb *\li	#ISC_R_SUCCESS		- the message was unsigned, or the message
1256135446Strhodes *				  was signed correctly.
1257135446Strhodes *
1258170222Sdougb *\li	#DNS_R_EXPECTEDTSIG	- A TSIG was expected, but not seen
1259170222Sdougb *\li	#DNS_R_UNEXPECTEDTSIG	- A TSIG was seen but not expected
1260170222Sdougb *\li	#DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
1261135446Strhodes */
1262135446Strhodes
1263135446Strhodesisc_result_t
1264135446Strhodesdns_message_rechecksig(dns_message_t *msg, dns_view_t *view);
1265170222Sdougb/*%<
1266135446Strhodes * Reset the signature state and then if the message was signed,
1267135446Strhodes * verify the message.
1268135446Strhodes *
1269135446Strhodes * Requires:
1270135446Strhodes *
1271170222Sdougb *\li	msg is a valid parsed message.
1272170222Sdougb *\li	view is a valid view or NULL
1273135446Strhodes *
1274135446Strhodes * Returns:
1275135446Strhodes *
1276170222Sdougb *\li	#ISC_R_SUCCESS		- the message was unsigned, or the message
1277135446Strhodes *				  was signed correctly.
1278135446Strhodes *
1279170222Sdougb *\li	#DNS_R_EXPECTEDTSIG	- A TSIG was expected, but not seen
1280170222Sdougb *\li	#DNS_R_UNEXPECTEDTSIG	- A TSIG was seen but not expected
1281170222Sdougb *\li	#DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
1282135446Strhodes */
1283135446Strhodes
1284135446Strhodesvoid
1285135446Strhodesdns_message_resetsig(dns_message_t *msg);
1286170222Sdougb/*%<
1287135446Strhodes * Reset the signature state.
1288135446Strhodes *
1289135446Strhodes * Requires:
1290170222Sdougb *\li	'msg' is a valid parsed message.
1291135446Strhodes */
1292135446Strhodes
1293135446Strhodesisc_region_t *
1294135446Strhodesdns_message_getrawmessage(dns_message_t *msg);
1295170222Sdougb/*%<
1296135446Strhodes * Retrieve the raw message in compressed wire format.  The message must
1297135446Strhodes * have been successfully parsed for it to have been saved.
1298135446Strhodes *
1299135446Strhodes * Requires:
1300170222Sdougb *\li	msg is a valid parsed message.
1301135446Strhodes *
1302135446Strhodes * Returns:
1303170222Sdougb *\li	NULL	if there is no saved message.
1304135446Strhodes *	a pointer to a region which refers the dns message.
1305135446Strhodes */
1306135446Strhodes
1307135446Strhodesvoid
1308135446Strhodesdns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
1309165071Sdougb			 const void *order_arg);
1310170222Sdougb/*%<
1311135446Strhodes * Define the order in which RR sets get rendered by
1312135446Strhodes * dns_message_rendersection() to be the ascending order
1313135446Strhodes * defined by the integer value returned by 'order' when
1314135446Strhodes * given each RR and 'arg' as arguments.  If 'order' and
1315135446Strhodes * 'order_arg' are NULL, a default order is used.
1316135446Strhodes *
1317135446Strhodes * Requires:
1318170222Sdougb *\li	msg be a valid message.
1319170222Sdougb *\li	order_arg is NULL if and only if order is NULL.
1320135446Strhodes */
1321135446Strhodes
1322193149Sdougbvoid
1323135446Strhodesdns_message_settimeadjust(dns_message_t *msg, int timeadjust);
1324170222Sdougb/*%<
1325135446Strhodes * Adjust the time used to sign/verify a message by timeadjust.
1326135446Strhodes * Currently only TSIG.
1327135446Strhodes *
1328135446Strhodes * Requires:
1329170222Sdougb *\li	msg be a valid message.
1330135446Strhodes */
1331135446Strhodes
1332193149Sdougbint
1333135446Strhodesdns_message_gettimeadjust(dns_message_t *msg);
1334170222Sdougb/*%<
1335135446Strhodes * Return the current time adjustment.
1336135446Strhodes *
1337135446Strhodes * Requires:
1338170222Sdougb *\li	msg be a valid message.
1339135446Strhodes */
1340135446Strhodes
1341135446StrhodesISC_LANG_ENDDECLS
1342135446Strhodes
1343135446Strhodes#endif /* DNS_MESSAGE_H */
1344