1135446Strhodes/*
2254402Serwin * Copyright (C) 2004-2010, 2012, 2013  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
18135446Strhodes#ifndef DNS_MESSAGE_H
19135446Strhodes#define DNS_MESSAGE_H 1
20135446Strhodes
21135446Strhodes/***
22135446Strhodes ***	Imports
23135446Strhodes ***/
24135446Strhodes
25135446Strhodes#include <isc/lang.h>
26135446Strhodes#include <isc/magic.h>
27135446Strhodes
28135446Strhodes#include <dns/compress.h>
29135446Strhodes#include <dns/masterdump.h>
30135446Strhodes#include <dns/types.h>
31135446Strhodes
32135446Strhodes#include <dst/dst.h>
33135446Strhodes
34193149Sdougb/*! \file dns/message.h
35170222Sdougb * \brief Message Handling Module
36170222Sdougb *
37135446Strhodes * How this beast works:
38135446Strhodes *
39135446Strhodes * When a dns message is received in a buffer, dns_message_fromwire() is called
40135446Strhodes * on the memory region.  Various items are checked including the format
41135446Strhodes * of the message (if counts are right, if counts consume the entire sections,
42135446Strhodes * and if sections consume the entire message) and known pseudo-RRs in the
43135446Strhodes * additional data section are analyzed and removed.
44135446Strhodes *
45135446Strhodes * TSIG checking is also done at this layer, and any DNSSEC transaction
46135446Strhodes * signatures should also be checked here.
47135446Strhodes *
48135446Strhodes * Notes on using the gettemp*() and puttemp*() functions:
49135446Strhodes *
50135446Strhodes * These functions return items (names, rdatasets, etc) allocated from some
51135446Strhodes * internal state of the dns_message_t.
52135446Strhodes *
53135446Strhodes * Names and rdatasets must be put back into the dns_message_t in
54135446Strhodes * one of two ways.  Assume a name was allocated via
55135446Strhodes * dns_message_gettempname():
56135446Strhodes *
57170222Sdougb *\li	(1) insert it into a section, using dns_message_addname().
58135446Strhodes *
59170222Sdougb *\li	(2) return it to the message using dns_message_puttempname().
60135446Strhodes *
61135446Strhodes * The same applies to rdatasets.
62135446Strhodes *
63135446Strhodes * On the other hand, offsets, rdatalists and rdatas allocated using
64135446Strhodes * dns_message_gettemp*() will always be freed automatically
65135446Strhodes * when the message is reset or destroyed; calling dns_message_puttemp*()
66135446Strhodes * on rdatalists and rdatas is optional and serves only to enable the item
67135446Strhodes * to be reused multiple times during the lifetime of the message; offsets
68135446Strhodes * cannot be reused.
69135446Strhodes *
70135446Strhodes * Buffers allocated using isc_buffer_allocate() can be automatically freed
71135446Strhodes * as well by giving the buffer to the message using dns_message_takebuffer().
72135446Strhodes * Doing this will cause the buffer to be freed using isc_buffer_free()
73135446Strhodes * when the section lists are cleared, such as in a reset or in a destroy.
74135446Strhodes * Since the buffer itself exists until the message is destroyed, this sort
75135446Strhodes * of code can be written:
76135446Strhodes *
77170222Sdougb * \code
78135446Strhodes *	buffer = isc_buffer_allocate(mctx, 512);
79135446Strhodes *	name = NULL;
80135446Strhodes *	name = dns_message_gettempname(message, &name);
81135446Strhodes *	dns_name_init(name, NULL);
82224092Sdougb *	result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer);
83135446Strhodes *	dns_message_takebuffer(message, &buffer);
84170222Sdougb * \endcode
85135446Strhodes *
86135446Strhodes *
87135446Strhodes * TODO:
88135446Strhodes *
89135446Strhodes * XXX Needed:  ways to set and retrieve EDNS information, add rdata to a
90135446Strhodes * section, move rdata from one section to another, remove rdata, etc.
91135446Strhodes */
92135446Strhodes
93135446Strhodes#define DNS_MESSAGEFLAG_QR		0x8000U
94135446Strhodes#define DNS_MESSAGEFLAG_AA		0x0400U
95135446Strhodes#define DNS_MESSAGEFLAG_TC		0x0200U
96135446Strhodes#define DNS_MESSAGEFLAG_RD		0x0100U
97135446Strhodes#define DNS_MESSAGEFLAG_RA		0x0080U
98135446Strhodes#define DNS_MESSAGEFLAG_AD		0x0020U
99135446Strhodes#define DNS_MESSAGEFLAG_CD		0x0010U
100135446Strhodes
101193149Sdougb/*%< EDNS0 extended message flags */
102135446Strhodes#define DNS_MESSAGEEXTFLAG_DO		0x8000U
103135446Strhodes
104193149Sdougb/*%< EDNS0 extended OPT codes */
105193149Sdougb#define DNS_OPT_NSID		0x0003		/*%< NSID opt code */
106262706Serwin#define DNS_OPT_CLIENT_SUBNET	0x0008		/*%< client subnet opt code */
107193149Sdougb
108135446Strhodes#define DNS_MESSAGE_REPLYPRESERVE	(DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD)
109135446Strhodes#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
110135446Strhodes
111170222Sdougb#define DNS_MESSAGE_HEADERLEN		12 /*%< 6 isc_uint16_t's */
112135446Strhodes
113135446Strhodes#define DNS_MESSAGE_MAGIC		ISC_MAGIC('M','S','G','@')
114135446Strhodes#define DNS_MESSAGE_VALID(msg)		ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC)
115135446Strhodes
116135446Strhodes/*
117135446Strhodes * Ordering here matters.  DNS_SECTION_ANY must be the lowest and negative,
118135446Strhodes * and DNS_SECTION_MAX must be one greater than the last used section.
119135446Strhodes */
120135446Strhodestypedef int dns_section_t;
121135446Strhodes#define DNS_SECTION_ANY			(-1)
122135446Strhodes#define DNS_SECTION_QUESTION		0
123135446Strhodes#define DNS_SECTION_ANSWER		1
124135446Strhodes#define DNS_SECTION_AUTHORITY		2
125135446Strhodes#define DNS_SECTION_ADDITIONAL		3
126135446Strhodes#define DNS_SECTION_MAX			4
127135446Strhodes
128135446Strhodestypedef int dns_pseudosection_t;
129135446Strhodes#define DNS_PSEUDOSECTION_ANY		(-1)
130135446Strhodes#define DNS_PSEUDOSECTION_OPT           0
131135446Strhodes#define DNS_PSEUDOSECTION_TSIG          1
132135446Strhodes#define DNS_PSEUDOSECTION_SIG0          2
133135446Strhodes#define DNS_PSEUDOSECTION_MAX           3
134135446Strhodes
135135446Strhodestypedef int dns_messagetextflag_t;
136135446Strhodes#define DNS_MESSAGETEXTFLAG_NOCOMMENTS	0x0001
137135446Strhodes#define DNS_MESSAGETEXTFLAG_NOHEADERS	0x0002
138224092Sdougb#define DNS_MESSAGETEXTFLAG_ONESOA	0x0004
139224092Sdougb#define DNS_MESSAGETEXTFLAG_OMITSOA	0x0008
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. */
177224092Sdougb#ifdef ALLOW_FILTER_AAAA_ON_V4
178224092Sdougb#define DNS_MESSAGERENDER_FILTER_AAAA	0x0020	/*%< filter AAAA records */
179224092Sdougb#endif
180135446Strhodes
181135446Strhodestypedef struct dns_msgblock dns_msgblock_t;
182135446Strhodes
183135446Strhodesstruct dns_message {
184135446Strhodes	/* public from here down */
185135446Strhodes	unsigned int			magic;
186135446Strhodes
187135446Strhodes	dns_messageid_t			id;
188135446Strhodes	unsigned int			flags;
189135446Strhodes	dns_rcode_t			rcode;
190135446Strhodes	unsigned int			opcode;
191135446Strhodes	dns_rdataclass_t		rdclass;
192135446Strhodes
193135446Strhodes	/* 4 real, 1 pseudo */
194135446Strhodes	unsigned int			counts[DNS_SECTION_MAX];
195135446Strhodes
196135446Strhodes	/* private from here down */
197135446Strhodes	dns_namelist_t			sections[DNS_SECTION_MAX];
198135446Strhodes	dns_name_t		       *cursors[DNS_SECTION_MAX];
199135446Strhodes	dns_rdataset_t		       *opt;
200135446Strhodes	dns_rdataset_t		       *sig0;
201135446Strhodes	dns_rdataset_t		       *tsig;
202135446Strhodes
203135446Strhodes	int				state;
204135446Strhodes	unsigned int			from_to_wire : 2;
205135446Strhodes	unsigned int			header_ok : 1;
206135446Strhodes	unsigned int			question_ok : 1;
207135446Strhodes	unsigned int			tcp_continuation : 1;
208135446Strhodes	unsigned int			verified_sig : 1;
209135446Strhodes	unsigned int			verify_attempted : 1;
210135446Strhodes	unsigned int			free_query : 1;
211135446Strhodes	unsigned int			free_saved : 1;
212292321Sdelphij	unsigned int			tkey : 1;
213292321Sdelphij	unsigned int			rdclass_set : 1;
214135446Strhodes
215135446Strhodes	unsigned int			opt_reserved;
216135446Strhodes	unsigned int			sig_reserved;
217135446Strhodes	unsigned int			reserved; /* reserved space (render) */
218135446Strhodes
219135446Strhodes	isc_buffer_t		       *buffer;
220135446Strhodes	dns_compress_t		       *cctx;
221135446Strhodes
222135446Strhodes	isc_mem_t		       *mctx;
223135446Strhodes	isc_mempool_t		       *namepool;
224135446Strhodes	isc_mempool_t		       *rdspool;
225135446Strhodes
226135446Strhodes	isc_bufferlist_t		scratchpad;
227135446Strhodes	isc_bufferlist_t		cleanup;
228135446Strhodes
229135446Strhodes	ISC_LIST(dns_msgblock_t)	rdatas;
230135446Strhodes	ISC_LIST(dns_msgblock_t)	rdatalists;
231135446Strhodes	ISC_LIST(dns_msgblock_t)	offsets;
232135446Strhodes
233135446Strhodes	ISC_LIST(dns_rdata_t)		freerdata;
234135446Strhodes	ISC_LIST(dns_rdatalist_t)	freerdatalist;
235135446Strhodes
236135446Strhodes	dns_rcode_t			tsigstatus;
237135446Strhodes	dns_rcode_t			querytsigstatus;
238135446Strhodes	dns_name_t		       *tsigname; /* Owner name of TSIG, if any */
239135446Strhodes	dns_rdataset_t		       *querytsig;
240135446Strhodes	dns_tsigkey_t		       *tsigkey;
241135446Strhodes	dst_context_t		       *tsigctx;
242135446Strhodes	int				sigstart;
243135446Strhodes	int				timeadjust;
244135446Strhodes
245135446Strhodes	dns_name_t		       *sig0name; /* Owner name of SIG0, if any */
246135446Strhodes	dst_key_t		       *sig0key;
247135446Strhodes	dns_rcode_t			sig0status;
248135446Strhodes	isc_region_t			query;
249135446Strhodes	isc_region_t			saved;
250135446Strhodes
251135446Strhodes	dns_rdatasetorderfunc_t		order;
252165071Sdougb	const void *			order_arg;
253135446Strhodes};
254135446Strhodes
255254402Serwinstruct dns_ednsopt {
256254402Serwin	isc_uint16_t			code;
257254402Serwin	isc_uint16_t			length;
258254402Serwin	unsigned char			*value;
259254402Serwin};
260254402Serwin
261135446Strhodes/***
262135446Strhodes *** Functions
263135446Strhodes ***/
264135446Strhodes
265135446StrhodesISC_LANG_BEGINDECLS
266135446Strhodes
267135446Strhodesisc_result_t
268135446Strhodesdns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp);
269135446Strhodes
270170222Sdougb/*%<
271135446Strhodes * Create msg structure.
272135446Strhodes *
273135446Strhodes * This function will allocate some internal blocks of memory that are
274135446Strhodes * expected to be needed for parsing or rendering nearly any type of message.
275135446Strhodes *
276135446Strhodes * Requires:
277170222Sdougb *\li	'mctx' be a valid memory context.
278135446Strhodes *
279170222Sdougb *\li	'msgp' be non-null and '*msg' be NULL.
280135446Strhodes *
281170222Sdougb *\li	'intent' must be one of DNS_MESSAGE_INTENTPARSE or
282170222Sdougb *	#DNS_MESSAGE_INTENTRENDER.
283135446Strhodes *
284135446Strhodes * Ensures:
285170222Sdougb *\li	The data in "*msg" is set to indicate an unused and empty msg
286135446Strhodes *	structure.
287135446Strhodes *
288135446Strhodes * Returns:
289170222Sdougb *\li	#ISC_R_NOMEMORY		-- out of memory
290170222Sdougb *\li	#ISC_R_SUCCESS		-- success
291135446Strhodes */
292135446Strhodes
293135446Strhodesvoid
294135446Strhodesdns_message_reset(dns_message_t *msg, unsigned int intent);
295170222Sdougb/*%<
296135446Strhodes * Reset a message structure to default state.  All internal lists are freed
297135446Strhodes * or reset to a default state as well.  This is simply a more efficient
298135446Strhodes * way to call dns_message_destroy() followed by dns_message_allocate(),
299135446Strhodes * since it avoid many memory allocations.
300135446Strhodes *
301135446Strhodes * If any data loanouts (buffers, names, rdatas, etc) were requested,
302135446Strhodes * the caller must no longer use them after this call.
303135446Strhodes *
304135446Strhodes * The intended next use of the message will be 'intent'.
305135446Strhodes *
306135446Strhodes * Requires:
307135446Strhodes *
308170222Sdougb *\li	'msg' be valid.
309135446Strhodes *
310170222Sdougb *\li	'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER
311135446Strhodes */
312135446Strhodes
313135446Strhodesvoid
314135446Strhodesdns_message_destroy(dns_message_t **msgp);
315170222Sdougb/*%<
316135446Strhodes * Destroy all state in the message.
317135446Strhodes *
318135446Strhodes * Requires:
319135446Strhodes *
320170222Sdougb *\li	'msgp' be valid.
321135446Strhodes *
322135446Strhodes * Ensures:
323170222Sdougb *\li	'*msgp' == NULL
324135446Strhodes */
325135446Strhodes
326135446Strhodesisc_result_t
327135446Strhodesdns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
328135446Strhodes			  const dns_master_style_t *style,
329135446Strhodes			  dns_messagetextflag_t flags,
330135446Strhodes			  isc_buffer_t *target);
331135446Strhodes
332135446Strhodesisc_result_t
333135446Strhodesdns_message_pseudosectiontotext(dns_message_t *msg,
334135446Strhodes				dns_pseudosection_t section,
335135446Strhodes				const dns_master_style_t *style,
336135446Strhodes				dns_messagetextflag_t flags,
337135446Strhodes				isc_buffer_t *target);
338170222Sdougb/*%<
339135446Strhodes * Convert section 'section' or 'pseudosection' of message 'msg' to
340135446Strhodes * a cleartext representation
341135446Strhodes *
342135446Strhodes * Notes:
343170222Sdougb *     \li See dns_message_totext for meanings of flags.
344135446Strhodes *
345135446Strhodes * Requires:
346135446Strhodes *
347170222Sdougb *\li	'msg' is a valid message.
348135446Strhodes *
349170222Sdougb *\li	'style' is a valid master dump style.
350135446Strhodes *
351170222Sdougb *\li	'target' is a valid buffer.
352135446Strhodes *
353170222Sdougb *\li	'section' is a valid section label.
354135446Strhodes *
355135446Strhodes * Ensures:
356135446Strhodes *
357170222Sdougb *\li	If the result is success:
358135446Strhodes *		The used space in 'target' is updated.
359135446Strhodes *
360135446Strhodes * Returns:
361135446Strhodes *
362170222Sdougb *\li	#ISC_R_SUCCESS
363170222Sdougb *\li	#ISC_R_NOSPACE
364170222Sdougb *\li	#ISC_R_NOMORE
365135446Strhodes *
366170222Sdougb *\li	Note: On error return, *target may be partially filled with data.
367135446Strhodes*/
368135446Strhodes
369135446Strhodesisc_result_t
370135446Strhodesdns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
371135446Strhodes		   dns_messagetextflag_t flags, isc_buffer_t *target);
372170222Sdougb/*%<
373135446Strhodes * Convert all sections of message 'msg' to a cleartext representation
374135446Strhodes *
375135446Strhodes * Notes:
376170222Sdougb * \li     In flags, If #DNS_MESSAGETEXTFLAG_OMITDOT is set, then the
377135446Strhodes *      final '.' in absolute names will not be emitted.  If
378170222Sdougb *      #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning
379135446Strhodes *      with ";;" will be emitted indicating section name.  If
380170222Sdougb *      #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will
381135446Strhodes *      be emitted.
382135446Strhodes *
383224092Sdougb *	If #DNS_MESSAGETEXTFLAG_ONESOA is set then only print the
384224092Sdougb *	first SOA record in the answer section.  If
385224092Sdougb *	#DNS_MESSAGETEXTFLAG_OMITSOA is set don't print any SOA records
386224092Sdougb *	in the answer section.  These are useful for suppressing the
387224092Sdougb *	display of the second SOA record in a AXFR by setting
388224092Sdougb *	#DNS_MESSAGETEXTFLAG_ONESOA on the first message in a AXFR stream
389224092Sdougb *	and #DNS_MESSAGETEXTFLAG_OMITSOA on subsequent messages.
390224092Sdougb *
391135446Strhodes * Requires:
392135446Strhodes *
393170222Sdougb *\li	'msg' is a valid message.
394135446Strhodes *
395170222Sdougb *\li	'style' is a valid master dump style.
396135446Strhodes *
397170222Sdougb *\li	'target' is a valid buffer.
398135446Strhodes *
399135446Strhodes * Ensures:
400135446Strhodes *
401170222Sdougb *\li	If the result is success:
402135446Strhodes *		The used space in 'target' is updated.
403135446Strhodes *
404135446Strhodes * Returns:
405135446Strhodes *
406170222Sdougb *\li	#ISC_R_SUCCESS
407170222Sdougb *\li	#ISC_R_NOSPACE
408170222Sdougb *\li	#ISC_R_NOMORE
409135446Strhodes *
410170222Sdougb *\li	Note: On error return, *target may be partially filled with data.
411135446Strhodes */
412135446Strhodes
413135446Strhodesisc_result_t
414135446Strhodesdns_message_parse(dns_message_t *msg, isc_buffer_t *source,
415135446Strhodes		  unsigned int options);
416170222Sdougb/*%<
417135446Strhodes * Parse raw wire data in 'source' as a DNS message.
418135446Strhodes *
419135446Strhodes * OPT records are detected and stored in the pseudo-section "opt".
420135446Strhodes * TSIGs are detected and stored in the pseudo-section "tsig".
421135446Strhodes *
422170222Sdougb * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message
423135446Strhodes * is UPDATE, a separate dns_name_t object will be created for each RR in the
424135446Strhodes * message.  Each such dns_name_t will have a single rdataset containing the
425135446Strhodes * single RR, and the order of the RRs in the message is preserved.
426135446Strhodes * Otherwise, only one dns_name_t object will be created for each unique
427135446Strhodes * owner name in the section, and each such dns_name_t will have a list
428135446Strhodes * of rdatasets.  To access the names and their data, use
429135446Strhodes * dns_message_firstname() and dns_message_nextname().
430135446Strhodes *
431170222Sdougb * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
432135446Strhodes * not be considered FORMERRs.  If the entire message can be parsed, it
433135446Strhodes * will be returned and DNS_R_RECOVERABLE will be returned.
434135446Strhodes *
435170222Sdougb * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
436135446Strhodes * RR's as possible, DNS_R_RECOVERABLE will be returned.
437135446Strhodes *
438135446Strhodes * OPT and TSIG records are always handled specially, regardless of the
439135446Strhodes * 'preserve_order' setting.
440135446Strhodes *
441135446Strhodes * Requires:
442170222Sdougb *\li	"msg" be valid.
443135446Strhodes *
444170222Sdougb *\li	"buffer" be a wire format buffer.
445135446Strhodes *
446135446Strhodes * Ensures:
447170222Sdougb *\li	The buffer's data format is correct.
448135446Strhodes *
449170222Sdougb *\li	The buffer's contents verify as correct regarding header bits, buffer
450135446Strhodes * 	and rdata sizes, etc.
451135446Strhodes *
452135446Strhodes * Returns:
453170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well
454170222Sdougb *\li	#ISC_R_NOMEMORY		-- no memory
455170222Sdougb *\li	#DNS_R_RECOVERABLE	-- the message parsed properly, but contained
456135446Strhodes *				   errors.
457170222Sdougb *\li	Many other errors possible XXXMLG
458135446Strhodes */
459135446Strhodes
460135446Strhodesisc_result_t
461135446Strhodesdns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
462135446Strhodes			isc_buffer_t *buffer);
463170222Sdougb/*%<
464135446Strhodes * Begin rendering on a message.  Only one call can be made to this function
465135446Strhodes * per message.
466135446Strhodes *
467135446Strhodes * The compression context is "owned" by the message library until
468135446Strhodes * dns_message_renderend() is called.  It must be invalidated by the caller.
469135446Strhodes *
470135446Strhodes * The buffer is "owned" by the message library until dns_message_renderend()
471135446Strhodes * is called.
472135446Strhodes *
473135446Strhodes * Requires:
474135446Strhodes *
475170222Sdougb *\li	'msg' be valid.
476135446Strhodes *
477170222Sdougb *\li	'cctx' be valid.
478135446Strhodes *
479170222Sdougb *\li	'buffer' is a valid buffer.
480135446Strhodes *
481135446Strhodes * Side Effects:
482135446Strhodes *
483170222Sdougb *\li	The buffer is cleared before it is used.
484135446Strhodes *
485135446Strhodes * Returns:
486170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well
487170222Sdougb *\li	#ISC_R_NOSPACE		-- output buffer is too small
488135446Strhodes */
489135446Strhodes
490135446Strhodesisc_result_t
491135446Strhodesdns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
492170222Sdougb/*%<
493135446Strhodes * Reset the buffer.  This can be used after growing the old buffer
494135446Strhodes * on a ISC_R_NOSPACE return from most of the render functions.
495135446Strhodes *
496135446Strhodes * On successful completion, the old buffer is no longer used by the
497135446Strhodes * library.  The new buffer is owned by the library until
498135446Strhodes * dns_message_renderend() is called.
499135446Strhodes *
500135446Strhodes * Requires:
501135446Strhodes *
502170222Sdougb *\li	'msg' be valid.
503135446Strhodes *
504170222Sdougb *\li	dns_message_renderbegin() was called.
505135446Strhodes *
506170222Sdougb *\li	buffer != NULL.
507135446Strhodes *
508135446Strhodes * Returns:
509170222Sdougb *\li	#ISC_R_NOSPACE		-- new buffer is too small
510170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
511135446Strhodes */
512135446Strhodes
513135446Strhodesisc_result_t
514135446Strhodesdns_message_renderreserve(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 * Reserve "space" bytes in the given buffer.
520135446Strhodes *
521135446Strhodes * Requires:
522135446Strhodes *
523170222Sdougb *\li	'msg' be valid.
524135446Strhodes *
525170222Sdougb *\li	dns_message_renderbegin() was called.
526135446Strhodes *
527135446Strhodes * Returns:
528170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
529170222Sdougb *\li	#ISC_R_NOSPACE		-- not enough free space in the buffer.
530135446Strhodes */
531135446Strhodes
532135446Strhodesvoid
533135446Strhodesdns_message_renderrelease(dns_message_t *msg, unsigned int space);
534170222Sdougb/*%<
535135446Strhodes * XXXMLG should use size_t rather than unsigned int once the buffer
536135446Strhodes * API is cleaned up
537135446Strhodes *
538135446Strhodes * Release "space" bytes in the given buffer that was previously reserved.
539135446Strhodes *
540135446Strhodes * Requires:
541135446Strhodes *
542170222Sdougb *\li	'msg' be valid.
543135446Strhodes *
544170222Sdougb *\li	'space' is less than or equal to the total amount of space reserved
545135446Strhodes *	via prior calls to dns_message_renderreserve().
546135446Strhodes *
547170222Sdougb *\li	dns_message_renderbegin() was called.
548135446Strhodes */
549135446Strhodes
550135446Strhodesisc_result_t
551135446Strhodesdns_message_rendersection(dns_message_t *msg, dns_section_t section,
552135446Strhodes			  unsigned int options);
553170222Sdougb/*%<
554135446Strhodes * Render all names, rdatalists, etc from the given section at the
555135446Strhodes * specified priority or higher.
556135446Strhodes *
557135446Strhodes * Requires:
558170222Sdougb *\li	'msg' be valid.
559135446Strhodes *
560170222Sdougb *\li	'section' be a valid section.
561135446Strhodes *
562170222Sdougb *\li	dns_message_renderbegin() was called.
563135446Strhodes *
564135446Strhodes * Returns:
565170222Sdougb *\li	#ISC_R_SUCCESS		-- all records were written, and there are
566135446Strhodes *				   no more records for this section.
567170222Sdougb *\li	#ISC_R_NOSPACE		-- Not enough room in the buffer to write
568135446Strhodes *				   all records requested.
569170222Sdougb *\li	#DNS_R_MOREDATA		-- All requested records written, and there
570135446Strhodes *				   are records remaining for this section.
571135446Strhodes */
572135446Strhodes
573135446Strhodesvoid
574135446Strhodesdns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
575170222Sdougb/*%<
576135446Strhodes * Render the message header.  This is implicitly called by
577135446Strhodes * dns_message_renderend().
578135446Strhodes *
579135446Strhodes * Requires:
580135446Strhodes *
581170222Sdougb *\li	'msg' be a valid message.
582135446Strhodes *
583170222Sdougb *\li	dns_message_renderbegin() was called.
584135446Strhodes *
585170222Sdougb *\li	'target' is a valid buffer with enough space to hold a message header
586135446Strhodes */
587135446Strhodes
588135446Strhodesisc_result_t
589135446Strhodesdns_message_renderend(dns_message_t *msg);
590170222Sdougb/*%<
591135446Strhodes * Finish rendering to the buffer.  Note that more data can be in the
592135446Strhodes * 'msg' structure.  Destroying the structure will free this, or in a multi-
593135446Strhodes * part EDNS1 message this data can be rendered to another buffer later.
594135446Strhodes *
595135446Strhodes * Requires:
596135446Strhodes *
597170222Sdougb *\li	'msg' be a valid message.
598135446Strhodes *
599170222Sdougb *\li	dns_message_renderbegin() was called.
600135446Strhodes *
601135446Strhodes * Returns:
602170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
603135446Strhodes */
604135446Strhodes
605135446Strhodesvoid
606135446Strhodesdns_message_renderreset(dns_message_t *msg);
607170222Sdougb/*%<
608135446Strhodes * Reset the message so that it may be rendered again.
609135446Strhodes *
610135446Strhodes * Notes:
611135446Strhodes *
612170222Sdougb *\li	If dns_message_renderbegin() has been called, dns_message_renderend()
613135446Strhodes *	must be called before calling this function.
614135446Strhodes *
615135446Strhodes * Requires:
616135446Strhodes *
617170222Sdougb *\li	'msg' be a valid message with rendering intent.
618135446Strhodes */
619135446Strhodes
620135446Strhodesisc_result_t
621135446Strhodesdns_message_firstname(dns_message_t *msg, dns_section_t section);
622170222Sdougb/*%<
623135446Strhodes * Set internal per-section name pointer to the beginning of the section.
624135446Strhodes *
625135446Strhodes * The functions dns_message_firstname() and dns_message_nextname() may
626135446Strhodes * be used for iterating over the owner names in a section.
627135446Strhodes *
628135446Strhodes * Requires:
629135446Strhodes *
630170222Sdougb *\li   	'msg' be valid.
631135446Strhodes *
632170222Sdougb *\li	'section' be a valid section.
633135446Strhodes *
634135446Strhodes * Returns:
635170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
636170222Sdougb *\li	#ISC_R_NOMORE		-- No names on given section.
637135446Strhodes */
638135446Strhodes
639135446Strhodesisc_result_t
640135446Strhodesdns_message_nextname(dns_message_t *msg, dns_section_t section);
641170222Sdougb/*%<
642135446Strhodes * Sets the internal per-section name pointer to point to the next name
643135446Strhodes * in that section.
644135446Strhodes *
645135446Strhodes * Requires:
646135446Strhodes *
647170222Sdougb * \li  	'msg' be valid.
648135446Strhodes *
649170222Sdougb *\li	'section' be a valid section.
650135446Strhodes *
651170222Sdougb *\li	dns_message_firstname() must have been called on this section,
652135446Strhodes *	and the result was ISC_R_SUCCESS.
653135446Strhodes *
654135446Strhodes * Returns:
655170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
656170222Sdougb *\li	#ISC_R_NOMORE		-- No more names in given section.
657135446Strhodes */
658135446Strhodes
659135446Strhodesvoid
660135446Strhodesdns_message_currentname(dns_message_t *msg, dns_section_t section,
661135446Strhodes			dns_name_t **name);
662170222Sdougb/*%<
663135446Strhodes * Sets 'name' to point to the name where the per-section internal name
664135446Strhodes * pointer is currently set.
665135446Strhodes *
666135446Strhodes * This function returns the name in the database, so any data associated
667135446Strhodes * with it (via the name's "list" member) contains the actual rdatasets.
668135446Strhodes *
669135446Strhodes * Requires:
670135446Strhodes *
671170222Sdougb *\li	'msg' be valid.
672135446Strhodes *
673170222Sdougb *\li	'name' be non-NULL, and *name be NULL.
674135446Strhodes *
675170222Sdougb *\li	'section' be a valid section.
676135446Strhodes *
677170222Sdougb *\li	dns_message_firstname() must have been called on this section,
678135446Strhodes *	and the result of it and any dns_message_nextname() calls was
679170222Sdougb *	#ISC_R_SUCCESS.
680135446Strhodes */
681135446Strhodes
682135446Strhodesisc_result_t
683135446Strhodesdns_message_findname(dns_message_t *msg, dns_section_t section,
684135446Strhodes		     dns_name_t *target, dns_rdatatype_t type,
685135446Strhodes		     dns_rdatatype_t covers, dns_name_t **foundname,
686135446Strhodes		     dns_rdataset_t **rdataset);
687170222Sdougb/*%<
688135446Strhodes * Search for a name in the specified section.  If it is found, *name is
689135446Strhodes * set to point to the name, and *rdataset is set to point to the found
690135446Strhodes * rdataset (if type is specified as other than dns_rdatatype_any).
691135446Strhodes *
692135446Strhodes * Requires:
693170222Sdougb *\li	'msg' be valid.
694135446Strhodes *
695170222Sdougb *\li	'section' be a valid section.
696135446Strhodes *
697170222Sdougb *\li	If a pointer to the name is desired, 'foundname' should be non-NULL.
698135446Strhodes *	If it is non-NULL, '*foundname' MUST be NULL.
699135446Strhodes *
700170222Sdougb *\li	If a type other than dns_datatype_any is searched for, 'rdataset'
701135446Strhodes *	may be non-NULL, '*rdataset' be NULL, and will point at the found
702135446Strhodes *	rdataset.  If the type is dns_datatype_any, 'rdataset' must be NULL.
703135446Strhodes *
704170222Sdougb *\li	'target' be a valid name.
705135446Strhodes *
706170222Sdougb *\li	'type' be a valid type.
707135446Strhodes *
708170222Sdougb *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
709135446Strhodes *	Otherwise it should be 0.
710135446Strhodes *
711135446Strhodes * Returns:
712170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
713170222Sdougb *\li	#DNS_R_NXDOMAIN		-- name does not exist in that section.
714170222Sdougb *\li	#DNS_R_NXRRSET		-- The name does exist, but the desired
715135446Strhodes *				   type does not.
716135446Strhodes */
717135446Strhodes
718135446Strhodesisc_result_t
719135446Strhodesdns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
720135446Strhodes		     dns_rdatatype_t covers, dns_rdataset_t **rdataset);
721170222Sdougb/*%<
722135446Strhodes * Search the name for the specified type.  If it is found, *rdataset is
723135446Strhodes * filled in with a pointer to that rdataset.
724135446Strhodes *
725135446Strhodes * Requires:
726170222Sdougb *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
727135446Strhodes *
728170222Sdougb *\li	'type' be a valid type, and NOT dns_rdatatype_any.
729135446Strhodes *
730170222Sdougb *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
731135446Strhodes *	Otherwise it should be 0.
732135446Strhodes *
733135446Strhodes * Returns:
734170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
735170222Sdougb *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
736135446Strhodes */
737135446Strhodes
738165071Sdougbisc_result_t
739165071Sdougbdns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
740165071Sdougb		 dns_rdatatype_t type, dns_rdatatype_t covers,
741165071Sdougb		 dns_rdataset_t **rdataset);
742165071Sdougb/*%<
743165071Sdougb * Search the name for the specified rdclass and type.  If it is found,
744165071Sdougb * *rdataset is filled in with a pointer to that rdataset.
745165071Sdougb *
746165071Sdougb * Requires:
747165071Sdougb *\li	if '**rdataset' is non-NULL, *rdataset needs to be NULL.
748165071Sdougb *
749165071Sdougb *\li	'type' be a valid type, and NOT dns_rdatatype_any.
750165071Sdougb *
751165071Sdougb *\li	If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
752165071Sdougb *	Otherwise it should be 0.
753165071Sdougb *
754165071Sdougb * Returns:
755165071Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
756165071Sdougb *\li	#ISC_R_NOTFOUND		-- the desired type does not exist.
757165071Sdougb */
758165071Sdougb
759135446Strhodesvoid
760135446Strhodesdns_message_movename(dns_message_t *msg, dns_name_t *name,
761135446Strhodes		     dns_section_t fromsection,
762135446Strhodes		     dns_section_t tosection);
763170222Sdougb/*%<
764135446Strhodes * Move a name from one section to another.
765135446Strhodes *
766135446Strhodes * Requires:
767135446Strhodes *
768170222Sdougb *\li	'msg' be valid.
769135446Strhodes *
770170222Sdougb *\li	'name' must be a name already in 'fromsection'.
771135446Strhodes *
772170222Sdougb *\li	'fromsection' must be a valid section.
773135446Strhodes *
774170222Sdougb *\li	'tosection' must be a valid section.
775135446Strhodes */
776135446Strhodes
777135446Strhodesvoid
778135446Strhodesdns_message_addname(dns_message_t *msg, dns_name_t *name,
779135446Strhodes		    dns_section_t section);
780170222Sdougb/*%<
781135446Strhodes * Adds the name to the given section.
782135446Strhodes *
783135446Strhodes * It is the caller's responsibility to enforce any unique name requirements
784135446Strhodes * in a section.
785135446Strhodes *
786135446Strhodes * Requires:
787135446Strhodes *
788170222Sdougb *\li	'msg' be valid, and be a renderable message.
789135446Strhodes *
790170222Sdougb *\li	'name' be a valid absolute name.
791135446Strhodes *
792170222Sdougb *\li	'section' be a named section.
793135446Strhodes */
794135446Strhodes
795170222Sdougbvoid
796170222Sdougbdns_message_removename(dns_message_t *msg, dns_name_t *name,
797193149Sdougb		       dns_section_t section);
798170222Sdougb/*%<
799170222Sdougb * Remove a existing name from a given section.
800170222Sdougb *
801170222Sdougb * It is the caller's responsibility to ensure the name is part of the
802170222Sdougb * given section.
803170222Sdougb *
804170222Sdougb * Requires:
805170222Sdougb *
806170222Sdougb *\li	'msg' be valid, and be a renderable message.
807170222Sdougb *
808170222Sdougb *\li	'name' be a valid absolute name.
809170222Sdougb *
810170222Sdougb *\li	'section' be a named section.
811170222Sdougb */
812170222Sdougb
813170222Sdougb
814135446Strhodes/*
815135446Strhodes * LOANOUT FUNCTIONS
816135446Strhodes *
817135446Strhodes * Each of these functions loan a particular type of data to the caller.
818135446Strhodes * The storage for these will vanish when the message is destroyed or
819135446Strhodes * reset, and must NOT be used after these operations.
820135446Strhodes */
821135446Strhodes
822135446Strhodesisc_result_t
823135446Strhodesdns_message_gettempname(dns_message_t *msg, dns_name_t **item);
824170222Sdougb/*%<
825135446Strhodes * Return a name that can be used for any temporary purpose, including
826135446Strhodes * inserting into the message's linked lists.  The name must be returned
827135446Strhodes * to the message code using dns_message_puttempname() or inserted into
828135446Strhodes * one of the message's sections before the message is destroyed.
829135446Strhodes *
830135446Strhodes * It is the caller's responsibility to initialize this name.
831135446Strhodes *
832135446Strhodes * Requires:
833170222Sdougb *\li	msg be a valid message
834135446Strhodes *
835170222Sdougb *\li	item != NULL && *item == NULL
836135446Strhodes *
837135446Strhodes * Returns:
838170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
839170222Sdougb *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
840135446Strhodes */
841135446Strhodes
842135446Strhodesisc_result_t
843135446Strhodesdns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item);
844170222Sdougb/*%<
845135446Strhodes * Return an offsets array that can be used for any temporary purpose,
846135446Strhodes * such as attaching to a temporary name.  The offsets will be freed
847135446Strhodes * when the message is destroyed or reset.
848135446Strhodes *
849135446Strhodes * Requires:
850170222Sdougb *\li	msg be a valid message
851135446Strhodes *
852170222Sdougb *\li	item != NULL && *item == NULL
853135446Strhodes *
854135446Strhodes * Returns:
855170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
856170222Sdougb *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
857135446Strhodes */
858135446Strhodes
859135446Strhodesisc_result_t
860135446Strhodesdns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
861170222Sdougb/*%<
862135446Strhodes * Return a rdata that can be used for any temporary purpose, including
863135446Strhodes * inserting into the message's linked lists.  The rdata will be freed
864135446Strhodes * when the message is destroyed or reset.
865135446Strhodes *
866135446Strhodes * Requires:
867170222Sdougb *\li	msg be a valid message
868135446Strhodes *
869170222Sdougb *\li	item != NULL && *item == NULL
870135446Strhodes *
871135446Strhodes * Returns:
872170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
873170222Sdougb *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
874135446Strhodes */
875135446Strhodes
876135446Strhodesisc_result_t
877135446Strhodesdns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item);
878170222Sdougb/*%<
879135446Strhodes * Return a rdataset that can be used for any temporary purpose, including
880135446Strhodes * inserting into the message's linked lists. The name must be returned
881135446Strhodes * to the message code using dns_message_puttempname() or inserted into
882135446Strhodes * one of the message's sections before the message is destroyed.
883135446Strhodes *
884135446Strhodes * Requires:
885170222Sdougb *\li	msg be a valid message
886135446Strhodes *
887170222Sdougb *\li	item != NULL && *item == NULL
888135446Strhodes *
889135446Strhodes * Returns:
890170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
891170222Sdougb *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
892135446Strhodes */
893135446Strhodes
894135446Strhodesisc_result_t
895135446Strhodesdns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
896170222Sdougb/*%<
897135446Strhodes * Return a rdatalist that can be used for any temporary purpose, including
898135446Strhodes * inserting into the message's linked lists.  The rdatalist will be
899135446Strhodes * destroyed when the message is destroyed or reset.
900135446Strhodes *
901135446Strhodes * Requires:
902170222Sdougb *\li	msg be a valid message
903135446Strhodes *
904170222Sdougb *\li	item != NULL && *item == NULL
905135446Strhodes *
906135446Strhodes * Returns:
907170222Sdougb *\li	#ISC_R_SUCCESS		-- All is well.
908170222Sdougb *\li	#ISC_R_NOMEMORY		-- No item can be allocated.
909135446Strhodes */
910135446Strhodes
911135446Strhodesvoid
912135446Strhodesdns_message_puttempname(dns_message_t *msg, dns_name_t **item);
913170222Sdougb/*%<
914135446Strhodes * Return a borrowed name to the message's name free list.
915135446Strhodes *
916135446Strhodes * Requires:
917170222Sdougb *\li	msg be a valid message
918135446Strhodes *
919170222Sdougb *\li	item != NULL && *item point to a name returned by
920135446Strhodes *	dns_message_gettempname()
921135446Strhodes *
922135446Strhodes * Ensures:
923170222Sdougb *\li	*item == NULL
924135446Strhodes */
925135446Strhodes
926135446Strhodesvoid
927135446Strhodesdns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item);
928170222Sdougb/*%<
929135446Strhodes * Return a borrowed rdata to the message's rdata free list.
930135446Strhodes *
931135446Strhodes * Requires:
932170222Sdougb *\li	msg be a valid message
933135446Strhodes *
934170222Sdougb *\li	item != NULL && *item point to a rdata returned by
935135446Strhodes *	dns_message_gettemprdata()
936135446Strhodes *
937135446Strhodes * Ensures:
938170222Sdougb *\li	*item == NULL
939135446Strhodes */
940135446Strhodes
941135446Strhodesvoid
942135446Strhodesdns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item);
943170222Sdougb/*%<
944135446Strhodes * Return a borrowed rdataset to the message's rdataset free list.
945135446Strhodes *
946135446Strhodes * Requires:
947170222Sdougb *\li	msg be a valid message
948135446Strhodes *
949170222Sdougb *\li	item != NULL && *item point to a rdataset returned by
950135446Strhodes *	dns_message_gettemprdataset()
951135446Strhodes *
952135446Strhodes * Ensures:
953170222Sdougb *\li	*item == NULL
954135446Strhodes */
955135446Strhodes
956135446Strhodesvoid
957135446Strhodesdns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
958170222Sdougb/*%<
959135446Strhodes * Return a borrowed rdatalist to the message's rdatalist free list.
960135446Strhodes *
961135446Strhodes * Requires:
962170222Sdougb *\li	msg be a valid message
963135446Strhodes *
964170222Sdougb *\li	item != NULL && *item point to a rdatalist returned by
965135446Strhodes *	dns_message_gettemprdatalist()
966135446Strhodes *
967135446Strhodes * Ensures:
968170222Sdougb *\li	*item == NULL
969135446Strhodes */
970135446Strhodes
971135446Strhodesisc_result_t
972135446Strhodesdns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
973135446Strhodes		       unsigned int *flagsp);
974170222Sdougb/*%<
975135446Strhodes * Assume the remaining region of "source" is a DNS message.  Peek into
976135446Strhodes * it and fill in "*idp" with the message id, and "*flagsp" with the flags.
977135446Strhodes *
978135446Strhodes * Requires:
979135446Strhodes *
980170222Sdougb *\li	source != NULL
981135446Strhodes *
982135446Strhodes * Ensures:
983135446Strhodes *
984170222Sdougb *\li	if (idp != NULL) *idp == message id.
985135446Strhodes *
986170222Sdougb *\li	if (flagsp != NULL) *flagsp == message flags.
987135446Strhodes *
988135446Strhodes * Returns:
989135446Strhodes *
990170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
991135446Strhodes *
992170222Sdougb *\li	#ISC_R_UNEXPECTEDEND	-- buffer doesn't contain enough for a header.
993135446Strhodes */
994135446Strhodes
995135446Strhodesisc_result_t
996135446Strhodesdns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section);
997170222Sdougb/*%<
998135446Strhodes * Start formatting a reply to the query in 'msg'.
999135446Strhodes *
1000135446Strhodes * Requires:
1001135446Strhodes *
1002170222Sdougb *\li	'msg' is a valid message with parsing intent, and contains a query.
1003135446Strhodes *
1004135446Strhodes * Ensures:
1005135446Strhodes *
1006170222Sdougb *\li	The message will have a rendering intent.  If 'want_question_section'
1007135446Strhodes *	is true, the message opcode is query or notify, and the question
1008135446Strhodes *	section is present and properly formatted, then the question section
1009135446Strhodes *	will be included in the reply.  All other sections will be cleared.
1010135446Strhodes *	The QR flag will be set, the RD flag will be preserved, and all other
1011135446Strhodes *	flags will be cleared.
1012135446Strhodes *
1013135446Strhodes * Returns:
1014135446Strhodes *
1015170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
1016135446Strhodes *
1017170222Sdougb *\li	#DNS_R_FORMERR		-- the header or question section of the
1018135446Strhodes *				   message is invalid, replying is impossible.
1019135446Strhodes *				   If DNS_R_FORMERR is returned when
1020135446Strhodes *				   want_question_section is ISC_FALSE, then
1021135446Strhodes *				   it's the header section that's bad;
1022135446Strhodes *				   otherwise either of the header or question
1023135446Strhodes *				   sections may be bad.
1024135446Strhodes */
1025135446Strhodes
1026135446Strhodesdns_rdataset_t *
1027135446Strhodesdns_message_getopt(dns_message_t *msg);
1028170222Sdougb/*%<
1029135446Strhodes * Get the OPT record for 'msg'.
1030135446Strhodes *
1031135446Strhodes * Requires:
1032135446Strhodes *
1033170222Sdougb *\li	'msg' is a valid message.
1034135446Strhodes *
1035135446Strhodes * Returns:
1036135446Strhodes *
1037170222Sdougb *\li	The OPT rdataset of 'msg', or NULL if there isn't one.
1038135446Strhodes */
1039135446Strhodes
1040135446Strhodesisc_result_t
1041135446Strhodesdns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
1042170222Sdougb/*%<
1043135446Strhodes * Set the OPT record for 'msg'.
1044135446Strhodes *
1045135446Strhodes * Requires:
1046135446Strhodes *
1047170222Sdougb *\li	'msg' is a valid message with rendering intent
1048135446Strhodes *	and no sections have been rendered.
1049135446Strhodes *
1050170222Sdougb *\li	'opt' is a valid OPT record.
1051135446Strhodes *
1052135446Strhodes * Ensures:
1053135446Strhodes *
1054170222Sdougb *\li	The OPT record has either been freed or ownership of it has
1055135446Strhodes *	been transferred to the message.
1056135446Strhodes *
1057193149Sdougb *\li	If ISC_R_SUCCESS was returned, the OPT record will be rendered
1058135446Strhodes *	when dns_message_renderend() is called.
1059135446Strhodes *
1060135446Strhodes * Returns:
1061135446Strhodes *
1062170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
1063135446Strhodes *
1064170222Sdougb *\li	#ISC_R_NOSPACE		-- there is no space for the OPT record.
1065135446Strhodes */
1066135446Strhodes
1067135446Strhodesdns_rdataset_t *
1068135446Strhodesdns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
1069170222Sdougb/*%<
1070135446Strhodes * Get the TSIG record and owner for 'msg'.
1071135446Strhodes *
1072135446Strhodes * Requires:
1073135446Strhodes *
1074170222Sdougb *\li	'msg' is a valid message.
1075170222Sdougb *\li	'owner' is NULL or *owner is NULL.
1076135446Strhodes *
1077135446Strhodes * Returns:
1078135446Strhodes *
1079170222Sdougb *\li	The TSIG rdataset of 'msg', or NULL if there isn't one.
1080135446Strhodes *
1081135446Strhodes * Ensures:
1082135446Strhodes *
1083170222Sdougb * \li	If 'owner' is not NULL, it will point to the owner name.
1084135446Strhodes */
1085135446Strhodes
1086135446Strhodesisc_result_t
1087135446Strhodesdns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
1088170222Sdougb/*%<
1089135446Strhodes * Set the tsig key for 'msg'.  This is only necessary for when rendering a
1090135446Strhodes * query or parsing a response.  The key (if non-NULL) is attached to, and
1091135446Strhodes * will be detached when the message is destroyed.
1092135446Strhodes *
1093135446Strhodes * Requires:
1094135446Strhodes *
1095170222Sdougb *\li	'msg' is a valid message with rendering intent,
1096135446Strhodes *	dns_message_renderbegin() has been called, and no sections have been
1097135446Strhodes *	rendered.
1098170222Sdougb *\li	'key' is a valid tsig key or NULL.
1099135446Strhodes *
1100135446Strhodes * Returns:
1101135446Strhodes *
1102170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
1103135446Strhodes *
1104170222Sdougb *\li	#ISC_R_NOSPACE		-- there is no space for the TSIG record.
1105135446Strhodes */
1106135446Strhodes
1107135446Strhodesdns_tsigkey_t *
1108135446Strhodesdns_message_gettsigkey(dns_message_t *msg);
1109170222Sdougb/*%<
1110135446Strhodes * Gets the tsig key for 'msg'.
1111135446Strhodes *
1112135446Strhodes * Requires:
1113135446Strhodes *
1114170222Sdougb *\li	'msg' is a valid message
1115135446Strhodes */
1116135446Strhodes
1117135446Strhodesisc_result_t
1118135446Strhodesdns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
1119170222Sdougb/*%<
1120135446Strhodes * Indicates that 'querytsig' is the TSIG from the signed query for which
1121135446Strhodes * 'msg' is the response.  This is also used for chained TSIGs in TCP
1122135446Strhodes * responses.
1123135446Strhodes *
1124135446Strhodes * Requires:
1125135446Strhodes *
1126170222Sdougb *\li	'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
1127135446Strhodes *	or NULL
1128135446Strhodes *
1129170222Sdougb *\li	'msg' is a valid message
1130135446Strhodes *
1131135446Strhodes * Returns:
1132135446Strhodes *
1133170222Sdougb *\li	#ISC_R_SUCCESS
1134170222Sdougb *\li	#ISC_R_NOMEMORY
1135135446Strhodes */
1136135446Strhodes
1137135446Strhodesisc_result_t
1138135446Strhodesdns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
1139135446Strhodes			 isc_buffer_t **querytsig);
1140170222Sdougb/*%<
1141135446Strhodes * Gets the tsig from the TSIG from the signed query 'msg'.  This is also used
1142135446Strhodes * for chained TSIGs in TCP responses.  Unlike dns_message_gettsig, this makes
1143135446Strhodes * a copy of the data, so can be used if the message is destroyed.
1144135446Strhodes *
1145135446Strhodes * Requires:
1146135446Strhodes *
1147170222Sdougb *\li	'msg' is a valid signed message
1148170222Sdougb *\li	'mctx' is a valid memory context
1149170222Sdougb *\li	querytsig != NULL && *querytsig == NULL
1150135446Strhodes *
1151135446Strhodes * Returns:
1152135446Strhodes *
1153170222Sdougb *\li	#ISC_R_SUCCESS
1154170222Sdougb *\li	#ISC_R_NOMEMORY
1155135446Strhodes *
1156135446Strhodes * Ensures:
1157170222Sdougb *\li 	'tsig' points to NULL or an allocated buffer which must be freed
1158135446Strhodes * 	by the caller.
1159135446Strhodes */
1160135446Strhodes
1161135446Strhodesdns_rdataset_t *
1162135446Strhodesdns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
1163170222Sdougb/*%<
1164135446Strhodes * Get the SIG(0) record and owner for 'msg'.
1165135446Strhodes *
1166135446Strhodes * Requires:
1167135446Strhodes *
1168170222Sdougb *\li	'msg' is a valid message.
1169170222Sdougb *\li	'owner' is NULL or *owner is NULL.
1170135446Strhodes *
1171135446Strhodes * Returns:
1172135446Strhodes *
1173170222Sdougb *\li	The SIG(0) rdataset of 'msg', or NULL if there isn't one.
1174135446Strhodes *
1175135446Strhodes * Ensures:
1176135446Strhodes *
1177170222Sdougb * \li	If 'owner' is not NULL, it will point to the owner name.
1178135446Strhodes */
1179135446Strhodes
1180135446Strhodesisc_result_t
1181135446Strhodesdns_message_setsig0key(dns_message_t *msg, dst_key_t *key);
1182170222Sdougb/*%<
1183135446Strhodes * Set the SIG(0) key for 'msg'.
1184135446Strhodes *
1185135446Strhodes * Requires:
1186135446Strhodes *
1187170222Sdougb *\li	'msg' is a valid message with rendering intent,
1188135446Strhodes *	dns_message_renderbegin() has been called, and no sections have been
1189135446Strhodes *	rendered.
1190170222Sdougb *\li	'key' is a valid sig key or NULL.
1191135446Strhodes *
1192135446Strhodes * Returns:
1193135446Strhodes *
1194170222Sdougb *\li	#ISC_R_SUCCESS		-- all is well.
1195135446Strhodes *
1196170222Sdougb *\li	#ISC_R_NOSPACE		-- there is no space for the SIG(0) record.
1197135446Strhodes */
1198135446Strhodes
1199135446Strhodesdst_key_t *
1200135446Strhodesdns_message_getsig0key(dns_message_t *msg);
1201170222Sdougb/*%<
1202135446Strhodes * Gets the SIG(0) key for 'msg'.
1203135446Strhodes *
1204135446Strhodes * Requires:
1205135446Strhodes *
1206170222Sdougb *\li	'msg' is a valid message
1207135446Strhodes */
1208135446Strhodes
1209135446Strhodesvoid
1210135446Strhodesdns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
1211170222Sdougb/*%<
1212135446Strhodes * Give the *buffer to the message code to clean up when it is no
1213135446Strhodes * longer needed.  This is usually when the message is reset or
1214135446Strhodes * destroyed.
1215135446Strhodes *
1216135446Strhodes * Requires:
1217135446Strhodes *
1218170222Sdougb *\li	msg be a valid message.
1219135446Strhodes *
1220170222Sdougb *\li	buffer != NULL && *buffer is a valid isc_buffer_t, which was
1221193149Sdougb *	dynamically allocated via isc_buffer_allocate().
1222135446Strhodes */
1223135446Strhodes
1224135446Strhodesisc_result_t
1225135446Strhodesdns_message_signer(dns_message_t *msg, dns_name_t *signer);
1226170222Sdougb/*%<
1227135446Strhodes * If this message was signed, return the identity of the signer.
1228135446Strhodes * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the
1229135446Strhodes * key that signed the message.
1230135446Strhodes *
1231135446Strhodes * Requires:
1232135446Strhodes *
1233170222Sdougb *\li	msg is a valid parsed message.
1234170222Sdougb *\li	signer is a valid name
1235135446Strhodes *
1236135446Strhodes * Returns:
1237135446Strhodes *
1238170222Sdougb *\li	#ISC_R_SUCCESS		- the message was signed, and *signer
1239135446Strhodes *				  contains the signing identity
1240135446Strhodes *
1241170222Sdougb *\li	#ISC_R_NOTFOUND		- no TSIG or SIG(0) record is present in the
1242135446Strhodes *				  message
1243135446Strhodes *
1244170222Sdougb *\li	#DNS_R_TSIGVERIFYFAILURE	- the message was signed by a TSIG, but the
1245135446Strhodes *				  signature failed to verify
1246135446Strhodes *
1247170222Sdougb *\li	#DNS_R_TSIGERRORSET	- the message was signed by a TSIG and
1248135446Strhodes *				  verified, but the query was rejected by
1249135446Strhodes *				  the server
1250135446Strhodes *
1251170222Sdougb *\li	#DNS_R_NOIDENTITY	- the message was signed by a TSIG and
1252135446Strhodes *				  verified, but the key has no identity since
1253135446Strhodes *				  it was generated by an unsigned TKEY process
1254135446Strhodes *
1255170222Sdougb *\li	#DNS_R_SIGINVALID	- the message was signed by a SIG(0), but
1256135446Strhodes *				  the signature failed to verify
1257135446Strhodes *
1258170222Sdougb *\li	#DNS_R_NOTVERIFIEDYET	- the message was signed by a TSIG or SIG(0),
1259135446Strhodes *				  but the signature has not been verified yet
1260135446Strhodes */
1261135446Strhodes
1262135446Strhodesisc_result_t
1263135446Strhodesdns_message_checksig(dns_message_t *msg, dns_view_t *view);
1264170222Sdougb/*%<
1265135446Strhodes * If this message was signed, verify the signature.
1266135446Strhodes *
1267135446Strhodes * Requires:
1268135446Strhodes *
1269170222Sdougb *\li	msg is a valid parsed message.
1270170222Sdougb *\li	view is a valid view or NULL
1271135446Strhodes *
1272135446Strhodes * Returns:
1273135446Strhodes *
1274170222Sdougb *\li	#ISC_R_SUCCESS		- the message was unsigned, or the message
1275135446Strhodes *				  was signed correctly.
1276135446Strhodes *
1277170222Sdougb *\li	#DNS_R_EXPECTEDTSIG	- A TSIG was expected, but not seen
1278170222Sdougb *\li	#DNS_R_UNEXPECTEDTSIG	- A TSIG was seen but not expected
1279170222Sdougb *\li	#DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
1280135446Strhodes */
1281135446Strhodes
1282135446Strhodesisc_result_t
1283135446Strhodesdns_message_rechecksig(dns_message_t *msg, dns_view_t *view);
1284170222Sdougb/*%<
1285135446Strhodes * Reset the signature state and then if the message was signed,
1286135446Strhodes * verify the message.
1287135446Strhodes *
1288135446Strhodes * Requires:
1289135446Strhodes *
1290170222Sdougb *\li	msg is a valid parsed message.
1291170222Sdougb *\li	view is a valid view or NULL
1292135446Strhodes *
1293135446Strhodes * Returns:
1294135446Strhodes *
1295170222Sdougb *\li	#ISC_R_SUCCESS		- the message was unsigned, or the message
1296135446Strhodes *				  was signed correctly.
1297135446Strhodes *
1298170222Sdougb *\li	#DNS_R_EXPECTEDTSIG	- A TSIG was expected, but not seen
1299170222Sdougb *\li	#DNS_R_UNEXPECTEDTSIG	- A TSIG was seen but not expected
1300170222Sdougb *\li	#DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
1301135446Strhodes */
1302135446Strhodes
1303135446Strhodesvoid
1304135446Strhodesdns_message_resetsig(dns_message_t *msg);
1305170222Sdougb/*%<
1306135446Strhodes * Reset the signature state.
1307135446Strhodes *
1308135446Strhodes * Requires:
1309170222Sdougb *\li	'msg' is a valid parsed message.
1310135446Strhodes */
1311135446Strhodes
1312135446Strhodesisc_region_t *
1313135446Strhodesdns_message_getrawmessage(dns_message_t *msg);
1314170222Sdougb/*%<
1315135446Strhodes * Retrieve the raw message in compressed wire format.  The message must
1316135446Strhodes * have been successfully parsed for it to have been saved.
1317135446Strhodes *
1318135446Strhodes * Requires:
1319170222Sdougb *\li	msg is a valid parsed message.
1320135446Strhodes *
1321135446Strhodes * Returns:
1322170222Sdougb *\li	NULL	if there is no saved message.
1323135446Strhodes *	a pointer to a region which refers the dns message.
1324135446Strhodes */
1325135446Strhodes
1326135446Strhodesvoid
1327135446Strhodesdns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
1328165071Sdougb			 const void *order_arg);
1329170222Sdougb/*%<
1330135446Strhodes * Define the order in which RR sets get rendered by
1331135446Strhodes * dns_message_rendersection() to be the ascending order
1332135446Strhodes * defined by the integer value returned by 'order' when
1333135446Strhodes * given each RR and 'arg' as arguments.  If 'order' and
1334135446Strhodes * 'order_arg' are NULL, a default order is used.
1335135446Strhodes *
1336135446Strhodes * Requires:
1337170222Sdougb *\li	msg be a valid message.
1338170222Sdougb *\li	order_arg is NULL if and only if order is NULL.
1339135446Strhodes */
1340135446Strhodes
1341193149Sdougbvoid
1342135446Strhodesdns_message_settimeadjust(dns_message_t *msg, int timeadjust);
1343170222Sdougb/*%<
1344135446Strhodes * Adjust the time used to sign/verify a message by timeadjust.
1345135446Strhodes * Currently only TSIG.
1346135446Strhodes *
1347135446Strhodes * Requires:
1348170222Sdougb *\li	msg be a valid message.
1349135446Strhodes */
1350135446Strhodes
1351193149Sdougbint
1352135446Strhodesdns_message_gettimeadjust(dns_message_t *msg);
1353170222Sdougb/*%<
1354135446Strhodes * Return the current time adjustment.
1355135446Strhodes *
1356135446Strhodes * Requires:
1357170222Sdougb *\li	msg be a valid message.
1358135446Strhodes */
1359135446Strhodes
1360254402Serwinisc_result_t
1361254402Serwindns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt,
1362254402Serwin		     unsigned int version, isc_uint16_t udpsize,
1363254402Serwin		     unsigned int flags, dns_ednsopt_t *ednsopts, size_t count);
1364254402Serwin/*%<
1365254402Serwin * Built a opt record.
1366254402Serwin *
1367254402Serwin * Requires:
1368254402Serwin * \li   msg be a valid message.
1369254402Serwin * \li   opt to be a non NULL and *opt to be NULL.
1370254402Serwin *
1371254402Serwin * Returns:
1372254402Serwin * \li	 ISC_R_SUCCESS on success.
1373254402Serwin * \li	 ISC_R_NOMEMORY
1374254402Serwin * \li	 ISC_R_NOSPACE
1375254402Serwin * \li	 other.
1376254402Serwin */
1377254402Serwin
1378292321Sdelphijvoid
1379292321Sdelphijdns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass);
1380292321Sdelphij/*%<
1381292321Sdelphij * Set the expected class of records in the response.
1382292321Sdelphij *
1383292321Sdelphij * Requires:
1384292321Sdelphij * \li   msg be a valid message with parsing intent.
1385292321Sdelphij */
1386292321Sdelphij
1387135446StrhodesISC_LANG_ENDDECLS
1388135446Strhodes
1389135446Strhodes#endif /* DNS_MESSAGE_H */
1390