Merge from vendor branch OPENSSL:
[dragonfly.git] / contrib / bind-9.3 / lib / dns / include / dns / message.h
1 /*
2  * Copyright (C) 2004, 2006  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: message.h,v 1.100.2.3.8.10 2006/02/28 06:32:54 marka Exp $ */
19
20 #ifndef DNS_MESSAGE_H
21 #define DNS_MESSAGE_H 1
22
23 /***
24  ***    Imports
25  ***/
26
27 #include <isc/lang.h>
28 #include <isc/magic.h>
29
30 #include <dns/compress.h>
31 #include <dns/masterdump.h>
32 #include <dns/types.h>
33
34 #include <dst/dst.h>
35
36 /*
37  * How this beast works:
38  *
39  * When a dns message is received in a buffer, dns_message_fromwire() is called
40  * on the memory region.  Various items are checked including the format
41  * of the message (if counts are right, if counts consume the entire sections,
42  * and if sections consume the entire message) and known pseudo-RRs in the
43  * additional data section are analyzed and removed.
44  *
45  * TSIG checking is also done at this layer, and any DNSSEC transaction
46  * signatures should also be checked here.
47  *
48  * Notes on using the gettemp*() and puttemp*() functions:
49  *
50  * These functions return items (names, rdatasets, etc) allocated from some
51  * internal state of the dns_message_t.
52  *
53  * Names and rdatasets must be put back into the dns_message_t in
54  * one of two ways.  Assume a name was allocated via
55  * dns_message_gettempname():
56  *
57  *      (1) insert it into a section, using dns_message_addname().
58  *
59  *      (2) return it to the message using dns_message_puttempname().
60  *
61  * The same applies to rdatasets.
62  *
63  * On the other hand, offsets, rdatalists and rdatas allocated using
64  * dns_message_gettemp*() will always be freed automatically
65  * when the message is reset or destroyed; calling dns_message_puttemp*()
66  * on rdatalists and rdatas is optional and serves only to enable the item
67  * to be reused multiple times during the lifetime of the message; offsets
68  * cannot be reused.
69  *
70  * Buffers allocated using isc_buffer_allocate() can be automatically freed
71  * as well by giving the buffer to the message using dns_message_takebuffer().
72  * Doing this will cause the buffer to be freed using isc_buffer_free()
73  * when the section lists are cleared, such as in a reset or in a destroy.
74  * Since the buffer itself exists until the message is destroyed, this sort
75  * of code can be written:
76  *
77  *      buffer = isc_buffer_allocate(mctx, 512);
78  *      name = NULL;
79  *      name = dns_message_gettempname(message, &name);
80  *      dns_name_init(name, NULL);
81  *      result = dns_name_fromtext(name, &source, dns_rootname, ISC_FALSE,
82  *                                 buffer);
83  *      dns_message_takebuffer(message, &buffer);
84  *
85  *
86  * TODO:
87  *
88  * XXX Needed:  ways to set and retrieve EDNS information, add rdata to a
89  * section, move rdata from one section to another, remove rdata, etc.
90  */
91
92 #define DNS_MESSAGEFLAG_QR              0x8000U
93 #define DNS_MESSAGEFLAG_AA              0x0400U
94 #define DNS_MESSAGEFLAG_TC              0x0200U
95 #define DNS_MESSAGEFLAG_RD              0x0100U
96 #define DNS_MESSAGEFLAG_RA              0x0080U
97 #define DNS_MESSAGEFLAG_AD              0x0020U
98 #define DNS_MESSAGEFLAG_CD              0x0010U
99
100 #define DNS_MESSAGEEXTFLAG_DO           0x8000U
101
102 #define DNS_MESSAGE_REPLYPRESERVE       (DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD)
103 #define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
104
105 #define DNS_MESSAGE_HEADERLEN           12 /* 6 isc_uint16_t's */
106
107 #define DNS_MESSAGE_MAGIC               ISC_MAGIC('M','S','G','@')
108 #define DNS_MESSAGE_VALID(msg)          ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC)
109
110 /*
111  * Ordering here matters.  DNS_SECTION_ANY must be the lowest and negative,
112  * and DNS_SECTION_MAX must be one greater than the last used section.
113  */
114 typedef int dns_section_t;
115 #define DNS_SECTION_ANY                 (-1)
116 #define DNS_SECTION_QUESTION            0
117 #define DNS_SECTION_ANSWER              1
118 #define DNS_SECTION_AUTHORITY           2
119 #define DNS_SECTION_ADDITIONAL          3
120 #define DNS_SECTION_MAX                 4
121
122 typedef int dns_pseudosection_t;
123 #define DNS_PSEUDOSECTION_ANY           (-1)
124 #define DNS_PSEUDOSECTION_OPT           0
125 #define DNS_PSEUDOSECTION_TSIG          1
126 #define DNS_PSEUDOSECTION_SIG0          2
127 #define DNS_PSEUDOSECTION_MAX           3
128
129 typedef int dns_messagetextflag_t;
130 #define DNS_MESSAGETEXTFLAG_NOCOMMENTS  0x0001
131 #define DNS_MESSAGETEXTFLAG_NOHEADERS   0x0002
132
133 /*
134  * Dynamic update names for these sections.
135  */
136 #define DNS_SECTION_ZONE                DNS_SECTION_QUESTION
137 #define DNS_SECTION_PREREQUISITE        DNS_SECTION_ANSWER
138 #define DNS_SECTION_UPDATE              DNS_SECTION_AUTHORITY
139
140 /*
141  * These tell the message library how the created dns_message_t will be used.
142  */
143 #define DNS_MESSAGE_INTENTUNKNOWN       0 /* internal use only */
144 #define DNS_MESSAGE_INTENTPARSE         1 /* parsing messages */
145 #define DNS_MESSAGE_INTENTRENDER        2 /* rendering */
146
147 /*
148  * Control behavior of parsing
149  */
150 #define DNS_MESSAGEPARSE_PRESERVEORDER  0x0001  /* preserve rdata order */
151 #define DNS_MESSAGEPARSE_BESTEFFORT     0x0002  /* return a message if a
152                                                    recoverable parse error
153                                                    occurs */
154 #define DNS_MESSAGEPARSE_CLONEBUFFER    0x0004  /* save a copy of the
155                                                    source buffer */
156 #define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /* trucation errors are
157                                                   * not fatal. */
158
159 /*
160  * Control behavior of rendering
161  */
162 #define DNS_MESSAGERENDER_ORDERED       0x0001  /* don't change order */
163 #define DNS_MESSAGERENDER_PARTIAL       0x0002  /* allow a partial rdataset */
164 #define DNS_MESSAGERENDER_OMITDNSSEC    0x0004  /* omit DNSSEC records */
165 #define DNS_MESSAGERENDER_PREFER_A      0x0008  /* prefer A records in
166                                                  * additional section. */
167 #define DNS_MESSAGERENDER_PREFER_AAAA   0x0010  /* prefer AAAA records in
168                                                  * additional section. */
169
170 typedef struct dns_msgblock dns_msgblock_t;
171
172 struct dns_message {
173         /* public from here down */
174         unsigned int                    magic;
175
176         dns_messageid_t                 id;
177         unsigned int                    flags;
178         dns_rcode_t                     rcode;
179         unsigned int                    opcode;
180         dns_rdataclass_t                rdclass;
181
182         /* 4 real, 1 pseudo */
183         unsigned int                    counts[DNS_SECTION_MAX];
184
185         /* private from here down */
186         dns_namelist_t                  sections[DNS_SECTION_MAX];
187         dns_name_t                     *cursors[DNS_SECTION_MAX];
188         dns_rdataset_t                 *opt;
189         dns_rdataset_t                 *sig0;
190         dns_rdataset_t                 *tsig;
191
192         int                             state;
193         unsigned int                    from_to_wire : 2;
194         unsigned int                    header_ok : 1;
195         unsigned int                    question_ok : 1;
196         unsigned int                    tcp_continuation : 1;
197         unsigned int                    verified_sig : 1;
198         unsigned int                    verify_attempted : 1;
199         unsigned int                    free_query : 1;
200         unsigned int                    free_saved : 1;
201
202         unsigned int                    opt_reserved;
203         unsigned int                    sig_reserved;
204         unsigned int                    reserved; /* reserved space (render) */
205
206         isc_buffer_t                   *buffer;
207         dns_compress_t                 *cctx;
208
209         isc_mem_t                      *mctx;
210         isc_mempool_t                  *namepool;
211         isc_mempool_t                  *rdspool;
212
213         isc_bufferlist_t                scratchpad;
214         isc_bufferlist_t                cleanup;
215
216         ISC_LIST(dns_msgblock_t)        rdatas;
217         ISC_LIST(dns_msgblock_t)        rdatalists;
218         ISC_LIST(dns_msgblock_t)        offsets;
219
220         ISC_LIST(dns_rdata_t)           freerdata;
221         ISC_LIST(dns_rdatalist_t)       freerdatalist;
222
223         dns_rcode_t                     tsigstatus;
224         dns_rcode_t                     querytsigstatus;
225         dns_name_t                     *tsigname; /* Owner name of TSIG, if any */
226         dns_rdataset_t                 *querytsig;
227         dns_tsigkey_t                  *tsigkey;
228         dst_context_t                  *tsigctx;
229         int                             sigstart;
230         int                             timeadjust;
231
232         dns_name_t                     *sig0name; /* Owner name of SIG0, if any */
233         dst_key_t                      *sig0key;
234         dns_rcode_t                     sig0status;
235         isc_region_t                    query;
236         isc_region_t                    saved;
237
238         dns_rdatasetorderfunc_t         order;
239         const void *                    order_arg;
240 };
241
242 /***
243  *** Functions
244  ***/
245
246 ISC_LANG_BEGINDECLS
247
248 isc_result_t
249 dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp);
250
251 /*
252  * Create msg structure.
253  *
254  * This function will allocate some internal blocks of memory that are
255  * expected to be needed for parsing or rendering nearly any type of message.
256  *
257  * Requires:
258  *      'mctx' be a valid memory context.
259  *
260  *      'msgp' be non-null and '*msg' be NULL.
261  *
262  *      'intent' must be one of DNS_MESSAGE_INTENTPARSE or
263  *      DNS_MESSAGE_INTENTRENDER.
264  *
265  * Ensures:
266  *      The data in "*msg" is set to indicate an unused and empty msg
267  *      structure.
268  *
269  * Returns:
270  *      ISC_R_NOMEMORY          -- out of memory
271  *      ISC_R_SUCCESS           -- success
272  */
273
274 void
275 dns_message_reset(dns_message_t *msg, unsigned int intent);
276 /*
277  * Reset a message structure to default state.  All internal lists are freed
278  * or reset to a default state as well.  This is simply a more efficient
279  * way to call dns_message_destroy() followed by dns_message_allocate(),
280  * since it avoid many memory allocations.
281  *
282  * If any data loanouts (buffers, names, rdatas, etc) were requested,
283  * the caller must no longer use them after this call.
284  *
285  * The intended next use of the message will be 'intent'.
286  *
287  * Requires:
288  *
289  *      'msg' be valid.
290  *
291  *      'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER
292  */
293
294 void
295 dns_message_destroy(dns_message_t **msgp);
296 /*
297  * Destroy all state in the message.
298  *
299  * Requires:
300  *
301  *      'msgp' be valid.
302  *
303  * Ensures:
304  *      '*msgp' == NULL
305  */
306
307 isc_result_t
308 dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
309                           const dns_master_style_t *style,
310                           dns_messagetextflag_t flags,
311                           isc_buffer_t *target);
312
313 isc_result_t
314 dns_message_pseudosectiontotext(dns_message_t *msg,
315                                 dns_pseudosection_t section,
316                                 const dns_master_style_t *style,
317                                 dns_messagetextflag_t flags,
318                                 isc_buffer_t *target);
319 /*
320  * Convert section 'section' or 'pseudosection' of message 'msg' to
321  * a cleartext representation
322  *
323  * Notes:
324  *      See dns_message_totext for meanings of flags.
325  *
326  * Requires:
327  *
328  *      'msg' is a valid message.
329  *
330  *      'style' is a valid master dump style.
331  *
332  *      'target' is a valid buffer.
333  *
334  *      'section' is a valid section label.
335  *
336  * Ensures:
337  *
338  *      If the result is success:
339  *
340  *              The used space in 'target' is updated.
341  *
342  * Returns:
343  *
344  *      ISC_R_SUCCESS
345  *      ISC_R_NOSPACE
346  *      ISC_R_NOMORE
347  *
348  *      Note: On error return, *target may be partially filled with data.
349 */
350
351 isc_result_t
352 dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
353                    dns_messagetextflag_t flags, isc_buffer_t *target);
354 /*
355  * Convert all sections of message 'msg' to a cleartext representation
356  *
357  * Notes:
358  *      In flags, If DNS_MESSAGETEXTFLAG_OMITDOT is set, then the
359  *      final '.' in absolute names will not be emitted.  If
360  *      DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning
361  *      with ";;" will be emitted indicating section name.  If
362  *      DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will
363  *      be emitted.
364  *
365  * Requires:
366  *
367  *      'msg' is a valid message.
368  *
369  *      'style' is a valid master dump style.
370  *
371  *      'target' is a valid buffer.
372  *
373  * Ensures:
374  *
375  *      If the result is success:
376  *
377  *              The used space in 'target' is updated.
378  *
379  * Returns:
380  *
381  *      ISC_R_SUCCESS
382  *      ISC_R_NOSPACE
383  *      ISC_R_NOMORE
384  *
385  *      Note: On error return, *target may be partially filled with data.
386  */
387
388 isc_result_t
389 dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
390                   unsigned int options);
391 /*
392  * Parse raw wire data in 'source' as a DNS message.
393  *
394  * OPT records are detected and stored in the pseudo-section "opt".
395  * TSIGs are detected and stored in the pseudo-section "tsig".
396  *
397  * If DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message
398  * is UPDATE, a separate dns_name_t object will be created for each RR in the
399  * message.  Each such dns_name_t will have a single rdataset containing the
400  * single RR, and the order of the RRs in the message is preserved.
401  * Otherwise, only one dns_name_t object will be created for each unique
402  * owner name in the section, and each such dns_name_t will have a list
403  * of rdatasets.  To access the names and their data, use
404  * dns_message_firstname() and dns_message_nextname().
405  *
406  * If DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
407  * not be considered FORMERRs.  If the entire message can be parsed, it
408  * will be returned and DNS_R_RECOVERABLE will be returned.
409  *
410  * If DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
411  * RR's as possible, DNS_R_RECOVERABLE will be returned.
412  *
413  * OPT and TSIG records are always handled specially, regardless of the
414  * 'preserve_order' setting.
415  *
416  * Requires:
417  *      "msg" be valid.
418  *
419  *      "buffer" be a wire format buffer.
420  *
421  * Ensures:
422  *      The buffer's data format is correct.
423  *
424  *      The buffer's contents verify as correct regarding header bits, buffer
425  *      and rdata sizes, etc.
426  *
427  * Returns:
428  *      ISC_R_SUCCESS           -- all is well
429  *      ISC_R_NOMEMORY          -- no memory
430  *      DNS_R_RECOVERABLE       -- the message parsed properly, but contained
431  *                                 errors.
432  *      Many other errors possible XXXMLG
433  */
434
435 isc_result_t
436 dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
437                         isc_buffer_t *buffer);
438 /*
439  * Begin rendering on a message.  Only one call can be made to this function
440  * per message.
441  *
442  * The compression context is "owned" by the message library until
443  * dns_message_renderend() is called.  It must be invalidated by the caller.
444  *
445  * The buffer is "owned" by the message library until dns_message_renderend()
446  * is called.
447  *
448  * Requires:
449  *
450  *      'msg' be valid.
451  *
452  *      'cctx' be valid.
453  *
454  *      'buffer' is a valid buffer.
455  *
456  * Side Effects:
457  *
458  *      The buffer is cleared before it is used.
459  *
460  * Returns:
461  *      ISC_R_SUCCESS           -- all is well
462  *      ISC_R_NOSPACE           -- output buffer is too small
463  */
464
465 isc_result_t
466 dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
467 /*
468  * Reset the buffer.  This can be used after growing the old buffer
469  * on a ISC_R_NOSPACE return from most of the render functions.
470  *
471  * On successful completion, the old buffer is no longer used by the
472  * library.  The new buffer is owned by the library until
473  * dns_message_renderend() is called.
474  *
475  * Requires:
476  *
477  *      'msg' be valid.
478  *
479  *      dns_message_renderbegin() was called.
480  *
481  *      buffer != NULL.
482  *
483  * Returns:
484  *      ISC_R_NOSPACE           -- new buffer is too small
485  *      ISC_R_SUCCESS           -- all is well.
486  */
487
488 isc_result_t
489 dns_message_renderreserve(dns_message_t *msg, unsigned int space);
490 /*
491  * XXXMLG should use size_t rather than unsigned int once the buffer
492  * API is cleaned up
493  *
494  * Reserve "space" bytes in the given buffer.
495  *
496  * Requires:
497  *
498  *      'msg' be valid.
499  *
500  *      dns_message_renderbegin() was called.
501  *
502  * Returns:
503  *      ISC_R_SUCCESS           -- all is well.
504  *      ISC_R_NOSPACE           -- not enough free space in the buffer.
505  */
506
507 void
508 dns_message_renderrelease(dns_message_t *msg, unsigned int space);
509 /*
510  * XXXMLG should use size_t rather than unsigned int once the buffer
511  * API is cleaned up
512  *
513  * Release "space" bytes in the given buffer that was previously reserved.
514  *
515  * Requires:
516  *
517  *      'msg' be valid.
518  *
519  *      'space' is less than or equal to the total amount of space reserved
520  *      via prior calls to dns_message_renderreserve().
521  *
522  *      dns_message_renderbegin() was called.
523  */
524
525 isc_result_t
526 dns_message_rendersection(dns_message_t *msg, dns_section_t section,
527                           unsigned int options);
528 /*
529  * Render all names, rdatalists, etc from the given section at the
530  * specified priority or higher.
531  *
532  * Requires:
533  *      'msg' be valid.
534  *
535  *      'section' be a valid section.
536  *
537  *      dns_message_renderbegin() was called.
538  *
539  * Returns:
540  *      ISC_R_SUCCESS           -- all records were written, and there are
541  *                                 no more records for this section.
542  *      ISC_R_NOSPACE           -- Not enough room in the buffer to write
543  *                                 all records requested.
544  *      DNS_R_MOREDATA          -- All requested records written, and there
545  *                                 are records remaining for this section.
546  */
547
548 void
549 dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
550 /*
551  * Render the message header.  This is implicitly called by
552  * dns_message_renderend().
553  *
554  * Requires:
555  *
556  *      'msg' be a valid message.
557  *
558  *      dns_message_renderbegin() was called.
559  *
560  *      'target' is a valid buffer with enough space to hold a message header
561  */
562
563 isc_result_t
564 dns_message_renderend(dns_message_t *msg);
565 /*
566  * Finish rendering to the buffer.  Note that more data can be in the
567  * 'msg' structure.  Destroying the structure will free this, or in a multi-
568  * part EDNS1 message this data can be rendered to another buffer later.
569  *
570  * Requires:
571  *
572  *      'msg' be a valid message.
573  *
574  *      dns_message_renderbegin() was called.
575  *
576  * Returns:
577  *      ISC_R_SUCCESS           -- all is well.
578  */
579
580 void
581 dns_message_renderreset(dns_message_t *msg);
582 /*
583  * Reset the message so that it may be rendered again.
584  *
585  * Notes:
586  *
587  *      If dns_message_renderbegin() has been called, dns_message_renderend()
588  *      must be called before calling this function.
589  *
590  * Requires:
591  *
592  *      'msg' be a valid message with rendering intent.
593  */
594
595 isc_result_t
596 dns_message_firstname(dns_message_t *msg, dns_section_t section);
597 /*
598  * Set internal per-section name pointer to the beginning of the section.
599  *
600  * The functions dns_message_firstname() and dns_message_nextname() may
601  * be used for iterating over the owner names in a section.
602  *
603  * Requires:
604  *
605  *      'msg' be valid.
606  *
607  *      'section' be a valid section.
608  *
609  * Returns:
610  *      ISC_R_SUCCESS           -- All is well.
611  *      ISC_R_NOMORE            -- No names on given section.
612  */
613
614 isc_result_t
615 dns_message_nextname(dns_message_t *msg, dns_section_t section);
616 /*
617  * Sets the internal per-section name pointer to point to the next name
618  * in that section.
619  *
620  * Requires:
621  *
622  *      'msg' be valid.
623  *
624  *      'section' be a valid section.
625  *
626  *      dns_message_firstname() must have been called on this section,
627  *      and the result was ISC_R_SUCCESS.
628  *
629  * Returns:
630  *      ISC_R_SUCCESS           -- All is well.
631  *      ISC_R_NOMORE            -- No more names in given section.
632  */
633
634 void
635 dns_message_currentname(dns_message_t *msg, dns_section_t section,
636                         dns_name_t **name);
637 /*
638  * Sets 'name' to point to the name where the per-section internal name
639  * pointer is currently set.
640  *
641  * This function returns the name in the database, so any data associated
642  * with it (via the name's "list" member) contains the actual rdatasets.
643  *
644  * Requires:
645  *
646  *      'msg' be valid.
647  *
648  *      'name' be non-NULL, and *name be NULL.
649  *
650  *      'section' be a valid section.
651  *
652  *      dns_message_firstname() must have been called on this section,
653  *      and the result of it and any dns_message_nextname() calls was
654  *      ISC_R_SUCCESS.
655  */
656
657 isc_result_t
658 dns_message_findname(dns_message_t *msg, dns_section_t section,
659                      dns_name_t *target, dns_rdatatype_t type,
660                      dns_rdatatype_t covers, dns_name_t **foundname,
661                      dns_rdataset_t **rdataset);
662 /*
663  * Search for a name in the specified section.  If it is found, *name is
664  * set to point to the name, and *rdataset is set to point to the found
665  * rdataset (if type is specified as other than dns_rdatatype_any).
666  *
667  * Requires:
668  *      'msg' be valid.
669  *
670  *      'section' be a valid section.
671  *
672  *      If a pointer to the name is desired, 'foundname' should be non-NULL.
673  *      If it is non-NULL, '*foundname' MUST be NULL.
674  *
675  *      If a type other than dns_datatype_any is searched for, 'rdataset'
676  *      may be non-NULL, '*rdataset' be NULL, and will point at the found
677  *      rdataset.  If the type is dns_datatype_any, 'rdataset' must be NULL.
678  *
679  *      'target' be a valid name.
680  *
681  *      'type' be a valid type.
682  *
683  *      If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
684  *      Otherwise it should be 0.
685  *
686  * Returns:
687  *      ISC_R_SUCCESS           -- all is well.
688  *      DNS_R_NXDOMAIN          -- name does not exist in that section.
689  *      DNS_R_NXRRSET           -- The name does exist, but the desired
690  *                                 type does not.
691  */
692
693 isc_result_t
694 dns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
695                      dns_rdatatype_t covers, dns_rdataset_t **rdataset);
696 /*
697  * Search the name for the specified type.  If it is found, *rdataset is
698  * filled in with a pointer to that rdataset.
699  *
700  * Requires:
701  *      if '**rdataset' is non-NULL, *rdataset needs to be NULL.
702  *
703  *      'type' be a valid type, and NOT dns_rdatatype_any.
704  *
705  *      If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
706  *      Otherwise it should be 0.
707  *
708  * Returns:
709  *      ISC_R_SUCCESS           -- all is well.
710  *      ISC_R_NOTFOUND          -- the desired type does not exist.
711  */
712
713 isc_result_t
714 dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
715                  dns_rdatatype_t type, dns_rdatatype_t covers,
716                  dns_rdataset_t **rdataset);
717 /*%<
718  * Search the name for the specified rdclass and type.  If it is found,
719  * *rdataset is filled in with a pointer to that rdataset.
720  *
721  * Requires:
722  *\li   if '**rdataset' is non-NULL, *rdataset needs to be NULL.
723  *
724  *\li   'type' be a valid type, and NOT dns_rdatatype_any.
725  *
726  *\li   If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type.
727  *      Otherwise it should be 0.
728  *
729  * Returns:
730  *\li   #ISC_R_SUCCESS          -- all is well.
731  *\li   #ISC_R_NOTFOUND         -- the desired type does not exist.
732  */
733
734 void
735 dns_message_movename(dns_message_t *msg, dns_name_t *name,
736                      dns_section_t fromsection,
737                      dns_section_t tosection);
738 /*
739  * Move a name from one section to another.
740  *
741  * Requires:
742  *
743  *      'msg' be valid.
744  *
745  *      'name' must be a name already in 'fromsection'.
746  *
747  *      'fromsection' must be a valid section.
748  *
749  *      'tosection' must be a valid section.
750  */
751
752 void
753 dns_message_addname(dns_message_t *msg, dns_name_t *name,
754                     dns_section_t section);
755 /*
756  * Adds the name to the given section.
757  *
758  * It is the caller's responsibility to enforce any unique name requirements
759  * in a section.
760  *
761  * Requires:
762  *
763  *      'msg' be valid, and be a renderable message.
764  *
765  *      'name' be a valid absolute name.
766  *
767  *      'section' be a named section.
768  */
769
770 /*
771  * LOANOUT FUNCTIONS
772  *
773  * Each of these functions loan a particular type of data to the caller.
774  * The storage for these will vanish when the message is destroyed or
775  * reset, and must NOT be used after these operations.
776  */
777
778 isc_result_t
779 dns_message_gettempname(dns_message_t *msg, dns_name_t **item);
780 /*
781  * Return a name that can be used for any temporary purpose, including
782  * inserting into the message's linked lists.  The name must be returned
783  * to the message code using dns_message_puttempname() or inserted into
784  * one of the message's sections before the message is destroyed.
785  *
786  * It is the caller's responsibility to initialize this name.
787  *
788  * Requires:
789  *      msg be a valid message
790  *
791  *      item != NULL && *item == NULL
792  *
793  * Returns:
794  *      ISC_R_SUCCESS           -- All is well.
795  *      ISC_R_NOMEMORY          -- No item can be allocated.
796  */
797
798 isc_result_t
799 dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item);
800 /*
801  * Return an offsets array that can be used for any temporary purpose,
802  * such as attaching to a temporary name.  The offsets will be freed
803  * when the message is destroyed or reset.
804  *
805  * Requires:
806  *      msg be a valid message
807  *
808  *      item != NULL && *item == NULL
809  *
810  * Returns:
811  *      ISC_R_SUCCESS           -- All is well.
812  *      ISC_R_NOMEMORY          -- No item can be allocated.
813  */
814
815 isc_result_t
816 dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
817 /*
818  * Return a rdata that can be used for any temporary purpose, including
819  * inserting into the message's linked lists.  The rdata will be freed
820  * when the message is destroyed or reset.
821  *
822  * Requires:
823  *      msg be a valid message
824  *
825  *      item != NULL && *item == NULL
826  *
827  * Returns:
828  *      ISC_R_SUCCESS           -- All is well.
829  *      ISC_R_NOMEMORY          -- No item can be allocated.
830  */
831
832 isc_result_t
833 dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item);
834 /*
835  * Return a rdataset that can be used for any temporary purpose, including
836  * inserting into the message's linked lists. The name must be returned
837  * to the message code using dns_message_puttempname() or inserted into
838  * one of the message's sections before the message is destroyed.
839  *
840  * Requires:
841  *      msg be a valid message
842  *
843  *      item != NULL && *item == NULL
844  *
845  * Returns:
846  *      ISC_R_SUCCESS           -- All is well.
847  *      ISC_R_NOMEMORY          -- No item can be allocated.
848  */
849
850 isc_result_t
851 dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
852 /*
853  * Return a rdatalist that can be used for any temporary purpose, including
854  * inserting into the message's linked lists.  The rdatalist will be
855  * destroyed when the message is destroyed or reset.
856  *
857  * Requires:
858  *      msg be a valid message
859  *
860  *      item != NULL && *item == NULL
861  *
862  * Returns:
863  *      ISC_R_SUCCESS           -- All is well.
864  *      ISC_R_NOMEMORY          -- No item can be allocated.
865  */
866
867 void
868 dns_message_puttempname(dns_message_t *msg, dns_name_t **item);
869 /*
870  * Return a borrowed name to the message's name free list.
871  *
872  * Requires:
873  *      msg be a valid message
874  *
875  *      item != NULL && *item point to a name returned by
876  *      dns_message_gettempname()
877  *
878  * Ensures:
879  *      *item == NULL
880  */
881
882 void
883 dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item);
884 /*
885  * Return a borrowed rdata to the message's rdata free list.
886  *
887  * Requires:
888  *      msg be a valid message
889  *
890  *      item != NULL && *item point to a rdata returned by
891  *      dns_message_gettemprdata()
892  *
893  * Ensures:
894  *      *item == NULL
895  */
896
897 void
898 dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item);
899 /*
900  * Return a borrowed rdataset to the message's rdataset free list.
901  *
902  * Requires:
903  *      msg be a valid message
904  *
905  *      item != NULL && *item point to a rdataset returned by
906  *      dns_message_gettemprdataset()
907  *
908  * Ensures:
909  *      *item == NULL
910  */
911
912 void
913 dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
914 /*
915  * Return a borrowed rdatalist to the message's rdatalist free list.
916  *
917  * Requires:
918  *      msg be a valid message
919  *
920  *      item != NULL && *item point to a rdatalist returned by
921  *      dns_message_gettemprdatalist()
922  *
923  * Ensures:
924  *      *item == NULL
925  */
926
927 isc_result_t
928 dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
929                        unsigned int *flagsp);
930 /*
931  * Assume the remaining region of "source" is a DNS message.  Peek into
932  * it and fill in "*idp" with the message id, and "*flagsp" with the flags.
933  *
934  * Requires:
935  *
936  *      source != NULL
937  *
938  * Ensures:
939  *
940  *      if (idp != NULL) *idp == message id.
941  *
942  *      if (flagsp != NULL) *flagsp == message flags.
943  *
944  * Returns:
945  *
946  *      ISC_R_SUCCESS           -- all is well.
947  *
948  *      ISC_R_UNEXPECTEDEND     -- buffer doesn't contain enough for a header.
949  */
950
951 isc_result_t
952 dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section);
953 /*
954  * Start formatting a reply to the query in 'msg'.
955  *
956  * Requires:
957  *
958  *      'msg' is a valid message with parsing intent, and contains a query.
959  *
960  * Ensures:
961  *
962  *      The message will have a rendering intent.  If 'want_question_section'
963  *      is true, the message opcode is query or notify, and the question
964  *      section is present and properly formatted, then the question section
965  *      will be included in the reply.  All other sections will be cleared.
966  *      The QR flag will be set, the RD flag will be preserved, and all other
967  *      flags will be cleared.
968  *
969  * Returns:
970  *
971  *      ISC_R_SUCCESS           -- all is well.
972  *
973  *      DNS_R_FORMERR           -- the header or question section of the
974  *                                 message is invalid, replying is impossible.
975  *                                 If DNS_R_FORMERR is returned when
976  *                                 want_question_section is ISC_FALSE, then
977  *                                 it's the header section that's bad;
978  *                                 otherwise either of the header or question
979  *                                 sections may be bad.
980  */
981
982 dns_rdataset_t *
983 dns_message_getopt(dns_message_t *msg);
984 /*
985  * Get the OPT record for 'msg'.
986  *
987  * Requires:
988  *
989  *      'msg' is a valid message.
990  *
991  * Returns:
992  *
993  *      The OPT rdataset of 'msg', or NULL if there isn't one.
994  */
995
996 isc_result_t
997 dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
998 /*
999  * Set the OPT record for 'msg'.
1000  *
1001  * Requires:
1002  *
1003  *      'msg' is a valid message with rendering intent
1004  *      and no sections have been rendered.
1005  *
1006  *      'opt' is a valid OPT record.
1007  *
1008  * Ensures:
1009  *
1010  *      The OPT record has either been freed or ownership of it has
1011  *      been transferred to the message.
1012  *
1013  *      If ISC_R_SUCCESS was returned, the OPT record will be rendered 
1014  *      when dns_message_renderend() is called.
1015  *
1016  * Returns:
1017  *
1018  *      ISC_R_SUCCESS           -- all is well.
1019  *
1020  *      ISC_R_NOSPACE           -- there is no space for the OPT record.
1021  */
1022
1023 dns_rdataset_t *
1024 dns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
1025 /*
1026  * Get the TSIG record and owner for 'msg'.
1027  *
1028  * Requires:
1029  *
1030  *      'msg' is a valid message.
1031  *      'owner' is NULL or *owner is NULL.
1032  *
1033  * Returns:
1034  *
1035  *      The TSIG rdataset of 'msg', or NULL if there isn't one.
1036  *
1037  * Ensures:
1038  *
1039  *      If 'owner' is not NULL, it will point to the owner name.
1040  */
1041
1042 isc_result_t
1043 dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
1044 /*
1045  * Set the tsig key for 'msg'.  This is only necessary for when rendering a
1046  * query or parsing a response.  The key (if non-NULL) is attached to, and
1047  * will be detached when the message is destroyed.
1048  *
1049  * Requires:
1050  *
1051  *      'msg' is a valid message with rendering intent,
1052  *      dns_message_renderbegin() has been called, and no sections have been
1053  *      rendered.
1054  *      'key' is a valid tsig key or NULL.
1055  *
1056  * Returns:
1057  *
1058  *      ISC_R_SUCCESS           -- all is well.
1059  *
1060  *      ISC_R_NOSPACE           -- there is no space for the TSIG record.
1061  */
1062
1063 dns_tsigkey_t *
1064 dns_message_gettsigkey(dns_message_t *msg);
1065 /*
1066  * Gets the tsig key for 'msg'.
1067  *
1068  * Requires:
1069  *
1070  *      'msg' is a valid message
1071  */
1072
1073 isc_result_t
1074 dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
1075 /*
1076  * Indicates that 'querytsig' is the TSIG from the signed query for which
1077  * 'msg' is the response.  This is also used for chained TSIGs in TCP
1078  * responses.
1079  *
1080  * Requires:
1081  *
1082  *      'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
1083  *      or NULL
1084  *
1085  *      'msg' is a valid message
1086  *
1087  * Returns:
1088  *
1089  *      ISC_R_SUCCESS
1090  *      ISC_R_NOMEMORY
1091  */
1092
1093 isc_result_t
1094 dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
1095                          isc_buffer_t **querytsig);
1096 /*
1097  * Gets the tsig from the TSIG from the signed query 'msg'.  This is also used
1098  * for chained TSIGs in TCP responses.  Unlike dns_message_gettsig, this makes
1099  * a copy of the data, so can be used if the message is destroyed.
1100  *
1101  * Requires:
1102  *
1103  *      'msg' is a valid signed message
1104  *      'mctx' is a valid memory context
1105  *      querytsig != NULL && *querytsig == NULL
1106  *
1107  * Returns:
1108  *
1109  *      ISC_R_SUCCESS
1110  *      ISC_R_NOMEMORY
1111  *
1112  * Ensures:
1113  *      'tsig' points to NULL or an allocated buffer which must be freed
1114  *      by the caller.
1115  */
1116
1117 dns_rdataset_t *
1118 dns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
1119 /*
1120  * Get the SIG(0) record and owner for 'msg'.
1121  *
1122  * Requires:
1123  *
1124  *      'msg' is a valid message.
1125  *      'owner' is NULL or *owner is NULL.
1126  *
1127  * Returns:
1128  *
1129  *      The SIG(0) rdataset of 'msg', or NULL if there isn't one.
1130  *
1131  * Ensures:
1132  *
1133  *      If 'owner' is not NULL, it will point to the owner name.
1134  */
1135
1136 isc_result_t
1137 dns_message_setsig0key(dns_message_t *msg, dst_key_t *key);
1138 /*
1139  * Set the SIG(0) key for 'msg'.
1140  *
1141  * Requires:
1142  *
1143  *      'msg' is a valid message with rendering intent,
1144  *      dns_message_renderbegin() has been called, and no sections have been
1145  *      rendered.
1146  *      'key' is a valid sig key or NULL.
1147  *
1148  * Returns:
1149  *
1150  *      ISC_R_SUCCESS           -- all is well.
1151  *
1152  *      ISC_R_NOSPACE           -- there is no space for the SIG(0) record.
1153  */
1154
1155 dst_key_t *
1156 dns_message_getsig0key(dns_message_t *msg);
1157 /*
1158  * Gets the SIG(0) key for 'msg'.
1159  *
1160  * Requires:
1161  *
1162  *      'msg' is a valid message
1163  */
1164
1165 void
1166 dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
1167 /*
1168  * Give the *buffer to the message code to clean up when it is no
1169  * longer needed.  This is usually when the message is reset or
1170  * destroyed.
1171  *
1172  * Requires:
1173  *
1174  *      msg be a valid message.
1175  *
1176  *      buffer != NULL && *buffer is a valid isc_buffer_t, which was
1177  *      dynamincally allocated via isc_buffer_allocate().
1178  */
1179
1180 isc_result_t
1181 dns_message_signer(dns_message_t *msg, dns_name_t *signer);
1182 /*
1183  * If this message was signed, return the identity of the signer.
1184  * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the
1185  * key that signed the message.
1186  *
1187  * Requires:
1188  *
1189  *      msg is a valid parsed message.
1190  *      signer is a valid name
1191  *
1192  * Returns:
1193  *
1194  *      ISC_R_SUCCESS           - the message was signed, and *signer
1195  *                                contains the signing identity
1196  *
1197  *      ISC_R_NOTFOUND          - no TSIG or SIG(0) record is present in the
1198  *                                message
1199  *
1200  *      DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the
1201  *                                signature failed to verify
1202  *
1203  *      DNS_R_TSIGERRORSET      - the message was signed by a TSIG and
1204  *                                verified, but the query was rejected by
1205  *                                the server
1206  *
1207  *      DNS_R_NOIDENTITY        - the message was signed by a TSIG and
1208  *                                verified, but the key has no identity since
1209  *                                it was generated by an unsigned TKEY process
1210  *
1211  *      DNS_R_SIGINVALID        - the message was signed by a SIG(0), but
1212  *                                the signature failed to verify
1213  *
1214  *      DNS_R_NOTVERIFIEDYET    - the message was signed by a TSIG or SIG(0),
1215  *                                but the signature has not been verified yet
1216  */
1217
1218 isc_result_t
1219 dns_message_checksig(dns_message_t *msg, dns_view_t *view);
1220 /*
1221  * If this message was signed, verify the signature.
1222  *
1223  * Requires:
1224  *
1225  *      msg is a valid parsed message.
1226  *      view is a valid view or NULL
1227  *
1228  * Returns:
1229  *
1230  *      ISC_R_SUCCESS           - the message was unsigned, or the message
1231  *                                was signed correctly.
1232  *
1233  *      DNS_R_EXPECTEDTSIG      - A TSIG was expected, but not seen
1234  *      DNS_R_UNEXPECTEDTSIG    - A TSIG was seen but not expected
1235  *      DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
1236  */
1237
1238 isc_result_t
1239 dns_message_rechecksig(dns_message_t *msg, dns_view_t *view);
1240 /*
1241  * Reset the signature state and then if the message was signed,
1242  * verify the message.
1243  *
1244  * Requires:
1245  *
1246  *      msg is a valid parsed message.
1247  *      view is a valid view or NULL
1248  *
1249  * Returns:
1250  *
1251  *      ISC_R_SUCCESS           - the message was unsigned, or the message
1252  *                                was signed correctly.
1253  *
1254  *      DNS_R_EXPECTEDTSIG      - A TSIG was expected, but not seen
1255  *      DNS_R_UNEXPECTEDTSIG    - A TSIG was seen but not expected
1256  *      DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
1257  */
1258
1259 void
1260 dns_message_resetsig(dns_message_t *msg);
1261 /*
1262  * Reset the signature state.
1263  *
1264  * Requires:
1265  *      'msg' is a valid parsed message.
1266  */
1267
1268 isc_region_t *
1269 dns_message_getrawmessage(dns_message_t *msg);
1270 /*
1271  * Retrieve the raw message in compressed wire format.  The message must
1272  * have been successfully parsed for it to have been saved.
1273  *
1274  * Requires:
1275  *      msg is a valid parsed message.
1276  *
1277  * Returns:
1278  *      NULL    if there is no saved message.
1279  *      a pointer to a region which refers the dns message.
1280  */
1281
1282 void
1283 dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
1284                          const void *order_arg);
1285 /*
1286  * Define the order in which RR sets get rendered by
1287  * dns_message_rendersection() to be the ascending order
1288  * defined by the integer value returned by 'order' when
1289  * given each RR and 'arg' as arguments.  If 'order' and
1290  * 'order_arg' are NULL, a default order is used.
1291  *
1292  * Requires:
1293  *      msg be a valid message.
1294  *      order_arg is NULL if and only if order is NULL.
1295  */
1296
1297 void 
1298 dns_message_settimeadjust(dns_message_t *msg, int timeadjust);
1299 /*
1300  * Adjust the time used to sign/verify a message by timeadjust.
1301  * Currently only TSIG.
1302  *
1303  * Requires:
1304  *      msg be a valid message.
1305  */
1306
1307 int 
1308 dns_message_gettimeadjust(dns_message_t *msg);
1309 /*
1310  * Return the current time adjustment.
1311  *
1312  * Requires:
1313  *      msg be a valid message.
1314  */
1315
1316 ISC_LANG_ENDDECLS
1317
1318 #endif /* DNS_MESSAGE_H */