Merge from vendor branch CVS:
[dragonfly.git] / contrib / bind-9.2.4rc7 / lib / dns / include / dns / message.h
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2002  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.4 2004/03/09 06:11:19 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)
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
165 typedef struct dns_msgblock dns_msgblock_t;
166
167 struct dns_message {
168         /* public from here down */
169         unsigned int                    magic;
170
171         dns_messageid_t                 id;
172         unsigned int                    flags;
173         dns_rcode_t                     rcode;
174         unsigned int                    opcode;
175         dns_rdataclass_t                rdclass;
176
177         /* 4 real, 1 pseudo */
178         unsigned int                    counts[DNS_SECTION_MAX];
179
180         /* private from here down */
181         dns_namelist_t                  sections[DNS_SECTION_MAX];
182         dns_name_t                     *cursors[DNS_SECTION_MAX];
183         dns_rdataset_t                 *opt;
184         dns_rdataset_t                 *sig0;
185         dns_rdataset_t                 *tsig;
186
187         int                             state;
188         unsigned int                    from_to_wire : 2;
189         unsigned int                    header_ok : 1;
190         unsigned int                    question_ok : 1;
191         unsigned int                    tcp_continuation : 1;
192         unsigned int                    verified_sig : 1;
193         unsigned int                    verify_attempted : 1;
194         unsigned int                    free_query : 1;
195         unsigned int                    free_saved : 1;
196
197         unsigned int                    opt_reserved;
198         unsigned int                    sig_reserved;
199         unsigned int                    reserved; /* reserved space (render) */
200
201         isc_buffer_t                   *buffer;
202         dns_compress_t                 *cctx;
203
204         isc_mem_t                      *mctx;
205         isc_mempool_t                  *namepool;
206         isc_mempool_t                  *rdspool;
207
208         isc_bufferlist_t                scratchpad;
209         isc_bufferlist_t                cleanup;
210
211         ISC_LIST(dns_msgblock_t)        rdatas;
212         ISC_LIST(dns_msgblock_t)        rdatalists;
213         ISC_LIST(dns_msgblock_t)        offsets;
214
215         ISC_LIST(dns_rdata_t)           freerdata;
216         ISC_LIST(dns_rdatalist_t)       freerdatalist;
217
218         dns_rcode_t                     tsigstatus;
219         dns_rcode_t                     querytsigstatus;
220         dns_name_t                     *tsigname;
221         dns_rdataset_t                 *querytsig;
222         dns_tsigkey_t                  *tsigkey;
223         dst_context_t                  *tsigctx;
224         int                             sigstart;
225         int                             timeadjust;
226
227         dns_name_t                     *sig0name;
228         dst_key_t                      *sig0key;
229         dns_rcode_t                     sig0status;
230         isc_region_t                    query;
231         isc_region_t                    saved;
232
233         dns_rdatasetorderfunc_t         order;
234         void *                          order_arg;
235 };
236
237 /***
238  *** Functions
239  ***/
240
241 ISC_LANG_BEGINDECLS
242
243 isc_result_t
244 dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp);
245
246 /*
247  * Create msg structure.
248  *
249  * This function will allocate some internal blocks of memory that are
250  * expected to be needed for parsing or rendering nearly any type of message.
251  *
252  * Requires:
253  *      'mctx' be a valid memory context.
254  *
255  *      'msgp' be non-null and '*msg' be NULL.
256  *
257  *      'intent' must be one of DNS_MESSAGE_INTENTPARSE or
258  *      DNS_MESSAGE_INTENTRENDER.
259  *
260  * Ensures:
261  *      The data in "*msg" is set to indicate an unused and empty msg
262  *      structure.
263  *
264  * Returns:
265  *      ISC_R_NOMEMORY          -- out of memory
266  *      ISC_R_SUCCESS           -- success
267  */
268
269 void
270 dns_message_reset(dns_message_t *msg, unsigned int intent);
271 /*
272  * Reset a message structure to default state.  All internal lists are freed
273  * or reset to a default state as well.  This is simply a more efficient
274  * way to call dns_message_destroy() followed by dns_message_allocate(),
275  * since it avoid many memory allocations.
276  *
277  * If any data loanouts (buffers, names, rdatas, etc) were requested,
278  * the caller must no longer use them after this call.
279  *
280  * The intended next use of the message will be 'intent'.
281  *
282  * Requires:
283  *
284  *      'msg' be valid.
285  *
286  *      'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER
287  */
288
289 void
290 dns_message_destroy(dns_message_t **msgp);
291 /*
292  * Destroy all state in the message.
293  *
294  * Requires:
295  *
296  *      'msgp' be valid.
297  *
298  * Ensures:
299  *      '*msgp' == NULL
300  */
301
302 isc_result_t
303 dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
304                           const dns_master_style_t *style,
305                           dns_messagetextflag_t flags,
306                           isc_buffer_t *target);
307
308 isc_result_t
309 dns_message_pseudosectiontotext(dns_message_t *msg,
310                                 dns_pseudosection_t section,
311                                 const dns_master_style_t *style,
312                                 dns_messagetextflag_t flags,
313                                 isc_buffer_t *target);
314 /*
315  * Convert section 'section' or 'pseudosection' of message 'msg' to
316  * a cleartext representation
317  *
318  * Notes:
319  *      See dns_message_totext for meanings of flags.
320  *
321  * Requires:
322  *
323  *      'msg' is a valid message.
324  *
325  *      'style' is a valid master dump style.
326  *
327  *      'target' is a valid buffer.
328  *
329  *      'section' is a valid section label.
330  *
331  * Ensures:
332  *
333  *      If the result is success:
334  *
335  *              The used space in 'target' is updated.
336  *
337  * Returns:
338  *
339  *      ISC_R_SUCCESS
340  *      ISC_R_NOSPACE
341  *      ISC_R_NOMORE
342  *
343  *      Note: On error return, *target may be partially filled with data.
344 */
345
346 isc_result_t
347 dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
348                    dns_messagetextflag_t flags, isc_buffer_t *target);
349 /*
350  * Convert all sections of message 'msg' to a cleartext representation
351  *
352  * Notes:
353  *      In flags, If DNS_MESSAGETEXTFLAG_OMITDOT is set, then the
354  *      final '.' in absolute names will not be emitted.  If
355  *      DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning
356  *      with ";;" will be emitted indicating section name.  If
357  *      DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will
358  *      be emitted.
359  *
360  * Requires:
361  *
362  *      'msg' is a valid message.
363  *
364  *      'style' is a valid master dump style.
365  *
366  *      'target' is a valid buffer.
367  *
368  * Ensures:
369  *
370  *      If the result is success:
371  *
372  *              The used space in 'target' is updated.
373  *
374  * Returns:
375  *
376  *      ISC_R_SUCCESS
377  *      ISC_R_NOSPACE
378  *      ISC_R_NOMORE
379  *
380  *      Note: On error return, *target may be partially filled with data.
381  */
382
383 isc_result_t
384 dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
385                   unsigned int options);
386 /*
387  * Parse raw wire data in 'source' as a DNS message.
388  *
389  * OPT records are detected and stored in the pseudo-section "opt".
390  * TSIGs are detected and stored in the pseudo-section "tsig".
391  *
392  * If DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message
393  * is UPDATE, a separate dns_name_t object will be created for each RR in the
394  * message.  Each such dns_name_t will have a single rdataset containing the
395  * single RR, and the order of the RRs in the message is preserved.
396  * Otherwise, only one dns_name_t object will be created for each unique
397  * owner name in the section, and each such dns_name_t will have a list
398  * of rdatasets.  To access the names and their data, use
399  * dns_message_firstname() and dns_message_nextname().
400  *
401  * If DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will
402  * not be considered FORMERRs.  If the entire message can be parsed, it
403  * will be returned and DNS_R_RECOVERABLE will be returned.
404  *
405  * If DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
406  * RR's as possible, DNS_R_RECOVERABLE will be returned.
407  *
408  * OPT and TSIG records are always handled specially, regardless of the
409  * 'preserve_order' setting.
410  *
411  * Requires:
412  *      "msg" be valid.
413  *
414  *      "buffer" be a wire format buffer.
415  *
416  * Ensures:
417  *      The buffer's data format is correct.
418  *
419  *      The buffer's contents verify as correct regarding header bits, buffer
420  *      and rdata sizes, etc.
421  *
422  * Returns:
423  *      ISC_R_SUCCESS           -- all is well
424  *      ISC_R_NOMEMORY          -- no memory
425  *      DNS_R_RECOVERABLE       -- the message parsed properly, but contained
426  *                                 errors.
427  *      Many other errors possible XXXMLG
428  */
429
430 isc_result_t
431 dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
432                         isc_buffer_t *buffer);
433 /*
434  * Begin rendering on a message.  Only one call can be made to this function
435  * per message.
436  *
437  * The compression context is "owned" by the message library until
438  * dns_message_renderend() is called.  It must be invalidated by the caller.
439  *
440  * The buffer is "owned" by the message library until dns_message_renderend()
441  * is called.
442  *
443  * Requires:
444  *
445  *      'msg' be valid.
446  *
447  *      'cctx' be valid.
448  *
449  *      'buffer' is a valid buffer.
450  *
451  * Side Effects:
452  *
453  *      The buffer is cleared before it is used.
454  *
455  * Returns:
456  *      ISC_R_SUCCESS           -- all is well
457  *      ISC_R_NOSPACE           -- output buffer is too small
458  */
459
460 isc_result_t
461 dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
462 /*
463  * Reset the buffer.  This can be used after growing the old buffer
464  * on a ISC_R_NOSPACE return from most of the render functions.
465  *
466  * On successful completion, the old buffer is no longer used by the
467  * library.  The new buffer is owned by the library until
468  * dns_message_renderend() is called.
469  *
470  * Requires:
471  *
472  *      'msg' be valid.
473  *
474  *      dns_message_renderbegin() was called.
475  *
476  *      buffer != NULL.
477  *
478  * Returns:
479  *      ISC_R_NOSPACE           -- new buffer is too small
480  *      ISC_R_SUCCESS           -- all is well.
481  */
482
483 isc_result_t
484 dns_message_renderreserve(dns_message_t *msg, unsigned int space);
485 /*
486  * XXXMLG should use size_t rather than unsigned int once the buffer
487  * API is cleaned up
488  *
489  * Reserve "space" bytes in the given buffer.
490  *
491  * Requires:
492  *
493  *      'msg' be valid.
494  *
495  *      dns_message_renderbegin() was called.
496  *
497  * Returns:
498  *      ISC_R_SUCCESS           -- all is well.
499  *      ISC_R_NOSPACE           -- not enough free space in the buffer.
500  */
501
502 void
503 dns_message_renderrelease(dns_message_t *msg, unsigned int space);
504 /*
505  * XXXMLG should use size_t rather than unsigned int once the buffer
506  * API is cleaned up
507  *
508  * Release "space" bytes in the given buffer that was previously reserved.
509  *
510  * Requires:
511  *
512  *      'msg' be valid.
513  *
514  *      'space' is less than or equal to the total amount of space reserved
515  *      via prior calls to dns_message_renderreserve().
516  *
517  *      dns_message_renderbegin() was called.
518  */
519
520 isc_result_t
521 dns_message_rendersection(dns_message_t *msg, dns_section_t section,
522                           unsigned int options);
523 /*
524  * Render all names, rdatalists, etc from the given section at the
525  * specified priority or higher.
526  *
527  * Requires:
528  *      'msg' be valid.
529  *
530  *      'section' be a valid section.
531  *
532  *      dns_message_renderbegin() was called.
533  *
534  * Returns:
535  *      ISC_R_SUCCESS           -- all records were written, and there are
536  *                                 no more records for this section.
537  *      ISC_R_NOSPACE           -- Not enough room in the buffer to write
538  *                                 all records requested.
539  *      DNS_R_MOREDATA          -- All requested records written, and there
540  *                                 are records remaining for this section.
541  */
542
543 void
544 dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
545 /*
546  * Render the message header.  This is implicitly called by
547  * dns_message_renderend().
548  *
549  * Requires:
550  *
551  *      'msg' be a valid message.
552  *
553  *      dns_message_renderbegin() was called.
554  *
555  *      'target' is a valid buffer with enough space to hold a message header
556  */
557
558 isc_result_t
559 dns_message_renderend(dns_message_t *msg);
560 /*
561  * Finish rendering to the buffer.  Note that more data can be in the
562  * 'msg' structure.  Destroying the structure will free this, or in a multi-
563  * part EDNS1 message this data can be rendered to another buffer later.
564  *
565  * Requires:
566  *
567  *      'msg' be a valid message.
568  *
569  *      dns_message_renderbegin() was called.
570  *
571  * Returns:
572  *      ISC_R_SUCCESS           -- all is well.
573  */
574
575 void
576 dns_message_renderreset(dns_message_t *msg);
577 /*
578  * Reset the message so that it may be rendered again.
579  *
580  * Notes:
581  *
582  *      If dns_message_renderbegin() has been called, dns_message_renderend()
583  *      must be called before calling this function.
584  *
585  * Requires:
586  *
587  *      'msg' be a valid message with rendering intent.
588  */
589
590 isc_result_t
591 dns_message_firstname(dns_message_t *msg, dns_section_t section);
592 /*
593  * Set internal per-section name pointer to the beginning of the section.
594  *
595  * The functions dns_message_firstname() and dns_message_nextname() may
596  * be used for iterating over the owner names in a section.
597  *
598  * Requires:
599  *
600  *      'msg' be valid.
601  *
602  *      'section' be a valid section.
603  *
604  * Returns:
605  *      ISC_R_SUCCESS           -- All is well.
606  *      ISC_R_NOMORE            -- No names on given section.
607  */
608
609 isc_result_t
610 dns_message_nextname(dns_message_t *msg, dns_section_t section);
611 /*
612  * Sets the internal per-section name pointer to point to the next name
613  * in that section.
614  *
615  * Requires:
616  *
617  *      'msg' be valid.
618  *
619  *      'section' be a valid section.
620  *
621  *      dns_message_firstname() must have been called on this section,
622  *      and the result was ISC_R_SUCCESS.
623  *
624  * Returns:
625  *      ISC_R_SUCCESS           -- All is well.
626  *      ISC_R_NOMORE            -- No names in given section.
627  */
628
629 void
630 dns_message_currentname(dns_message_t *msg, dns_section_t section,
631                         dns_name_t **name);
632 /*
633  * Sets 'name' to point to the name where the per-section internal name
634  * pointer is currently set.
635  *
636  * This function returns the name in the database, so any data associated
637  * with it (via the name's "list" member) contains the actual rdatasets.
638  *
639  * Requires:
640  *
641  *      'msg' be valid.
642  *
643  *      'name' be non-NULL, and *name be NULL.
644  *
645  *      'section' be a valid section.
646  *
647  *      dns_message_firstname() must have been called on this section,
648  *      and the result of it and any dns_message_nextname() calls was
649  *      ISC_R_SUCCESS.
650  */
651
652 isc_result_t
653 dns_message_findname(dns_message_t *msg, dns_section_t section,
654                      dns_name_t *target, dns_rdatatype_t type,
655                      dns_rdatatype_t covers, dns_name_t **foundname,
656                      dns_rdataset_t **rdataset);
657 /*
658  * Search for a name in the specified section.  If it is found, *name is
659  * set to point to the name, and *rdataset is set to point to the found
660  * rdataset (if type is specified as other than dns_rdatatype_any).
661  *
662  * Requires:
663  *      'msg' be valid.
664  *
665  *      'section' be a valid section.
666  *
667  *      If a pointer to the name is desired, 'foundname' should be non-NULL.
668  *      If it is non-NULL, '*foundname' MUST be NULL.
669  *
670  *      If a type other than dns_datatype_any is searched for, 'rdataset'
671  *      may be non-NULL, '*rdataset' be NULL, and will point at the found
672  *      rdataset.  If the type is dns_datatype_any, 'rdataset' must be NULL.
673  *
674  *      'target' be a valid name.
675  *
676  *      'type' be a valid type.
677  *
678  *      If 'type' is dns_rdatatype_sig, 'covers' must be a valid type.
679  *      Otherwise it should be 0.
680  *
681  * Returns:
682  *      ISC_R_SUCCESS           -- all is well.
683  *      DNS_R_NXDOMAIN          -- name does not exist in that section.
684  *      DNS_R_NXRRSET           -- The name does exist, but the desired
685  *                                 type does not.
686  */
687
688 isc_result_t
689 dns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
690                      dns_rdatatype_t covers, dns_rdataset_t **rdataset);
691 /*
692  * Search the name for the specified type.  If it is found, *rdataset is
693  * filled in with a pointer to that rdataset.
694  *
695  * Requires:
696  *      if '**rdataset' is non-NULL, *rdataset needs to be NULL.
697  *
698  *      'type' be a valid type, and NOT dns_rdatatype_any.
699  *
700  *      If 'type' is dns_rdatatype_sig, 'covers' must be a valid type.
701  *      Otherwise it should be 0.
702  *
703  * Returns:
704  *      ISC_R_SUCCESS           -- all is well.
705  *      ISC_R_NOTFOUND          -- the desired type does not exist.
706  */
707
708 void
709 dns_message_movename(dns_message_t *msg, dns_name_t *name,
710                      dns_section_t fromsection,
711                      dns_section_t tosection);
712 /*
713  * Move a name from one section to another.
714  *
715  * Requires:
716  *
717  *      'msg' be valid.
718  *
719  *      'name' must be a name already in 'fromsection'.
720  *
721  *      'fromsection' must be a valid section.
722  *
723  *      'tosection' must be a valid section.
724  */
725
726 void
727 dns_message_addname(dns_message_t *msg, dns_name_t *name,
728                     dns_section_t section);
729 /*
730  * Adds the name to the given section.
731  *
732  * It is the caller's responsibility to enforce any unique name requirements
733  * in a section.
734  *
735  * Requires:
736  *
737  *      'msg' be valid, and be a renderable message.
738  *
739  *      'name' be a valid name.
740  *
741  *      'section' be a named section.
742  */
743
744 /*
745  * LOANOUT FUNCTIONS
746  *
747  * Each of these functions loan a particular type of data to the caller.
748  * The storage for these will vanish when the message is destroyed or
749  * reset, and must NOT be used after these operations.
750  */
751
752 isc_result_t
753 dns_message_gettempname(dns_message_t *msg, dns_name_t **item);
754 /*
755  * Return a name that can be used for any temporary purpose, including
756  * inserting into the message's linked lists.  The name must be returned
757  * to the message code using dns_message_puttempname() or inserted into
758  * one of the message's sections before the message is destroyed.
759  *
760  * It is the caller's responsibility to initialize this name.
761  *
762  * Requires:
763  *      msg be a valid message
764  *
765  *      item != NULL && *item == NULL
766  *
767  * Returns:
768  *      ISC_R_SUCCESS           -- All is well.
769  *      ISC_R_NOMEMORY          -- No item can be allocated.
770  */
771
772 isc_result_t
773 dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item);
774 /*
775  * Return an offsets array that can be used for any temporary purpose,
776  * such as attaching to a temporary name.  The offsets will be freed
777  * when the message is destroyed or reset.
778  *
779  * Requires:
780  *      msg be a valid message
781  *
782  *      item != NULL && *item == NULL
783  *
784  * Returns:
785  *      ISC_R_SUCCESS           -- All is well.
786  *      ISC_R_NOMEMORY          -- No item can be allocated.
787  */
788
789 isc_result_t
790 dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
791 /*
792  * Return a rdata that can be used for any temporary purpose, including
793  * inserting into the message's linked lists.  The rdata will be freed
794  * when the message is destroyed or reset.
795  *
796  * Requires:
797  *      msg be a valid message
798  *
799  *      item != NULL && *item == NULL
800  *
801  * Returns:
802  *      ISC_R_SUCCESS           -- All is well.
803  *      ISC_R_NOMEMORY          -- No item can be allocated.
804  */
805
806 isc_result_t
807 dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item);
808 /*
809  * Return a rdataset that can be used for any temporary purpose, including
810  * inserting into the message's linked lists. The name must be returned
811  * to the message code using dns_message_puttempname() or inserted into
812  * one of the message's sections before the message is destroyed.
813  *
814  * Requires:
815  *      msg be a valid message
816  *
817  *      item != NULL && *item == NULL
818  *
819  * Returns:
820  *      ISC_R_SUCCESS           -- All is well.
821  *      ISC_R_NOMEMORY          -- No item can be allocated.
822  */
823
824 isc_result_t
825 dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
826 /*
827  * Return a rdatalist that can be used for any temporary purpose, including
828  * inserting into the message's linked lists.  The rdatalist will be
829  * destroyed when the message is destroyed or reset.
830  *
831  * Requires:
832  *      msg be a valid message
833  *
834  *      item != NULL && *item == NULL
835  *
836  * Returns:
837  *      ISC_R_SUCCESS           -- All is well.
838  *      ISC_R_NOMEMORY          -- No item can be allocated.
839  */
840
841 void
842 dns_message_puttempname(dns_message_t *msg, dns_name_t **item);
843 /*
844  * Return a borrowed name to the message's name free list.
845  *
846  * Requires:
847  *      msg be a valid message
848  *
849  *      item != NULL && *item point to a name returned by
850  *      dns_message_gettempname()
851  *
852  * Ensures:
853  *      *item == NULL
854  */
855
856 void
857 dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item);
858 /*
859  * Return a borrowed rdata to the message's rdata free list.
860  *
861  * Requires:
862  *      msg be a valid message
863  *
864  *      item != NULL && *item point to a rdata returned by
865  *      dns_message_gettemprdata()
866  *
867  * Ensures:
868  *      *item == NULL
869  */
870
871 void
872 dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item);
873 /*
874  * Return a borrowed rdataset to the message's rdataset free list.
875  *
876  * Requires:
877  *      msg be a valid message
878  *
879  *      item != NULL && *item point to a rdataset returned by
880  *      dns_message_gettemprdataset()
881  *
882  * Ensures:
883  *      *item == NULL
884  */
885
886 void
887 dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
888 /*
889  * Return a borrowed rdatalist to the message's rdatalist free list.
890  *
891  * Requires:
892  *      msg be a valid message
893  *
894  *      item != NULL && *item point to a rdatalist returned by
895  *      dns_message_gettemprdatalist()
896  *
897  * Ensures:
898  *      *item == NULL
899  */
900
901 isc_result_t
902 dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
903                        unsigned int *flagsp);
904 /*
905  * Assume the remaining region of "source" is a DNS message.  Peek into
906  * it and fill in "*idp" with the message id, and "*flagsp" with the flags.
907  *
908  * Requires:
909  *
910  *      source != NULL
911  *
912  * Ensures:
913  *
914  *      if (idp != NULL) *idp == message id.
915  *
916  *      if (flagsp != NULL) *flagsp == message flags.
917  *
918  * Returns:
919  *
920  *      ISC_R_SUCCESS           -- all is well.
921  *
922  *      ISC_R_UNEXPECTEDEND     -- buffer doesn't contain enough for a header.
923  */
924
925 isc_result_t
926 dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section);
927 /*
928  * Start formatting a reply to the query in 'msg'.
929  *
930  * Requires:
931  *
932  *      'msg' is a valid message with parsing intent, and contains a query.
933  *
934  * Ensures:
935  *
936  *      The message will have a rendering intent.  If 'want_question_section'
937  *      is true, the message opcode is query or notify, and the question
938  *      section is present and properly formatted, then the question section
939  *      will be included in the reply.  All other sections will be cleared.
940  *      The QR flag will be set, the RD flag will be preserved, and all other
941  *      flags will be cleared.
942  *
943  * Returns:
944  *
945  *      ISC_R_SUCCESS           -- all is well.
946  *
947  *      DNS_R_FORMERR           -- the header or question section of the
948  *                                 message is invalid, replying is impossible.
949  *                                 If DNS_R_FORMERR is returned when
950  *                                 want_question_section is ISC_FALSE, then
951  *                                 it's the header section that's bad;
952  *                                 otherwise either of the header or question
953  *                                 sections may be bad.
954  */
955
956 dns_rdataset_t *
957 dns_message_getopt(dns_message_t *msg);
958 /*
959  * Get the OPT record for 'msg'.
960  *
961  * Requires:
962  *
963  *      'msg' is a valid message.
964  *
965  * Returns:
966  *
967  *      The OPT rdataset of 'msg', or NULL if there isn't one.
968  */
969
970 isc_result_t
971 dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
972 /*
973  * Set the OPT record for 'msg'.
974  *
975  * Requires:
976  *
977  *      'msg' is a valid message with rendering intent,
978  *      dns_message_renderbegin() has been called, and no sections have been
979  *      rendered.
980  *
981  *      'opt' is a valid OPT record.
982  *
983  * Ensures:
984  *
985  *      The OPT record has either been freed or ownership of it has
986  *      been transferred to the message.
987  *
988  *      If ISC_R_SUCCESS was returned, the OPT record will be rendered 
989  *      when dns_message_renderend() is called.
990  *
991  * Returns:
992  *
993  *      ISC_R_SUCCESS           -- all is well.
994  *
995  *      ISC_R_NOSPACE           -- there is no space for the OPT record.
996  */
997
998 dns_rdataset_t *
999 dns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
1000 /*
1001  * Get the TSIG record and owner for 'msg'.
1002  *
1003  * Requires:
1004  *
1005  *      'msg' is a valid message.
1006  *      'owner' is NULL or *owner is NULL.
1007  *
1008  * Returns:
1009  *
1010  *      The TSIG rdataset of 'msg', or NULL if there isn't one.
1011  *
1012  * Ensures:
1013  *
1014  *      If 'owner' is not NULL, it will point to the owner name.
1015  */
1016
1017 isc_result_t
1018 dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
1019 /*
1020  * Set the tsig key for 'msg'.  This is only necessary for when rendering a
1021  * query or parsing a response.  The key (if non-NULL) is attached to, and
1022  * will be detached when the message is destroyed.
1023  *
1024  * Requires:
1025  *
1026  *      'msg' is a valid message with rendering intent,
1027  *      dns_message_renderbegin() has been called, and no sections have been
1028  *      rendered.
1029  *      'key' is a valid tsig key or NULL.
1030  *
1031  * Returns:
1032  *
1033  *      ISC_R_SUCCESS           -- all is well.
1034  *
1035  *      ISC_R_NOSPACE           -- there is no space for the TSIG record.
1036  */
1037
1038 dns_tsigkey_t *
1039 dns_message_gettsigkey(dns_message_t *msg);
1040 /*
1041  * Gets the tsig key for 'msg'.
1042  *
1043  * Requires:
1044  *
1045  *      'msg' is a valid message
1046  */
1047
1048 isc_result_t
1049 dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
1050 /*
1051  * Indicates that 'querytsig' is the TSIG from the signed query for which
1052  * 'msg' is the response.  This is also used for chained TSIGs in TCP
1053  * responses.
1054  *
1055  * Requires:
1056  *
1057  *      'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
1058  *      or NULL
1059  *
1060  *      'msg' is a valid message
1061  *
1062  * Returns:
1063  *
1064  *      ISC_R_SUCCESS
1065  *      ISC_R_NOMEMORY
1066  */
1067
1068 isc_result_t
1069 dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
1070                          isc_buffer_t **querytsig);
1071 /*
1072  * Gets the tsig from the TSIG from the signed query 'msg'.  This is also used
1073  * for chained TSIGs in TCP responses.  Unlike dns_message_gettsig, this makes
1074  * a copy of the data, so can be used if the message is destroyed.
1075  *
1076  * Requires:
1077  *
1078  *      'msg' is a valid signed message
1079  *      'mctx' is a valid memory context
1080  *      querytsig != NULL && *querytsig == NULL
1081  *
1082  * Returns:
1083  *
1084  *      ISC_R_SUCCESS
1085  *      ISC_R_NOMEMORY
1086  *
1087  * Ensures:
1088  *      'tsig' points to NULL or an allocated buffer which must be freed
1089  *      by the caller.
1090  */
1091
1092 dns_rdataset_t *
1093 dns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
1094 /*
1095  * Get the SIG(0) record and owner for 'msg'.
1096  *
1097  * Requires:
1098  *
1099  *      'msg' is a valid message.
1100  *      'owner' is NULL or *owner is NULL.
1101  *
1102  * Returns:
1103  *
1104  *      The SIG(0) rdataset of 'msg', or NULL if there isn't one.
1105  *
1106  * Ensures:
1107  *
1108  *      If 'owner' is not NULL, it will point to the owner name.
1109  */
1110
1111 isc_result_t
1112 dns_message_setsig0key(dns_message_t *msg, dst_key_t *key);
1113 /*
1114  * Set the SIG(0) key for 'msg'.
1115  *
1116  * Requires:
1117  *
1118  *      'msg' is a valid message with rendering intent,
1119  *      dns_message_renderbegin() has been called, and no sections have been
1120  *      rendered.
1121  *      'key' is a valid sig key or NULL.
1122  *
1123  * Returns:
1124  *
1125  *      ISC_R_SUCCESS           -- all is well.
1126  *
1127  *      ISC_R_NOSPACE           -- there is no space for the SIG(0) record.
1128  */
1129
1130 dst_key_t *
1131 dns_message_getsig0key(dns_message_t *msg);
1132 /*
1133  * Gets the SIG(0) key for 'msg'.
1134  *
1135  * Requires:
1136  *
1137  *      'msg' is a valid message
1138  */
1139
1140 void
1141 dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
1142 /*
1143  * Give the *buffer to the message code to clean up when it is no
1144  * longer needed.  This is usually when the message is reset or
1145  * destroyed.
1146  *
1147  * Requires:
1148  *
1149  *      msg be a valid message.
1150  *
1151  *      buffer != NULL && *buffer is a valid isc_buffer_t, which was
1152  *      dynamincally allocated via isc_buffer_allocate().
1153  */
1154
1155 isc_result_t
1156 dns_message_signer(dns_message_t *msg, dns_name_t *signer);
1157 /*
1158  * If this message was signed, return the identity of the signer.
1159  * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the
1160  * key that signed the message.
1161  *
1162  * Requires:
1163  *
1164  *      msg is a valid parsed message.
1165  *      signer is a valid name
1166  *
1167  * Returns:
1168  *
1169  *      ISC_R_SUCCESS           - the message was signed, and *signer
1170  *                                contains the signing identity
1171  *
1172  *      ISC_R_NOTFOUND          - no TSIG or SIG(0) record is present in the
1173  *                                message
1174  *
1175  *      DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the
1176  *                                signature failed to verify
1177  *
1178  *      DNS_R_TSIGERRORSET      - the message was signed by a TSIG and
1179  *                                verified, but the query was rejected by
1180  *                                the server
1181  *
1182  *      DNS_R_NOIDENTITY        - the message was signed by a TSIG and
1183  *                                verified, but the key has no identity since
1184  *                                it was generated by an unsigned TKEY process
1185  *
1186  *      DNS_R_SIGINVALID        - the message was signed by a SIG(0), but
1187  *                                the signature failed to verify
1188  *
1189  *      DNS_R_SIGNOTVERIFIEDYET - the message was signed by a TSIG or SIG(0),
1190  *                                but the signature has not been verified yet
1191  */
1192
1193 isc_result_t
1194 dns_message_checksig(dns_message_t *msg, dns_view_t *view);
1195 /*
1196  * If this message was signed, verify the signature.
1197  *
1198  * Requires:
1199  *
1200  *      msg is a valid parsed message.
1201  *      view is a valid view or NULL
1202  *
1203  * Returns:
1204  *
1205  *      ISC_R_SUCCESS           - the message was unsigned, or the message
1206  *                                was signed correctly.
1207  *
1208  *      DNS_R_EXPECTEDTSIG      - A TSIG was expected, but not seen
1209  *      DNS_R_UNEXPECTEDTSIG    - A TSIG was seen but not expected
1210  *      DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify
1211  */
1212
1213 isc_region_t *
1214 dns_message_getrawmessage(dns_message_t *msg);
1215 /*
1216  * Retrieve the raw message in compressed wire format.  The message must
1217  * have been successfully parsed for it to have been saved.
1218  *
1219  * Requires:
1220  *      msg is a valid parsed message.
1221  *
1222  * Returns:
1223  *      NULL    if there is no saved message.
1224  *      a pointer to a region which refers the dns message.
1225  */
1226
1227 void
1228 dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
1229                          void *order_arg);
1230 /*
1231  * Define the order in which RR sets get rendered by
1232  * dns_message_rendersection() to be the ascending order
1233  * defined by the integer value returned by 'order' when
1234  * given each RR and 'arg' as arguments.  If 'order' and
1235  * 'order_arg' are NULL, a default order is used.
1236  *
1237  * Requires:
1238  *      msg be a valid message.
1239  *      order_arg is NULL if and only if order is NULL.
1240  */
1241
1242 void 
1243 dns_message_settimeadjust(dns_message_t *msg, int timeadjust);
1244 /*
1245  * Adjust the time used to sign/verify a message by timeadjust.
1246  * Currently only TSIG.
1247  *
1248  * Requires:
1249  *      msg be a valid message.
1250  */
1251
1252 int 
1253 dns_message_gettimeadjust(dns_message_t *msg);
1254 /*
1255  * Return the current time adjustment.
1256  *
1257  * Requires:
1258  *      msg be a valid message.
1259  */
1260
1261 ISC_LANG_ENDDECLS
1262
1263 #endif /* DNS_MESSAGE_H */