2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2002 Internet Software Consortium.
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.
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.
18 /* $Id: message.h,v 1.100.2.4 2004/03/09 06:11:19 marka Exp $ */
21 #define DNS_MESSAGE_H 1
28 #include <isc/magic.h>
30 #include <dns/compress.h>
31 #include <dns/masterdump.h>
32 #include <dns/types.h>
37 * How this beast works:
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.
45 * TSIG checking is also done at this layer, and any DNSSEC transaction
46 * signatures should also be checked here.
48 * Notes on using the gettemp*() and puttemp*() functions:
50 * These functions return items (names, rdatasets, etc) allocated from some
51 * internal state of the dns_message_t.
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():
57 * (1) insert it into a section, using dns_message_addname().
59 * (2) return it to the message using dns_message_puttempname().
61 * The same applies to rdatasets.
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
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:
77 * buffer = isc_buffer_allocate(mctx, 512);
79 * name = dns_message_gettempname(message, &name);
80 * dns_name_init(name, NULL);
81 * result = dns_name_fromtext(name, &source, dns_rootname, ISC_FALSE,
83 * dns_message_takebuffer(message, &buffer);
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.
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
100 #define DNS_MESSAGEEXTFLAG_DO 0x8000U
102 #define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD)
103 #define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO)
105 #define DNS_MESSAGE_HEADERLEN 12 /* 6 isc_uint16_t's */
107 #define DNS_MESSAGE_MAGIC ISC_MAGIC('M','S','G','@')
108 #define DNS_MESSAGE_VALID(msg) ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC)
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.
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
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
129 typedef int dns_messagetextflag_t;
130 #define DNS_MESSAGETEXTFLAG_NOCOMMENTS 0x0001
131 #define DNS_MESSAGETEXTFLAG_NOHEADERS 0x0002
134 * Dynamic update names for these sections.
136 #define DNS_SECTION_ZONE DNS_SECTION_QUESTION
137 #define DNS_SECTION_PREREQUISITE DNS_SECTION_ANSWER
138 #define DNS_SECTION_UPDATE DNS_SECTION_AUTHORITY
141 * These tell the message library how the created dns_message_t will be used.
143 #define DNS_MESSAGE_INTENTUNKNOWN 0 /* internal use only */
144 #define DNS_MESSAGE_INTENTPARSE 1 /* parsing messages */
145 #define DNS_MESSAGE_INTENTRENDER 2 /* rendering */
148 * Control behavior of parsing
150 #define DNS_MESSAGEPARSE_PRESERVEORDER 0x0001 /* preserve rdata order */
151 #define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /* return a message if a
152 recoverable parse error
154 #define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /* save a copy of the
156 #define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /* trucation errors are
160 * Control behavior of rendering
162 #define DNS_MESSAGERENDER_ORDERED 0x0001 /* don't change order */
163 #define DNS_MESSAGERENDER_PARTIAL 0x0002 /* allow a partial rdataset */
165 typedef struct dns_msgblock dns_msgblock_t;
168 /* public from here down */
175 dns_rdataclass_t rdclass;
177 /* 4 real, 1 pseudo */
178 unsigned int counts[DNS_SECTION_MAX];
180 /* private from here down */
181 dns_namelist_t sections[DNS_SECTION_MAX];
182 dns_name_t *cursors[DNS_SECTION_MAX];
184 dns_rdataset_t *sig0;
185 dns_rdataset_t *tsig;
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;
197 unsigned int opt_reserved;
198 unsigned int sig_reserved;
199 unsigned int reserved; /* reserved space (render) */
201 isc_buffer_t *buffer;
202 dns_compress_t *cctx;
205 isc_mempool_t *namepool;
206 isc_mempool_t *rdspool;
208 isc_bufferlist_t scratchpad;
209 isc_bufferlist_t cleanup;
211 ISC_LIST(dns_msgblock_t) rdatas;
212 ISC_LIST(dns_msgblock_t) rdatalists;
213 ISC_LIST(dns_msgblock_t) offsets;
215 ISC_LIST(dns_rdata_t) freerdata;
216 ISC_LIST(dns_rdatalist_t) freerdatalist;
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;
227 dns_name_t *sig0name;
229 dns_rcode_t sig0status;
233 dns_rdatasetorderfunc_t order;
244 dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp);
247 * Create msg structure.
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.
253 * 'mctx' be a valid memory context.
255 * 'msgp' be non-null and '*msg' be NULL.
257 * 'intent' must be one of DNS_MESSAGE_INTENTPARSE or
258 * DNS_MESSAGE_INTENTRENDER.
261 * The data in "*msg" is set to indicate an unused and empty msg
265 * ISC_R_NOMEMORY -- out of memory
266 * ISC_R_SUCCESS -- success
270 dns_message_reset(dns_message_t *msg, unsigned int intent);
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.
277 * If any data loanouts (buffers, names, rdatas, etc) were requested,
278 * the caller must no longer use them after this call.
280 * The intended next use of the message will be 'intent'.
286 * 'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER
290 dns_message_destroy(dns_message_t **msgp);
292 * Destroy all state in the message.
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);
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);
315 * Convert section 'section' or 'pseudosection' of message 'msg' to
316 * a cleartext representation
319 * See dns_message_totext for meanings of flags.
323 * 'msg' is a valid message.
325 * 'style' is a valid master dump style.
327 * 'target' is a valid buffer.
329 * 'section' is a valid section label.
333 * If the result is success:
335 * The used space in 'target' is updated.
343 * Note: On error return, *target may be partially filled with data.
347 dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
348 dns_messagetextflag_t flags, isc_buffer_t *target);
350 * Convert all sections of message 'msg' to a cleartext representation
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
362 * 'msg' is a valid message.
364 * 'style' is a valid master dump style.
366 * 'target' is a valid buffer.
370 * If the result is success:
372 * The used space in 'target' is updated.
380 * Note: On error return, *target may be partially filled with data.
384 dns_message_parse(dns_message_t *msg, isc_buffer_t *source,
385 unsigned int options);
387 * Parse raw wire data in 'source' as a DNS message.
389 * OPT records are detected and stored in the pseudo-section "opt".
390 * TSIGs are detected and stored in the pseudo-section "tsig".
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().
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.
405 * If DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete
406 * RR's as possible, DNS_R_RECOVERABLE will be returned.
408 * OPT and TSIG records are always handled specially, regardless of the
409 * 'preserve_order' setting.
414 * "buffer" be a wire format buffer.
417 * The buffer's data format is correct.
419 * The buffer's contents verify as correct regarding header bits, buffer
420 * and rdata sizes, etc.
423 * ISC_R_SUCCESS -- all is well
424 * ISC_R_NOMEMORY -- no memory
425 * DNS_R_RECOVERABLE -- the message parsed properly, but contained
427 * Many other errors possible XXXMLG
431 dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
432 isc_buffer_t *buffer);
434 * Begin rendering on a message. Only one call can be made to this function
437 * The compression context is "owned" by the message library until
438 * dns_message_renderend() is called. It must be invalidated by the caller.
440 * The buffer is "owned" by the message library until dns_message_renderend()
449 * 'buffer' is a valid buffer.
453 * The buffer is cleared before it is used.
456 * ISC_R_SUCCESS -- all is well
457 * ISC_R_NOSPACE -- output buffer is too small
461 dns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer);
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.
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.
474 * dns_message_renderbegin() was called.
479 * ISC_R_NOSPACE -- new buffer is too small
480 * ISC_R_SUCCESS -- all is well.
484 dns_message_renderreserve(dns_message_t *msg, unsigned int space);
486 * XXXMLG should use size_t rather than unsigned int once the buffer
489 * Reserve "space" bytes in the given buffer.
495 * dns_message_renderbegin() was called.
498 * ISC_R_SUCCESS -- all is well.
499 * ISC_R_NOSPACE -- not enough free space in the buffer.
503 dns_message_renderrelease(dns_message_t *msg, unsigned int space);
505 * XXXMLG should use size_t rather than unsigned int once the buffer
508 * Release "space" bytes in the given buffer that was previously reserved.
514 * 'space' is less than or equal to the total amount of space reserved
515 * via prior calls to dns_message_renderreserve().
517 * dns_message_renderbegin() was called.
521 dns_message_rendersection(dns_message_t *msg, dns_section_t section,
522 unsigned int options);
524 * Render all names, rdatalists, etc from the given section at the
525 * specified priority or higher.
530 * 'section' be a valid section.
532 * dns_message_renderbegin() was called.
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.
544 dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target);
546 * Render the message header. This is implicitly called by
547 * dns_message_renderend().
551 * 'msg' be a valid message.
553 * dns_message_renderbegin() was called.
555 * 'target' is a valid buffer with enough space to hold a message header
559 dns_message_renderend(dns_message_t *msg);
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.
567 * 'msg' be a valid message.
569 * dns_message_renderbegin() was called.
572 * ISC_R_SUCCESS -- all is well.
576 dns_message_renderreset(dns_message_t *msg);
578 * Reset the message so that it may be rendered again.
582 * If dns_message_renderbegin() has been called, dns_message_renderend()
583 * must be called before calling this function.
587 * 'msg' be a valid message with rendering intent.
591 dns_message_firstname(dns_message_t *msg, dns_section_t section);
593 * Set internal per-section name pointer to the beginning of the section.
595 * The functions dns_message_firstname() and dns_message_nextname() may
596 * be used for iterating over the owner names in a section.
602 * 'section' be a valid section.
605 * ISC_R_SUCCESS -- All is well.
606 * ISC_R_NOMORE -- No names on given section.
610 dns_message_nextname(dns_message_t *msg, dns_section_t section);
612 * Sets the internal per-section name pointer to point to the next name
619 * 'section' be a valid section.
621 * dns_message_firstname() must have been called on this section,
622 * and the result was ISC_R_SUCCESS.
625 * ISC_R_SUCCESS -- All is well.
626 * ISC_R_NOMORE -- No names in given section.
630 dns_message_currentname(dns_message_t *msg, dns_section_t section,
633 * Sets 'name' to point to the name where the per-section internal name
634 * pointer is currently set.
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.
643 * 'name' be non-NULL, and *name be NULL.
645 * 'section' be a valid section.
647 * dns_message_firstname() must have been called on this section,
648 * and the result of it and any dns_message_nextname() calls was
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);
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).
665 * 'section' be a valid section.
667 * If a pointer to the name is desired, 'foundname' should be non-NULL.
668 * If it is non-NULL, '*foundname' MUST be NULL.
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.
674 * 'target' be a valid name.
676 * 'type' be a valid type.
678 * If 'type' is dns_rdatatype_sig, 'covers' must be a valid type.
679 * Otherwise it should be 0.
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
689 dns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
690 dns_rdatatype_t covers, dns_rdataset_t **rdataset);
692 * Search the name for the specified type. If it is found, *rdataset is
693 * filled in with a pointer to that rdataset.
696 * if '**rdataset' is non-NULL, *rdataset needs to be NULL.
698 * 'type' be a valid type, and NOT dns_rdatatype_any.
700 * If 'type' is dns_rdatatype_sig, 'covers' must be a valid type.
701 * Otherwise it should be 0.
704 * ISC_R_SUCCESS -- all is well.
705 * ISC_R_NOTFOUND -- the desired type does not exist.
709 dns_message_movename(dns_message_t *msg, dns_name_t *name,
710 dns_section_t fromsection,
711 dns_section_t tosection);
713 * Move a name from one section to another.
719 * 'name' must be a name already in 'fromsection'.
721 * 'fromsection' must be a valid section.
723 * 'tosection' must be a valid section.
727 dns_message_addname(dns_message_t *msg, dns_name_t *name,
728 dns_section_t section);
730 * Adds the name to the given section.
732 * It is the caller's responsibility to enforce any unique name requirements
737 * 'msg' be valid, and be a renderable message.
739 * 'name' be a valid name.
741 * 'section' be a named section.
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.
753 dns_message_gettempname(dns_message_t *msg, dns_name_t **item);
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.
760 * It is the caller's responsibility to initialize this name.
763 * msg be a valid message
765 * item != NULL && *item == NULL
768 * ISC_R_SUCCESS -- All is well.
769 * ISC_R_NOMEMORY -- No item can be allocated.
773 dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item);
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.
780 * msg be a valid message
782 * item != NULL && *item == NULL
785 * ISC_R_SUCCESS -- All is well.
786 * ISC_R_NOMEMORY -- No item can be allocated.
790 dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
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.
797 * msg be a valid message
799 * item != NULL && *item == NULL
802 * ISC_R_SUCCESS -- All is well.
803 * ISC_R_NOMEMORY -- No item can be allocated.
807 dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item);
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.
815 * msg be a valid message
817 * item != NULL && *item == NULL
820 * ISC_R_SUCCESS -- All is well.
821 * ISC_R_NOMEMORY -- No item can be allocated.
825 dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
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.
832 * msg be a valid message
834 * item != NULL && *item == NULL
837 * ISC_R_SUCCESS -- All is well.
838 * ISC_R_NOMEMORY -- No item can be allocated.
842 dns_message_puttempname(dns_message_t *msg, dns_name_t **item);
844 * Return a borrowed name to the message's name free list.
847 * msg be a valid message
849 * item != NULL && *item point to a name returned by
850 * dns_message_gettempname()
857 dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item);
859 * Return a borrowed rdata to the message's rdata free list.
862 * msg be a valid message
864 * item != NULL && *item point to a rdata returned by
865 * dns_message_gettemprdata()
872 dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item);
874 * Return a borrowed rdataset to the message's rdataset free list.
877 * msg be a valid message
879 * item != NULL && *item point to a rdataset returned by
880 * dns_message_gettemprdataset()
887 dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item);
889 * Return a borrowed rdatalist to the message's rdatalist free list.
892 * msg be a valid message
894 * item != NULL && *item point to a rdatalist returned by
895 * dns_message_gettemprdatalist()
902 dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
903 unsigned int *flagsp);
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.
914 * if (idp != NULL) *idp == message id.
916 * if (flagsp != NULL) *flagsp == message flags.
920 * ISC_R_SUCCESS -- all is well.
922 * ISC_R_UNEXPECTEDEND -- buffer doesn't contain enough for a header.
926 dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section);
928 * Start formatting a reply to the query in 'msg'.
932 * 'msg' is a valid message with parsing intent, and contains a query.
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.
945 * ISC_R_SUCCESS -- all is well.
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.
957 dns_message_getopt(dns_message_t *msg);
959 * Get the OPT record for 'msg'.
963 * 'msg' is a valid message.
967 * The OPT rdataset of 'msg', or NULL if there isn't one.
971 dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt);
973 * Set the OPT record for 'msg'.
977 * 'msg' is a valid message with rendering intent,
978 * dns_message_renderbegin() has been called, and no sections have been
981 * 'opt' is a valid OPT record.
985 * The OPT record has either been freed or ownership of it has
986 * been transferred to the message.
988 * If ISC_R_SUCCESS was returned, the OPT record will be rendered
989 * when dns_message_renderend() is called.
993 * ISC_R_SUCCESS -- all is well.
995 * ISC_R_NOSPACE -- there is no space for the OPT record.
999 dns_message_gettsig(dns_message_t *msg, dns_name_t **owner);
1001 * Get the TSIG record and owner for 'msg'.
1005 * 'msg' is a valid message.
1006 * 'owner' is NULL or *owner is NULL.
1010 * The TSIG rdataset of 'msg', or NULL if there isn't one.
1014 * If 'owner' is not NULL, it will point to the owner name.
1018 dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key);
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.
1026 * 'msg' is a valid message with rendering intent,
1027 * dns_message_renderbegin() has been called, and no sections have been
1029 * 'key' is a valid tsig key or NULL.
1033 * ISC_R_SUCCESS -- all is well.
1035 * ISC_R_NOSPACE -- there is no space for the TSIG record.
1039 dns_message_gettsigkey(dns_message_t *msg);
1041 * Gets the tsig key for 'msg'.
1045 * 'msg' is a valid message
1049 dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig);
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
1057 * 'querytsig' is a valid buffer as returned by dns_message_getquerytsig()
1060 * 'msg' is a valid message
1069 dns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
1070 isc_buffer_t **querytsig);
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.
1078 * 'msg' is a valid signed message
1079 * 'mctx' is a valid memory context
1080 * querytsig != NULL && *querytsig == NULL
1088 * 'tsig' points to NULL or an allocated buffer which must be freed
1093 dns_message_getsig0(dns_message_t *msg, dns_name_t **owner);
1095 * Get the SIG(0) record and owner for 'msg'.
1099 * 'msg' is a valid message.
1100 * 'owner' is NULL or *owner is NULL.
1104 * The SIG(0) rdataset of 'msg', or NULL if there isn't one.
1108 * If 'owner' is not NULL, it will point to the owner name.
1112 dns_message_setsig0key(dns_message_t *msg, dst_key_t *key);
1114 * Set the SIG(0) key for 'msg'.
1118 * 'msg' is a valid message with rendering intent,
1119 * dns_message_renderbegin() has been called, and no sections have been
1121 * 'key' is a valid sig key or NULL.
1125 * ISC_R_SUCCESS -- all is well.
1127 * ISC_R_NOSPACE -- there is no space for the SIG(0) record.
1131 dns_message_getsig0key(dns_message_t *msg);
1133 * Gets the SIG(0) key for 'msg'.
1137 * 'msg' is a valid message
1141 dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer);
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
1149 * msg be a valid message.
1151 * buffer != NULL && *buffer is a valid isc_buffer_t, which was
1152 * dynamincally allocated via isc_buffer_allocate().
1156 dns_message_signer(dns_message_t *msg, dns_name_t *signer);
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.
1164 * msg is a valid parsed message.
1165 * signer is a valid name
1169 * ISC_R_SUCCESS - the message was signed, and *signer
1170 * contains the signing identity
1172 * ISC_R_NOTFOUND - no TSIG or SIG(0) record is present in the
1175 * DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the
1176 * signature failed to verify
1178 * DNS_R_TSIGERRORSET - the message was signed by a TSIG and
1179 * verified, but the query was rejected by
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
1186 * DNS_R_SIGINVALID - the message was signed by a SIG(0), but
1187 * the signature failed to verify
1189 * DNS_R_SIGNOTVERIFIEDYET - the message was signed by a TSIG or SIG(0),
1190 * but the signature has not been verified yet
1194 dns_message_checksig(dns_message_t *msg, dns_view_t *view);
1196 * If this message was signed, verify the signature.
1200 * msg is a valid parsed message.
1201 * view is a valid view or NULL
1205 * ISC_R_SUCCESS - the message was unsigned, or the message
1206 * was signed correctly.
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
1214 dns_message_getrawmessage(dns_message_t *msg);
1216 * Retrieve the raw message in compressed wire format. The message must
1217 * have been successfully parsed for it to have been saved.
1220 * msg is a valid parsed message.
1223 * NULL if there is no saved message.
1224 * a pointer to a region which refers the dns message.
1228 dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
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.
1238 * msg be a valid message.
1239 * order_arg is NULL if and only if order is NULL.
1243 dns_message_settimeadjust(dns_message_t *msg, int timeadjust);
1245 * Adjust the time used to sign/verify a message by timeadjust.
1246 * Currently only TSIG.
1249 * msg be a valid message.
1253 dns_message_gettimeadjust(dns_message_t *msg);
1255 * Return the current time adjustment.
1258 * msg be a valid message.
1263 #endif /* DNS_MESSAGE_H */