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