message.h revision 193149
1135446Strhodes/* 2193149Sdougb * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") 3135446Strhodes * Copyright (C) 1999-2003 Internet Software Consortium. 4135446Strhodes * 5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any 6135446Strhodes * purpose with or without fee is hereby granted, provided that the above 7135446Strhodes * copyright notice and this permission notice appear in all copies. 8135446Strhodes * 9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11135446Strhodes * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15135446Strhodes * PERFORMANCE OF THIS SOFTWARE. 16135446Strhodes */ 17135446Strhodes 18193149Sdougb/* $Id: message.h,v 1.125.118.2 2009/01/18 23:47:41 tbox Exp $ */ 19135446Strhodes 20135446Strhodes#ifndef DNS_MESSAGE_H 21135446Strhodes#define DNS_MESSAGE_H 1 22135446Strhodes 23135446Strhodes/*** 24135446Strhodes *** Imports 25135446Strhodes ***/ 26135446Strhodes 27135446Strhodes#include <isc/lang.h> 28135446Strhodes#include <isc/magic.h> 29135446Strhodes 30135446Strhodes#include <dns/compress.h> 31135446Strhodes#include <dns/masterdump.h> 32135446Strhodes#include <dns/types.h> 33135446Strhodes 34135446Strhodes#include <dst/dst.h> 35135446Strhodes 36193149Sdougb/*! \file dns/message.h 37170222Sdougb * \brief Message Handling Module 38170222Sdougb * 39135446Strhodes * How this beast works: 40135446Strhodes * 41135446Strhodes * When a dns message is received in a buffer, dns_message_fromwire() is called 42135446Strhodes * on the memory region. Various items are checked including the format 43135446Strhodes * of the message (if counts are right, if counts consume the entire sections, 44135446Strhodes * and if sections consume the entire message) and known pseudo-RRs in the 45135446Strhodes * additional data section are analyzed and removed. 46135446Strhodes * 47135446Strhodes * TSIG checking is also done at this layer, and any DNSSEC transaction 48135446Strhodes * signatures should also be checked here. 49135446Strhodes * 50135446Strhodes * Notes on using the gettemp*() and puttemp*() functions: 51135446Strhodes * 52135446Strhodes * These functions return items (names, rdatasets, etc) allocated from some 53135446Strhodes * internal state of the dns_message_t. 54135446Strhodes * 55135446Strhodes * Names and rdatasets must be put back into the dns_message_t in 56135446Strhodes * one of two ways. Assume a name was allocated via 57135446Strhodes * dns_message_gettempname(): 58135446Strhodes * 59170222Sdougb *\li (1) insert it into a section, using dns_message_addname(). 60135446Strhodes * 61170222Sdougb *\li (2) return it to the message using dns_message_puttempname(). 62135446Strhodes * 63135446Strhodes * The same applies to rdatasets. 64135446Strhodes * 65135446Strhodes * On the other hand, offsets, rdatalists and rdatas allocated using 66135446Strhodes * dns_message_gettemp*() will always be freed automatically 67135446Strhodes * when the message is reset or destroyed; calling dns_message_puttemp*() 68135446Strhodes * on rdatalists and rdatas is optional and serves only to enable the item 69135446Strhodes * to be reused multiple times during the lifetime of the message; offsets 70135446Strhodes * cannot be reused. 71135446Strhodes * 72135446Strhodes * Buffers allocated using isc_buffer_allocate() can be automatically freed 73135446Strhodes * as well by giving the buffer to the message using dns_message_takebuffer(). 74135446Strhodes * Doing this will cause the buffer to be freed using isc_buffer_free() 75135446Strhodes * when the section lists are cleared, such as in a reset or in a destroy. 76135446Strhodes * Since the buffer itself exists until the message is destroyed, this sort 77135446Strhodes * of code can be written: 78135446Strhodes * 79170222Sdougb * \code 80135446Strhodes * buffer = isc_buffer_allocate(mctx, 512); 81135446Strhodes * name = NULL; 82135446Strhodes * name = dns_message_gettempname(message, &name); 83135446Strhodes * dns_name_init(name, NULL); 84135446Strhodes * result = dns_name_fromtext(name, &source, dns_rootname, ISC_FALSE, 85135446Strhodes * buffer); 86135446Strhodes * dns_message_takebuffer(message, &buffer); 87170222Sdougb * \endcode 88135446Strhodes * 89135446Strhodes * 90135446Strhodes * TODO: 91135446Strhodes * 92135446Strhodes * XXX Needed: ways to set and retrieve EDNS information, add rdata to a 93135446Strhodes * section, move rdata from one section to another, remove rdata, etc. 94135446Strhodes */ 95135446Strhodes 96135446Strhodes#define DNS_MESSAGEFLAG_QR 0x8000U 97135446Strhodes#define DNS_MESSAGEFLAG_AA 0x0400U 98135446Strhodes#define DNS_MESSAGEFLAG_TC 0x0200U 99135446Strhodes#define DNS_MESSAGEFLAG_RD 0x0100U 100135446Strhodes#define DNS_MESSAGEFLAG_RA 0x0080U 101135446Strhodes#define DNS_MESSAGEFLAG_AD 0x0020U 102135446Strhodes#define DNS_MESSAGEFLAG_CD 0x0010U 103135446Strhodes 104193149Sdougb/*%< EDNS0 extended message flags */ 105135446Strhodes#define DNS_MESSAGEEXTFLAG_DO 0x8000U 106135446Strhodes 107193149Sdougb/*%< EDNS0 extended OPT codes */ 108193149Sdougb#define DNS_OPT_NSID 0x0003 /*%< NSID opt code */ 109193149Sdougb 110135446Strhodes#define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD) 111135446Strhodes#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO) 112135446Strhodes 113170222Sdougb#define DNS_MESSAGE_HEADERLEN 12 /*%< 6 isc_uint16_t's */ 114135446Strhodes 115135446Strhodes#define DNS_MESSAGE_MAGIC ISC_MAGIC('M','S','G','@') 116135446Strhodes#define DNS_MESSAGE_VALID(msg) ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC) 117135446Strhodes 118135446Strhodes/* 119135446Strhodes * Ordering here matters. DNS_SECTION_ANY must be the lowest and negative, 120135446Strhodes * and DNS_SECTION_MAX must be one greater than the last used section. 121135446Strhodes */ 122135446Strhodestypedef int dns_section_t; 123135446Strhodes#define DNS_SECTION_ANY (-1) 124135446Strhodes#define DNS_SECTION_QUESTION 0 125135446Strhodes#define DNS_SECTION_ANSWER 1 126135446Strhodes#define DNS_SECTION_AUTHORITY 2 127135446Strhodes#define DNS_SECTION_ADDITIONAL 3 128135446Strhodes#define DNS_SECTION_MAX 4 129135446Strhodes 130135446Strhodestypedef int dns_pseudosection_t; 131135446Strhodes#define DNS_PSEUDOSECTION_ANY (-1) 132135446Strhodes#define DNS_PSEUDOSECTION_OPT 0 133135446Strhodes#define DNS_PSEUDOSECTION_TSIG 1 134135446Strhodes#define DNS_PSEUDOSECTION_SIG0 2 135135446Strhodes#define DNS_PSEUDOSECTION_MAX 3 136135446Strhodes 137135446Strhodestypedef int dns_messagetextflag_t; 138135446Strhodes#define DNS_MESSAGETEXTFLAG_NOCOMMENTS 0x0001 139135446Strhodes#define DNS_MESSAGETEXTFLAG_NOHEADERS 0x0002 140135446Strhodes 141135446Strhodes/* 142135446Strhodes * Dynamic update names for these sections. 143135446Strhodes */ 144135446Strhodes#define DNS_SECTION_ZONE DNS_SECTION_QUESTION 145135446Strhodes#define DNS_SECTION_PREREQUISITE DNS_SECTION_ANSWER 146135446Strhodes#define DNS_SECTION_UPDATE DNS_SECTION_AUTHORITY 147135446Strhodes 148135446Strhodes/* 149135446Strhodes * These tell the message library how the created dns_message_t will be used. 150135446Strhodes */ 151170222Sdougb#define DNS_MESSAGE_INTENTUNKNOWN 0 /*%< internal use only */ 152170222Sdougb#define DNS_MESSAGE_INTENTPARSE 1 /*%< parsing messages */ 153170222Sdougb#define DNS_MESSAGE_INTENTRENDER 2 /*%< rendering */ 154135446Strhodes 155135446Strhodes/* 156135446Strhodes * Control behavior of parsing 157135446Strhodes */ 158170222Sdougb#define DNS_MESSAGEPARSE_PRESERVEORDER 0x0001 /*%< preserve rdata order */ 159170222Sdougb#define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /*%< return a message if a 160135446Strhodes recoverable parse error 161135446Strhodes occurs */ 162170222Sdougb#define DNS_MESSAGEPARSE_CLONEBUFFER 0x0004 /*%< save a copy of the 163135446Strhodes source buffer */ 164193149Sdougb#define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< truncation errors are 165135446Strhodes * not fatal. */ 166135446Strhodes 167135446Strhodes/* 168135446Strhodes * Control behavior of rendering 169135446Strhodes */ 170170222Sdougb#define DNS_MESSAGERENDER_ORDERED 0x0001 /*%< don't change order */ 171170222Sdougb#define DNS_MESSAGERENDER_PARTIAL 0x0002 /*%< allow a partial rdataset */ 172170222Sdougb#define DNS_MESSAGERENDER_OMITDNSSEC 0x0004 /*%< omit DNSSEC records */ 173170222Sdougb#define DNS_MESSAGERENDER_PREFER_A 0x0008 /*%< prefer A records in 174170222Sdougb additional section. */ 175170222Sdougb#define DNS_MESSAGERENDER_PREFER_AAAA 0x0010 /*%< prefer AAAA records in 176170222Sdougb additional section. */ 177135446Strhodes 178135446Strhodestypedef struct dns_msgblock dns_msgblock_t; 179135446Strhodes 180135446Strhodesstruct dns_message { 181135446Strhodes /* public from here down */ 182135446Strhodes unsigned int magic; 183135446Strhodes 184135446Strhodes dns_messageid_t id; 185135446Strhodes unsigned int flags; 186135446Strhodes dns_rcode_t rcode; 187135446Strhodes unsigned int opcode; 188135446Strhodes dns_rdataclass_t rdclass; 189135446Strhodes 190135446Strhodes /* 4 real, 1 pseudo */ 191135446Strhodes unsigned int counts[DNS_SECTION_MAX]; 192135446Strhodes 193135446Strhodes /* private from here down */ 194135446Strhodes dns_namelist_t sections[DNS_SECTION_MAX]; 195135446Strhodes dns_name_t *cursors[DNS_SECTION_MAX]; 196135446Strhodes dns_rdataset_t *opt; 197135446Strhodes dns_rdataset_t *sig0; 198135446Strhodes dns_rdataset_t *tsig; 199135446Strhodes 200135446Strhodes int state; 201135446Strhodes unsigned int from_to_wire : 2; 202135446Strhodes unsigned int header_ok : 1; 203135446Strhodes unsigned int question_ok : 1; 204135446Strhodes unsigned int tcp_continuation : 1; 205135446Strhodes unsigned int verified_sig : 1; 206135446Strhodes unsigned int verify_attempted : 1; 207135446Strhodes unsigned int free_query : 1; 208135446Strhodes unsigned int free_saved : 1; 209135446Strhodes 210135446Strhodes unsigned int opt_reserved; 211135446Strhodes unsigned int sig_reserved; 212135446Strhodes unsigned int reserved; /* reserved space (render) */ 213135446Strhodes 214135446Strhodes isc_buffer_t *buffer; 215135446Strhodes dns_compress_t *cctx; 216135446Strhodes 217135446Strhodes isc_mem_t *mctx; 218135446Strhodes isc_mempool_t *namepool; 219135446Strhodes isc_mempool_t *rdspool; 220135446Strhodes 221135446Strhodes isc_bufferlist_t scratchpad; 222135446Strhodes isc_bufferlist_t cleanup; 223135446Strhodes 224135446Strhodes ISC_LIST(dns_msgblock_t) rdatas; 225135446Strhodes ISC_LIST(dns_msgblock_t) rdatalists; 226135446Strhodes ISC_LIST(dns_msgblock_t) offsets; 227135446Strhodes 228135446Strhodes ISC_LIST(dns_rdata_t) freerdata; 229135446Strhodes ISC_LIST(dns_rdatalist_t) freerdatalist; 230135446Strhodes 231135446Strhodes dns_rcode_t tsigstatus; 232135446Strhodes dns_rcode_t querytsigstatus; 233135446Strhodes dns_name_t *tsigname; /* Owner name of TSIG, if any */ 234135446Strhodes dns_rdataset_t *querytsig; 235135446Strhodes dns_tsigkey_t *tsigkey; 236135446Strhodes dst_context_t *tsigctx; 237135446Strhodes int sigstart; 238135446Strhodes int timeadjust; 239135446Strhodes 240135446Strhodes dns_name_t *sig0name; /* Owner name of SIG0, if any */ 241135446Strhodes dst_key_t *sig0key; 242135446Strhodes dns_rcode_t sig0status; 243135446Strhodes isc_region_t query; 244135446Strhodes isc_region_t saved; 245135446Strhodes 246135446Strhodes dns_rdatasetorderfunc_t order; 247165071Sdougb const void * order_arg; 248135446Strhodes}; 249135446Strhodes 250135446Strhodes/*** 251135446Strhodes *** Functions 252135446Strhodes ***/ 253135446Strhodes 254135446StrhodesISC_LANG_BEGINDECLS 255135446Strhodes 256135446Strhodesisc_result_t 257135446Strhodesdns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp); 258135446Strhodes 259170222Sdougb/*%< 260135446Strhodes * Create msg structure. 261135446Strhodes * 262135446Strhodes * This function will allocate some internal blocks of memory that are 263135446Strhodes * expected to be needed for parsing or rendering nearly any type of message. 264135446Strhodes * 265135446Strhodes * Requires: 266170222Sdougb *\li 'mctx' be a valid memory context. 267135446Strhodes * 268170222Sdougb *\li 'msgp' be non-null and '*msg' be NULL. 269135446Strhodes * 270170222Sdougb *\li 'intent' must be one of DNS_MESSAGE_INTENTPARSE or 271170222Sdougb * #DNS_MESSAGE_INTENTRENDER. 272135446Strhodes * 273135446Strhodes * Ensures: 274170222Sdougb *\li The data in "*msg" is set to indicate an unused and empty msg 275135446Strhodes * structure. 276135446Strhodes * 277135446Strhodes * Returns: 278170222Sdougb *\li #ISC_R_NOMEMORY -- out of memory 279170222Sdougb *\li #ISC_R_SUCCESS -- success 280135446Strhodes */ 281135446Strhodes 282135446Strhodesvoid 283135446Strhodesdns_message_reset(dns_message_t *msg, unsigned int intent); 284170222Sdougb/*%< 285135446Strhodes * Reset a message structure to default state. All internal lists are freed 286135446Strhodes * or reset to a default state as well. This is simply a more efficient 287135446Strhodes * way to call dns_message_destroy() followed by dns_message_allocate(), 288135446Strhodes * since it avoid many memory allocations. 289135446Strhodes * 290135446Strhodes * If any data loanouts (buffers, names, rdatas, etc) were requested, 291135446Strhodes * the caller must no longer use them after this call. 292135446Strhodes * 293135446Strhodes * The intended next use of the message will be 'intent'. 294135446Strhodes * 295135446Strhodes * Requires: 296135446Strhodes * 297170222Sdougb *\li 'msg' be valid. 298135446Strhodes * 299170222Sdougb *\li 'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER 300135446Strhodes */ 301135446Strhodes 302135446Strhodesvoid 303135446Strhodesdns_message_destroy(dns_message_t **msgp); 304170222Sdougb/*%< 305135446Strhodes * Destroy all state in the message. 306135446Strhodes * 307135446Strhodes * Requires: 308135446Strhodes * 309170222Sdougb *\li 'msgp' be valid. 310135446Strhodes * 311135446Strhodes * Ensures: 312170222Sdougb *\li '*msgp' == NULL 313135446Strhodes */ 314135446Strhodes 315135446Strhodesisc_result_t 316135446Strhodesdns_message_sectiontotext(dns_message_t *msg, dns_section_t section, 317135446Strhodes const dns_master_style_t *style, 318135446Strhodes dns_messagetextflag_t flags, 319135446Strhodes isc_buffer_t *target); 320135446Strhodes 321135446Strhodesisc_result_t 322135446Strhodesdns_message_pseudosectiontotext(dns_message_t *msg, 323135446Strhodes dns_pseudosection_t section, 324135446Strhodes const dns_master_style_t *style, 325135446Strhodes dns_messagetextflag_t flags, 326135446Strhodes isc_buffer_t *target); 327170222Sdougb/*%< 328135446Strhodes * Convert section 'section' or 'pseudosection' of message 'msg' to 329135446Strhodes * a cleartext representation 330135446Strhodes * 331135446Strhodes * Notes: 332170222Sdougb * \li See dns_message_totext for meanings of flags. 333135446Strhodes * 334135446Strhodes * Requires: 335135446Strhodes * 336170222Sdougb *\li 'msg' is a valid message. 337135446Strhodes * 338170222Sdougb *\li 'style' is a valid master dump style. 339135446Strhodes * 340170222Sdougb *\li 'target' is a valid buffer. 341135446Strhodes * 342170222Sdougb *\li 'section' is a valid section label. 343135446Strhodes * 344135446Strhodes * Ensures: 345135446Strhodes * 346170222Sdougb *\li If the result is success: 347135446Strhodes * The used space in 'target' is updated. 348135446Strhodes * 349135446Strhodes * Returns: 350135446Strhodes * 351170222Sdougb *\li #ISC_R_SUCCESS 352170222Sdougb *\li #ISC_R_NOSPACE 353170222Sdougb *\li #ISC_R_NOMORE 354135446Strhodes * 355170222Sdougb *\li Note: On error return, *target may be partially filled with data. 356135446Strhodes*/ 357135446Strhodes 358135446Strhodesisc_result_t 359135446Strhodesdns_message_totext(dns_message_t *msg, const dns_master_style_t *style, 360135446Strhodes dns_messagetextflag_t flags, isc_buffer_t *target); 361170222Sdougb/*%< 362135446Strhodes * Convert all sections of message 'msg' to a cleartext representation 363135446Strhodes * 364135446Strhodes * Notes: 365170222Sdougb * \li In flags, If #DNS_MESSAGETEXTFLAG_OMITDOT is set, then the 366135446Strhodes * final '.' in absolute names will not be emitted. If 367170222Sdougb * #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning 368135446Strhodes * with ";;" will be emitted indicating section name. If 369170222Sdougb * #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will 370135446Strhodes * be emitted. 371135446Strhodes * 372135446Strhodes * Requires: 373135446Strhodes * 374170222Sdougb *\li 'msg' is a valid message. 375135446Strhodes * 376170222Sdougb *\li 'style' is a valid master dump style. 377135446Strhodes * 378170222Sdougb *\li 'target' is a valid buffer. 379135446Strhodes * 380135446Strhodes * Ensures: 381135446Strhodes * 382170222Sdougb *\li If the result is success: 383135446Strhodes * The used space in 'target' is updated. 384135446Strhodes * 385135446Strhodes * Returns: 386135446Strhodes * 387170222Sdougb *\li #ISC_R_SUCCESS 388170222Sdougb *\li #ISC_R_NOSPACE 389170222Sdougb *\li #ISC_R_NOMORE 390135446Strhodes * 391170222Sdougb *\li Note: On error return, *target may be partially filled with data. 392135446Strhodes */ 393135446Strhodes 394135446Strhodesisc_result_t 395135446Strhodesdns_message_parse(dns_message_t *msg, isc_buffer_t *source, 396135446Strhodes unsigned int options); 397170222Sdougb/*%< 398135446Strhodes * Parse raw wire data in 'source' as a DNS message. 399135446Strhodes * 400135446Strhodes * OPT records are detected and stored in the pseudo-section "opt". 401135446Strhodes * TSIGs are detected and stored in the pseudo-section "tsig". 402135446Strhodes * 403170222Sdougb * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message 404135446Strhodes * is UPDATE, a separate dns_name_t object will be created for each RR in the 405135446Strhodes * message. Each such dns_name_t will have a single rdataset containing the 406135446Strhodes * single RR, and the order of the RRs in the message is preserved. 407135446Strhodes * Otherwise, only one dns_name_t object will be created for each unique 408135446Strhodes * owner name in the section, and each such dns_name_t will have a list 409135446Strhodes * of rdatasets. To access the names and their data, use 410135446Strhodes * dns_message_firstname() and dns_message_nextname(). 411135446Strhodes * 412170222Sdougb * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will 413135446Strhodes * not be considered FORMERRs. If the entire message can be parsed, it 414135446Strhodes * will be returned and DNS_R_RECOVERABLE will be returned. 415135446Strhodes * 416170222Sdougb * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete 417135446Strhodes * RR's as possible, DNS_R_RECOVERABLE will be returned. 418135446Strhodes * 419135446Strhodes * OPT and TSIG records are always handled specially, regardless of the 420135446Strhodes * 'preserve_order' setting. 421135446Strhodes * 422135446Strhodes * Requires: 423170222Sdougb *\li "msg" be valid. 424135446Strhodes * 425170222Sdougb *\li "buffer" be a wire format buffer. 426135446Strhodes * 427135446Strhodes * Ensures: 428170222Sdougb *\li The buffer's data format is correct. 429135446Strhodes * 430170222Sdougb *\li The buffer's contents verify as correct regarding header bits, buffer 431135446Strhodes * and rdata sizes, etc. 432135446Strhodes * 433135446Strhodes * Returns: 434170222Sdougb *\li #ISC_R_SUCCESS -- all is well 435170222Sdougb *\li #ISC_R_NOMEMORY -- no memory 436170222Sdougb *\li #DNS_R_RECOVERABLE -- the message parsed properly, but contained 437135446Strhodes * errors. 438170222Sdougb *\li Many other errors possible XXXMLG 439135446Strhodes */ 440135446Strhodes 441135446Strhodesisc_result_t 442135446Strhodesdns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx, 443135446Strhodes isc_buffer_t *buffer); 444170222Sdougb/*%< 445135446Strhodes * Begin rendering on a message. Only one call can be made to this function 446135446Strhodes * per message. 447135446Strhodes * 448135446Strhodes * The compression context is "owned" by the message library until 449135446Strhodes * dns_message_renderend() is called. It must be invalidated by the caller. 450135446Strhodes * 451135446Strhodes * The buffer is "owned" by the message library until dns_message_renderend() 452135446Strhodes * is called. 453135446Strhodes * 454135446Strhodes * Requires: 455135446Strhodes * 456170222Sdougb *\li 'msg' be valid. 457135446Strhodes * 458170222Sdougb *\li 'cctx' be valid. 459135446Strhodes * 460170222Sdougb *\li 'buffer' is a valid buffer. 461135446Strhodes * 462135446Strhodes * Side Effects: 463135446Strhodes * 464170222Sdougb *\li The buffer is cleared before it is used. 465135446Strhodes * 466135446Strhodes * Returns: 467170222Sdougb *\li #ISC_R_SUCCESS -- all is well 468170222Sdougb *\li #ISC_R_NOSPACE -- output buffer is too small 469135446Strhodes */ 470135446Strhodes 471135446Strhodesisc_result_t 472135446Strhodesdns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer); 473170222Sdougb/*%< 474135446Strhodes * Reset the buffer. This can be used after growing the old buffer 475135446Strhodes * on a ISC_R_NOSPACE return from most of the render functions. 476135446Strhodes * 477135446Strhodes * On successful completion, the old buffer is no longer used by the 478135446Strhodes * library. The new buffer is owned by the library until 479135446Strhodes * dns_message_renderend() is called. 480135446Strhodes * 481135446Strhodes * Requires: 482135446Strhodes * 483170222Sdougb *\li 'msg' be valid. 484135446Strhodes * 485170222Sdougb *\li dns_message_renderbegin() was called. 486135446Strhodes * 487170222Sdougb *\li buffer != NULL. 488135446Strhodes * 489135446Strhodes * Returns: 490170222Sdougb *\li #ISC_R_NOSPACE -- new buffer is too small 491170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 492135446Strhodes */ 493135446Strhodes 494135446Strhodesisc_result_t 495135446Strhodesdns_message_renderreserve(dns_message_t *msg, unsigned int space); 496170222Sdougb/*%< 497135446Strhodes * XXXMLG should use size_t rather than unsigned int once the buffer 498135446Strhodes * API is cleaned up 499135446Strhodes * 500135446Strhodes * Reserve "space" bytes in the given buffer. 501135446Strhodes * 502135446Strhodes * Requires: 503135446Strhodes * 504170222Sdougb *\li 'msg' be valid. 505135446Strhodes * 506170222Sdougb *\li dns_message_renderbegin() was called. 507135446Strhodes * 508135446Strhodes * Returns: 509170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 510170222Sdougb *\li #ISC_R_NOSPACE -- not enough free space in the buffer. 511135446Strhodes */ 512135446Strhodes 513135446Strhodesvoid 514135446Strhodesdns_message_renderrelease(dns_message_t *msg, unsigned int space); 515170222Sdougb/*%< 516135446Strhodes * XXXMLG should use size_t rather than unsigned int once the buffer 517135446Strhodes * API is cleaned up 518135446Strhodes * 519135446Strhodes * Release "space" bytes in the given buffer that was previously reserved. 520135446Strhodes * 521135446Strhodes * Requires: 522135446Strhodes * 523170222Sdougb *\li 'msg' be valid. 524135446Strhodes * 525170222Sdougb *\li 'space' is less than or equal to the total amount of space reserved 526135446Strhodes * via prior calls to dns_message_renderreserve(). 527135446Strhodes * 528170222Sdougb *\li dns_message_renderbegin() was called. 529135446Strhodes */ 530135446Strhodes 531135446Strhodesisc_result_t 532135446Strhodesdns_message_rendersection(dns_message_t *msg, dns_section_t section, 533135446Strhodes unsigned int options); 534170222Sdougb/*%< 535135446Strhodes * Render all names, rdatalists, etc from the given section at the 536135446Strhodes * specified priority or higher. 537135446Strhodes * 538135446Strhodes * Requires: 539170222Sdougb *\li 'msg' be valid. 540135446Strhodes * 541170222Sdougb *\li 'section' be a valid section. 542135446Strhodes * 543170222Sdougb *\li dns_message_renderbegin() was called. 544135446Strhodes * 545135446Strhodes * Returns: 546170222Sdougb *\li #ISC_R_SUCCESS -- all records were written, and there are 547135446Strhodes * no more records for this section. 548170222Sdougb *\li #ISC_R_NOSPACE -- Not enough room in the buffer to write 549135446Strhodes * all records requested. 550170222Sdougb *\li #DNS_R_MOREDATA -- All requested records written, and there 551135446Strhodes * are records remaining for this section. 552135446Strhodes */ 553135446Strhodes 554135446Strhodesvoid 555135446Strhodesdns_message_renderheader(dns_message_t *msg, isc_buffer_t *target); 556170222Sdougb/*%< 557135446Strhodes * Render the message header. This is implicitly called by 558135446Strhodes * dns_message_renderend(). 559135446Strhodes * 560135446Strhodes * Requires: 561135446Strhodes * 562170222Sdougb *\li 'msg' be a valid message. 563135446Strhodes * 564170222Sdougb *\li dns_message_renderbegin() was called. 565135446Strhodes * 566170222Sdougb *\li 'target' is a valid buffer with enough space to hold a message header 567135446Strhodes */ 568135446Strhodes 569135446Strhodesisc_result_t 570135446Strhodesdns_message_renderend(dns_message_t *msg); 571170222Sdougb/*%< 572135446Strhodes * Finish rendering to the buffer. Note that more data can be in the 573135446Strhodes * 'msg' structure. Destroying the structure will free this, or in a multi- 574135446Strhodes * part EDNS1 message this data can be rendered to another buffer later. 575135446Strhodes * 576135446Strhodes * Requires: 577135446Strhodes * 578170222Sdougb *\li 'msg' be a valid message. 579135446Strhodes * 580170222Sdougb *\li dns_message_renderbegin() was called. 581135446Strhodes * 582135446Strhodes * Returns: 583170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 584135446Strhodes */ 585135446Strhodes 586135446Strhodesvoid 587135446Strhodesdns_message_renderreset(dns_message_t *msg); 588170222Sdougb/*%< 589135446Strhodes * Reset the message so that it may be rendered again. 590135446Strhodes * 591135446Strhodes * Notes: 592135446Strhodes * 593170222Sdougb *\li If dns_message_renderbegin() has been called, dns_message_renderend() 594135446Strhodes * must be called before calling this function. 595135446Strhodes * 596135446Strhodes * Requires: 597135446Strhodes * 598170222Sdougb *\li 'msg' be a valid message with rendering intent. 599135446Strhodes */ 600135446Strhodes 601135446Strhodesisc_result_t 602135446Strhodesdns_message_firstname(dns_message_t *msg, dns_section_t section); 603170222Sdougb/*%< 604135446Strhodes * Set internal per-section name pointer to the beginning of the section. 605135446Strhodes * 606135446Strhodes * The functions dns_message_firstname() and dns_message_nextname() may 607135446Strhodes * be used for iterating over the owner names in a section. 608135446Strhodes * 609135446Strhodes * Requires: 610135446Strhodes * 611170222Sdougb *\li 'msg' be valid. 612135446Strhodes * 613170222Sdougb *\li 'section' be a valid section. 614135446Strhodes * 615135446Strhodes * Returns: 616170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 617170222Sdougb *\li #ISC_R_NOMORE -- No names on given section. 618135446Strhodes */ 619135446Strhodes 620135446Strhodesisc_result_t 621135446Strhodesdns_message_nextname(dns_message_t *msg, dns_section_t section); 622170222Sdougb/*%< 623135446Strhodes * Sets the internal per-section name pointer to point to the next name 624135446Strhodes * in that section. 625135446Strhodes * 626135446Strhodes * Requires: 627135446Strhodes * 628170222Sdougb * \li 'msg' be valid. 629135446Strhodes * 630170222Sdougb *\li 'section' be a valid section. 631135446Strhodes * 632170222Sdougb *\li dns_message_firstname() must have been called on this section, 633135446Strhodes * and the result was ISC_R_SUCCESS. 634135446Strhodes * 635135446Strhodes * Returns: 636170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 637170222Sdougb *\li #ISC_R_NOMORE -- No more names in given section. 638135446Strhodes */ 639135446Strhodes 640135446Strhodesvoid 641135446Strhodesdns_message_currentname(dns_message_t *msg, dns_section_t section, 642135446Strhodes dns_name_t **name); 643170222Sdougb/*%< 644135446Strhodes * Sets 'name' to point to the name where the per-section internal name 645135446Strhodes * pointer is currently set. 646135446Strhodes * 647135446Strhodes * This function returns the name in the database, so any data associated 648135446Strhodes * with it (via the name's "list" member) contains the actual rdatasets. 649135446Strhodes * 650135446Strhodes * Requires: 651135446Strhodes * 652170222Sdougb *\li 'msg' be valid. 653135446Strhodes * 654170222Sdougb *\li 'name' be non-NULL, and *name be NULL. 655135446Strhodes * 656170222Sdougb *\li 'section' be a valid section. 657135446Strhodes * 658170222Sdougb *\li dns_message_firstname() must have been called on this section, 659135446Strhodes * and the result of it and any dns_message_nextname() calls was 660170222Sdougb * #ISC_R_SUCCESS. 661135446Strhodes */ 662135446Strhodes 663135446Strhodesisc_result_t 664135446Strhodesdns_message_findname(dns_message_t *msg, dns_section_t section, 665135446Strhodes dns_name_t *target, dns_rdatatype_t type, 666135446Strhodes dns_rdatatype_t covers, dns_name_t **foundname, 667135446Strhodes dns_rdataset_t **rdataset); 668170222Sdougb/*%< 669135446Strhodes * Search for a name in the specified section. If it is found, *name is 670135446Strhodes * set to point to the name, and *rdataset is set to point to the found 671135446Strhodes * rdataset (if type is specified as other than dns_rdatatype_any). 672135446Strhodes * 673135446Strhodes * Requires: 674170222Sdougb *\li 'msg' be valid. 675135446Strhodes * 676170222Sdougb *\li 'section' be a valid section. 677135446Strhodes * 678170222Sdougb *\li If a pointer to the name is desired, 'foundname' should be non-NULL. 679135446Strhodes * If it is non-NULL, '*foundname' MUST be NULL. 680135446Strhodes * 681170222Sdougb *\li If a type other than dns_datatype_any is searched for, 'rdataset' 682135446Strhodes * may be non-NULL, '*rdataset' be NULL, and will point at the found 683135446Strhodes * rdataset. If the type is dns_datatype_any, 'rdataset' must be NULL. 684135446Strhodes * 685170222Sdougb *\li 'target' be a valid name. 686135446Strhodes * 687170222Sdougb *\li 'type' be a valid type. 688135446Strhodes * 689170222Sdougb *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 690135446Strhodes * Otherwise it should be 0. 691135446Strhodes * 692135446Strhodes * Returns: 693170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 694170222Sdougb *\li #DNS_R_NXDOMAIN -- name does not exist in that section. 695170222Sdougb *\li #DNS_R_NXRRSET -- The name does exist, but the desired 696135446Strhodes * type does not. 697135446Strhodes */ 698135446Strhodes 699135446Strhodesisc_result_t 700135446Strhodesdns_message_findtype(dns_name_t *name, dns_rdatatype_t type, 701135446Strhodes dns_rdatatype_t covers, dns_rdataset_t **rdataset); 702170222Sdougb/*%< 703135446Strhodes * Search the name for the specified type. If it is found, *rdataset is 704135446Strhodes * filled in with a pointer to that rdataset. 705135446Strhodes * 706135446Strhodes * Requires: 707170222Sdougb *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. 708135446Strhodes * 709170222Sdougb *\li 'type' be a valid type, and NOT dns_rdatatype_any. 710135446Strhodes * 711170222Sdougb *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 712135446Strhodes * Otherwise it should be 0. 713135446Strhodes * 714135446Strhodes * Returns: 715170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 716170222Sdougb *\li #ISC_R_NOTFOUND -- the desired type does not exist. 717135446Strhodes */ 718135446Strhodes 719165071Sdougbisc_result_t 720165071Sdougbdns_message_find(dns_name_t *name, dns_rdataclass_t rdclass, 721165071Sdougb dns_rdatatype_t type, dns_rdatatype_t covers, 722165071Sdougb dns_rdataset_t **rdataset); 723165071Sdougb/*%< 724165071Sdougb * Search the name for the specified rdclass and type. If it is found, 725165071Sdougb * *rdataset is filled in with a pointer to that rdataset. 726165071Sdougb * 727165071Sdougb * Requires: 728165071Sdougb *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. 729165071Sdougb * 730165071Sdougb *\li 'type' be a valid type, and NOT dns_rdatatype_any. 731165071Sdougb * 732165071Sdougb *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 733165071Sdougb * Otherwise it should be 0. 734165071Sdougb * 735165071Sdougb * Returns: 736165071Sdougb *\li #ISC_R_SUCCESS -- all is well. 737165071Sdougb *\li #ISC_R_NOTFOUND -- the desired type does not exist. 738165071Sdougb */ 739165071Sdougb 740135446Strhodesvoid 741135446Strhodesdns_message_movename(dns_message_t *msg, dns_name_t *name, 742135446Strhodes dns_section_t fromsection, 743135446Strhodes dns_section_t tosection); 744170222Sdougb/*%< 745135446Strhodes * Move a name from one section to another. 746135446Strhodes * 747135446Strhodes * Requires: 748135446Strhodes * 749170222Sdougb *\li 'msg' be valid. 750135446Strhodes * 751170222Sdougb *\li 'name' must be a name already in 'fromsection'. 752135446Strhodes * 753170222Sdougb *\li 'fromsection' must be a valid section. 754135446Strhodes * 755170222Sdougb *\li 'tosection' must be a valid section. 756135446Strhodes */ 757135446Strhodes 758135446Strhodesvoid 759135446Strhodesdns_message_addname(dns_message_t *msg, dns_name_t *name, 760135446Strhodes dns_section_t section); 761170222Sdougb/*%< 762135446Strhodes * Adds the name to the given section. 763135446Strhodes * 764135446Strhodes * It is the caller's responsibility to enforce any unique name requirements 765135446Strhodes * in a section. 766135446Strhodes * 767135446Strhodes * Requires: 768135446Strhodes * 769170222Sdougb *\li 'msg' be valid, and be a renderable message. 770135446Strhodes * 771170222Sdougb *\li 'name' be a valid absolute name. 772135446Strhodes * 773170222Sdougb *\li 'section' be a named section. 774135446Strhodes */ 775135446Strhodes 776170222Sdougbvoid 777170222Sdougbdns_message_removename(dns_message_t *msg, dns_name_t *name, 778193149Sdougb dns_section_t section); 779170222Sdougb/*%< 780170222Sdougb * Remove a existing name from a given section. 781170222Sdougb * 782170222Sdougb * It is the caller's responsibility to ensure the name is part of the 783170222Sdougb * given section. 784170222Sdougb * 785170222Sdougb * Requires: 786170222Sdougb * 787170222Sdougb *\li 'msg' be valid, and be a renderable message. 788170222Sdougb * 789170222Sdougb *\li 'name' be a valid absolute name. 790170222Sdougb * 791170222Sdougb *\li 'section' be a named section. 792170222Sdougb */ 793170222Sdougb 794170222Sdougb 795135446Strhodes/* 796135446Strhodes * LOANOUT FUNCTIONS 797135446Strhodes * 798135446Strhodes * Each of these functions loan a particular type of data to the caller. 799135446Strhodes * The storage for these will vanish when the message is destroyed or 800135446Strhodes * reset, and must NOT be used after these operations. 801135446Strhodes */ 802135446Strhodes 803135446Strhodesisc_result_t 804135446Strhodesdns_message_gettempname(dns_message_t *msg, dns_name_t **item); 805170222Sdougb/*%< 806135446Strhodes * Return a name that can be used for any temporary purpose, including 807135446Strhodes * inserting into the message's linked lists. The name must be returned 808135446Strhodes * to the message code using dns_message_puttempname() or inserted into 809135446Strhodes * one of the message's sections before the message is destroyed. 810135446Strhodes * 811135446Strhodes * It is the caller's responsibility to initialize this name. 812135446Strhodes * 813135446Strhodes * Requires: 814170222Sdougb *\li msg be a valid message 815135446Strhodes * 816170222Sdougb *\li item != NULL && *item == NULL 817135446Strhodes * 818135446Strhodes * Returns: 819170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 820170222Sdougb *\li #ISC_R_NOMEMORY -- No item can be allocated. 821135446Strhodes */ 822135446Strhodes 823135446Strhodesisc_result_t 824135446Strhodesdns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item); 825170222Sdougb/*%< 826135446Strhodes * Return an offsets array that can be used for any temporary purpose, 827135446Strhodes * such as attaching to a temporary name. The offsets will be freed 828135446Strhodes * when the message is destroyed or reset. 829135446Strhodes * 830135446Strhodes * Requires: 831170222Sdougb *\li msg be a valid message 832135446Strhodes * 833170222Sdougb *\li item != NULL && *item == NULL 834135446Strhodes * 835135446Strhodes * Returns: 836170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 837170222Sdougb *\li #ISC_R_NOMEMORY -- No item can be allocated. 838135446Strhodes */ 839135446Strhodes 840135446Strhodesisc_result_t 841135446Strhodesdns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item); 842170222Sdougb/*%< 843135446Strhodes * Return a rdata that can be used for any temporary purpose, including 844135446Strhodes * inserting into the message's linked lists. The rdata will be freed 845135446Strhodes * when the message is destroyed or reset. 846135446Strhodes * 847135446Strhodes * Requires: 848170222Sdougb *\li msg be a valid message 849135446Strhodes * 850170222Sdougb *\li item != NULL && *item == NULL 851135446Strhodes * 852135446Strhodes * Returns: 853170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 854170222Sdougb *\li #ISC_R_NOMEMORY -- No item can be allocated. 855135446Strhodes */ 856135446Strhodes 857135446Strhodesisc_result_t 858135446Strhodesdns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item); 859170222Sdougb/*%< 860135446Strhodes * Return a rdataset that can be used for any temporary purpose, including 861135446Strhodes * inserting into the message's linked lists. The name must be returned 862135446Strhodes * to the message code using dns_message_puttempname() or inserted into 863135446Strhodes * one of the message's sections before the message is destroyed. 864135446Strhodes * 865135446Strhodes * Requires: 866170222Sdougb *\li msg be a valid message 867135446Strhodes * 868170222Sdougb *\li item != NULL && *item == NULL 869135446Strhodes * 870135446Strhodes * Returns: 871170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 872170222Sdougb *\li #ISC_R_NOMEMORY -- No item can be allocated. 873135446Strhodes */ 874135446Strhodes 875135446Strhodesisc_result_t 876135446Strhodesdns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); 877170222Sdougb/*%< 878135446Strhodes * Return a rdatalist that can be used for any temporary purpose, including 879135446Strhodes * inserting into the message's linked lists. The rdatalist will be 880135446Strhodes * destroyed when the message is destroyed or reset. 881135446Strhodes * 882135446Strhodes * Requires: 883170222Sdougb *\li msg be a valid message 884135446Strhodes * 885170222Sdougb *\li item != NULL && *item == NULL 886135446Strhodes * 887135446Strhodes * Returns: 888170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 889170222Sdougb *\li #ISC_R_NOMEMORY -- No item can be allocated. 890135446Strhodes */ 891135446Strhodes 892135446Strhodesvoid 893135446Strhodesdns_message_puttempname(dns_message_t *msg, dns_name_t **item); 894170222Sdougb/*%< 895135446Strhodes * Return a borrowed name to the message's name free list. 896135446Strhodes * 897135446Strhodes * Requires: 898170222Sdougb *\li msg be a valid message 899135446Strhodes * 900170222Sdougb *\li item != NULL && *item point to a name returned by 901135446Strhodes * dns_message_gettempname() 902135446Strhodes * 903135446Strhodes * Ensures: 904170222Sdougb *\li *item == NULL 905135446Strhodes */ 906135446Strhodes 907135446Strhodesvoid 908135446Strhodesdns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item); 909170222Sdougb/*%< 910135446Strhodes * Return a borrowed rdata to the message's rdata free list. 911135446Strhodes * 912135446Strhodes * Requires: 913170222Sdougb *\li msg be a valid message 914135446Strhodes * 915170222Sdougb *\li item != NULL && *item point to a rdata returned by 916135446Strhodes * dns_message_gettemprdata() 917135446Strhodes * 918135446Strhodes * Ensures: 919170222Sdougb *\li *item == NULL 920135446Strhodes */ 921135446Strhodes 922135446Strhodesvoid 923135446Strhodesdns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item); 924170222Sdougb/*%< 925135446Strhodes * Return a borrowed rdataset to the message's rdataset free list. 926135446Strhodes * 927135446Strhodes * Requires: 928170222Sdougb *\li msg be a valid message 929135446Strhodes * 930170222Sdougb *\li item != NULL && *item point to a rdataset returned by 931135446Strhodes * dns_message_gettemprdataset() 932135446Strhodes * 933135446Strhodes * Ensures: 934170222Sdougb *\li *item == NULL 935135446Strhodes */ 936135446Strhodes 937135446Strhodesvoid 938135446Strhodesdns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); 939170222Sdougb/*%< 940135446Strhodes * Return a borrowed rdatalist to the message's rdatalist free list. 941135446Strhodes * 942135446Strhodes * Requires: 943170222Sdougb *\li msg be a valid message 944135446Strhodes * 945170222Sdougb *\li item != NULL && *item point to a rdatalist returned by 946135446Strhodes * dns_message_gettemprdatalist() 947135446Strhodes * 948135446Strhodes * Ensures: 949170222Sdougb *\li *item == NULL 950135446Strhodes */ 951135446Strhodes 952135446Strhodesisc_result_t 953135446Strhodesdns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp, 954135446Strhodes unsigned int *flagsp); 955170222Sdougb/*%< 956135446Strhodes * Assume the remaining region of "source" is a DNS message. Peek into 957135446Strhodes * it and fill in "*idp" with the message id, and "*flagsp" with the flags. 958135446Strhodes * 959135446Strhodes * Requires: 960135446Strhodes * 961170222Sdougb *\li source != NULL 962135446Strhodes * 963135446Strhodes * Ensures: 964135446Strhodes * 965170222Sdougb *\li if (idp != NULL) *idp == message id. 966135446Strhodes * 967170222Sdougb *\li if (flagsp != NULL) *flagsp == message flags. 968135446Strhodes * 969135446Strhodes * Returns: 970135446Strhodes * 971170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 972135446Strhodes * 973170222Sdougb *\li #ISC_R_UNEXPECTEDEND -- buffer doesn't contain enough for a header. 974135446Strhodes */ 975135446Strhodes 976135446Strhodesisc_result_t 977135446Strhodesdns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section); 978170222Sdougb/*%< 979135446Strhodes * Start formatting a reply to the query in 'msg'. 980135446Strhodes * 981135446Strhodes * Requires: 982135446Strhodes * 983170222Sdougb *\li 'msg' is a valid message with parsing intent, and contains a query. 984135446Strhodes * 985135446Strhodes * Ensures: 986135446Strhodes * 987170222Sdougb *\li The message will have a rendering intent. If 'want_question_section' 988135446Strhodes * is true, the message opcode is query or notify, and the question 989135446Strhodes * section is present and properly formatted, then the question section 990135446Strhodes * will be included in the reply. All other sections will be cleared. 991135446Strhodes * The QR flag will be set, the RD flag will be preserved, and all other 992135446Strhodes * flags will be cleared. 993135446Strhodes * 994135446Strhodes * Returns: 995135446Strhodes * 996170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 997135446Strhodes * 998170222Sdougb *\li #DNS_R_FORMERR -- the header or question section of the 999135446Strhodes * message is invalid, replying is impossible. 1000135446Strhodes * If DNS_R_FORMERR is returned when 1001135446Strhodes * want_question_section is ISC_FALSE, then 1002135446Strhodes * it's the header section that's bad; 1003135446Strhodes * otherwise either of the header or question 1004135446Strhodes * sections may be bad. 1005135446Strhodes */ 1006135446Strhodes 1007135446Strhodesdns_rdataset_t * 1008135446Strhodesdns_message_getopt(dns_message_t *msg); 1009170222Sdougb/*%< 1010135446Strhodes * Get the OPT record for 'msg'. 1011135446Strhodes * 1012135446Strhodes * Requires: 1013135446Strhodes * 1014170222Sdougb *\li 'msg' is a valid message. 1015135446Strhodes * 1016135446Strhodes * Returns: 1017135446Strhodes * 1018170222Sdougb *\li The OPT rdataset of 'msg', or NULL if there isn't one. 1019135446Strhodes */ 1020135446Strhodes 1021135446Strhodesisc_result_t 1022135446Strhodesdns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt); 1023170222Sdougb/*%< 1024135446Strhodes * Set the OPT record for 'msg'. 1025135446Strhodes * 1026135446Strhodes * Requires: 1027135446Strhodes * 1028170222Sdougb *\li 'msg' is a valid message with rendering intent 1029135446Strhodes * and no sections have been rendered. 1030135446Strhodes * 1031170222Sdougb *\li 'opt' is a valid OPT record. 1032135446Strhodes * 1033135446Strhodes * Ensures: 1034135446Strhodes * 1035170222Sdougb *\li The OPT record has either been freed or ownership of it has 1036135446Strhodes * been transferred to the message. 1037135446Strhodes * 1038193149Sdougb *\li If ISC_R_SUCCESS was returned, the OPT record will be rendered 1039135446Strhodes * when dns_message_renderend() is called. 1040135446Strhodes * 1041135446Strhodes * Returns: 1042135446Strhodes * 1043170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 1044135446Strhodes * 1045170222Sdougb *\li #ISC_R_NOSPACE -- there is no space for the OPT record. 1046135446Strhodes */ 1047135446Strhodes 1048135446Strhodesdns_rdataset_t * 1049135446Strhodesdns_message_gettsig(dns_message_t *msg, dns_name_t **owner); 1050170222Sdougb/*%< 1051135446Strhodes * Get the TSIG record and owner for 'msg'. 1052135446Strhodes * 1053135446Strhodes * Requires: 1054135446Strhodes * 1055170222Sdougb *\li 'msg' is a valid message. 1056170222Sdougb *\li 'owner' is NULL or *owner is NULL. 1057135446Strhodes * 1058135446Strhodes * Returns: 1059135446Strhodes * 1060170222Sdougb *\li The TSIG rdataset of 'msg', or NULL if there isn't one. 1061135446Strhodes * 1062135446Strhodes * Ensures: 1063135446Strhodes * 1064170222Sdougb * \li If 'owner' is not NULL, it will point to the owner name. 1065135446Strhodes */ 1066135446Strhodes 1067135446Strhodesisc_result_t 1068135446Strhodesdns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key); 1069170222Sdougb/*%< 1070135446Strhodes * Set the tsig key for 'msg'. This is only necessary for when rendering a 1071135446Strhodes * query or parsing a response. The key (if non-NULL) is attached to, and 1072135446Strhodes * will be detached when the message is destroyed. 1073135446Strhodes * 1074135446Strhodes * Requires: 1075135446Strhodes * 1076170222Sdougb *\li 'msg' is a valid message with rendering intent, 1077135446Strhodes * dns_message_renderbegin() has been called, and no sections have been 1078135446Strhodes * rendered. 1079170222Sdougb *\li 'key' is a valid tsig key or NULL. 1080135446Strhodes * 1081135446Strhodes * Returns: 1082135446Strhodes * 1083170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 1084135446Strhodes * 1085170222Sdougb *\li #ISC_R_NOSPACE -- there is no space for the TSIG record. 1086135446Strhodes */ 1087135446Strhodes 1088135446Strhodesdns_tsigkey_t * 1089135446Strhodesdns_message_gettsigkey(dns_message_t *msg); 1090170222Sdougb/*%< 1091135446Strhodes * Gets the tsig key for 'msg'. 1092135446Strhodes * 1093135446Strhodes * Requires: 1094135446Strhodes * 1095170222Sdougb *\li 'msg' is a valid message 1096135446Strhodes */ 1097135446Strhodes 1098135446Strhodesisc_result_t 1099135446Strhodesdns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig); 1100170222Sdougb/*%< 1101135446Strhodes * Indicates that 'querytsig' is the TSIG from the signed query for which 1102135446Strhodes * 'msg' is the response. This is also used for chained TSIGs in TCP 1103135446Strhodes * responses. 1104135446Strhodes * 1105135446Strhodes * Requires: 1106135446Strhodes * 1107170222Sdougb *\li 'querytsig' is a valid buffer as returned by dns_message_getquerytsig() 1108135446Strhodes * or NULL 1109135446Strhodes * 1110170222Sdougb *\li 'msg' is a valid message 1111135446Strhodes * 1112135446Strhodes * Returns: 1113135446Strhodes * 1114170222Sdougb *\li #ISC_R_SUCCESS 1115170222Sdougb *\li #ISC_R_NOMEMORY 1116135446Strhodes */ 1117135446Strhodes 1118135446Strhodesisc_result_t 1119135446Strhodesdns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx, 1120135446Strhodes isc_buffer_t **querytsig); 1121170222Sdougb/*%< 1122135446Strhodes * Gets the tsig from the TSIG from the signed query 'msg'. This is also used 1123135446Strhodes * for chained TSIGs in TCP responses. Unlike dns_message_gettsig, this makes 1124135446Strhodes * a copy of the data, so can be used if the message is destroyed. 1125135446Strhodes * 1126135446Strhodes * Requires: 1127135446Strhodes * 1128170222Sdougb *\li 'msg' is a valid signed message 1129170222Sdougb *\li 'mctx' is a valid memory context 1130170222Sdougb *\li querytsig != NULL && *querytsig == NULL 1131135446Strhodes * 1132135446Strhodes * Returns: 1133135446Strhodes * 1134170222Sdougb *\li #ISC_R_SUCCESS 1135170222Sdougb *\li #ISC_R_NOMEMORY 1136135446Strhodes * 1137135446Strhodes * Ensures: 1138170222Sdougb *\li 'tsig' points to NULL or an allocated buffer which must be freed 1139135446Strhodes * by the caller. 1140135446Strhodes */ 1141135446Strhodes 1142135446Strhodesdns_rdataset_t * 1143135446Strhodesdns_message_getsig0(dns_message_t *msg, dns_name_t **owner); 1144170222Sdougb/*%< 1145135446Strhodes * Get the SIG(0) record and owner for 'msg'. 1146135446Strhodes * 1147135446Strhodes * Requires: 1148135446Strhodes * 1149170222Sdougb *\li 'msg' is a valid message. 1150170222Sdougb *\li 'owner' is NULL or *owner is NULL. 1151135446Strhodes * 1152135446Strhodes * Returns: 1153135446Strhodes * 1154170222Sdougb *\li The SIG(0) rdataset of 'msg', or NULL if there isn't one. 1155135446Strhodes * 1156135446Strhodes * Ensures: 1157135446Strhodes * 1158170222Sdougb * \li If 'owner' is not NULL, it will point to the owner name. 1159135446Strhodes */ 1160135446Strhodes 1161135446Strhodesisc_result_t 1162135446Strhodesdns_message_setsig0key(dns_message_t *msg, dst_key_t *key); 1163170222Sdougb/*%< 1164135446Strhodes * Set the SIG(0) key for 'msg'. 1165135446Strhodes * 1166135446Strhodes * Requires: 1167135446Strhodes * 1168170222Sdougb *\li 'msg' is a valid message with rendering intent, 1169135446Strhodes * dns_message_renderbegin() has been called, and no sections have been 1170135446Strhodes * rendered. 1171170222Sdougb *\li 'key' is a valid sig key or NULL. 1172135446Strhodes * 1173135446Strhodes * Returns: 1174135446Strhodes * 1175170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 1176135446Strhodes * 1177170222Sdougb *\li #ISC_R_NOSPACE -- there is no space for the SIG(0) record. 1178135446Strhodes */ 1179135446Strhodes 1180135446Strhodesdst_key_t * 1181135446Strhodesdns_message_getsig0key(dns_message_t *msg); 1182170222Sdougb/*%< 1183135446Strhodes * Gets the SIG(0) key for 'msg'. 1184135446Strhodes * 1185135446Strhodes * Requires: 1186135446Strhodes * 1187170222Sdougb *\li 'msg' is a valid message 1188135446Strhodes */ 1189135446Strhodes 1190135446Strhodesvoid 1191135446Strhodesdns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer); 1192170222Sdougb/*%< 1193135446Strhodes * Give the *buffer to the message code to clean up when it is no 1194135446Strhodes * longer needed. This is usually when the message is reset or 1195135446Strhodes * destroyed. 1196135446Strhodes * 1197135446Strhodes * Requires: 1198135446Strhodes * 1199170222Sdougb *\li msg be a valid message. 1200135446Strhodes * 1201170222Sdougb *\li buffer != NULL && *buffer is a valid isc_buffer_t, which was 1202193149Sdougb * dynamically allocated via isc_buffer_allocate(). 1203135446Strhodes */ 1204135446Strhodes 1205135446Strhodesisc_result_t 1206135446Strhodesdns_message_signer(dns_message_t *msg, dns_name_t *signer); 1207170222Sdougb/*%< 1208135446Strhodes * If this message was signed, return the identity of the signer. 1209135446Strhodes * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the 1210135446Strhodes * key that signed the message. 1211135446Strhodes * 1212135446Strhodes * Requires: 1213135446Strhodes * 1214170222Sdougb *\li msg is a valid parsed message. 1215170222Sdougb *\li signer is a valid name 1216135446Strhodes * 1217135446Strhodes * Returns: 1218135446Strhodes * 1219170222Sdougb *\li #ISC_R_SUCCESS - the message was signed, and *signer 1220135446Strhodes * contains the signing identity 1221135446Strhodes * 1222170222Sdougb *\li #ISC_R_NOTFOUND - no TSIG or SIG(0) record is present in the 1223135446Strhodes * message 1224135446Strhodes * 1225170222Sdougb *\li #DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the 1226135446Strhodes * signature failed to verify 1227135446Strhodes * 1228170222Sdougb *\li #DNS_R_TSIGERRORSET - the message was signed by a TSIG and 1229135446Strhodes * verified, but the query was rejected by 1230135446Strhodes * the server 1231135446Strhodes * 1232170222Sdougb *\li #DNS_R_NOIDENTITY - the message was signed by a TSIG and 1233135446Strhodes * verified, but the key has no identity since 1234135446Strhodes * it was generated by an unsigned TKEY process 1235135446Strhodes * 1236170222Sdougb *\li #DNS_R_SIGINVALID - the message was signed by a SIG(0), but 1237135446Strhodes * the signature failed to verify 1238135446Strhodes * 1239170222Sdougb *\li #DNS_R_NOTVERIFIEDYET - the message was signed by a TSIG or SIG(0), 1240135446Strhodes * but the signature has not been verified yet 1241135446Strhodes */ 1242135446Strhodes 1243135446Strhodesisc_result_t 1244135446Strhodesdns_message_checksig(dns_message_t *msg, dns_view_t *view); 1245170222Sdougb/*%< 1246135446Strhodes * If this message was signed, verify the signature. 1247135446Strhodes * 1248135446Strhodes * Requires: 1249135446Strhodes * 1250170222Sdougb *\li msg is a valid parsed message. 1251170222Sdougb *\li view is a valid view or NULL 1252135446Strhodes * 1253135446Strhodes * Returns: 1254135446Strhodes * 1255170222Sdougb *\li #ISC_R_SUCCESS - the message was unsigned, or the message 1256135446Strhodes * was signed correctly. 1257135446Strhodes * 1258170222Sdougb *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen 1259170222Sdougb *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected 1260170222Sdougb *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify 1261135446Strhodes */ 1262135446Strhodes 1263135446Strhodesisc_result_t 1264135446Strhodesdns_message_rechecksig(dns_message_t *msg, dns_view_t *view); 1265170222Sdougb/*%< 1266135446Strhodes * Reset the signature state and then if the message was signed, 1267135446Strhodes * verify the message. 1268135446Strhodes * 1269135446Strhodes * Requires: 1270135446Strhodes * 1271170222Sdougb *\li msg is a valid parsed message. 1272170222Sdougb *\li view is a valid view or NULL 1273135446Strhodes * 1274135446Strhodes * Returns: 1275135446Strhodes * 1276170222Sdougb *\li #ISC_R_SUCCESS - the message was unsigned, or the message 1277135446Strhodes * was signed correctly. 1278135446Strhodes * 1279170222Sdougb *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen 1280170222Sdougb *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected 1281170222Sdougb *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify 1282135446Strhodes */ 1283135446Strhodes 1284135446Strhodesvoid 1285135446Strhodesdns_message_resetsig(dns_message_t *msg); 1286170222Sdougb/*%< 1287135446Strhodes * Reset the signature state. 1288135446Strhodes * 1289135446Strhodes * Requires: 1290170222Sdougb *\li 'msg' is a valid parsed message. 1291135446Strhodes */ 1292135446Strhodes 1293135446Strhodesisc_region_t * 1294135446Strhodesdns_message_getrawmessage(dns_message_t *msg); 1295170222Sdougb/*%< 1296135446Strhodes * Retrieve the raw message in compressed wire format. The message must 1297135446Strhodes * have been successfully parsed for it to have been saved. 1298135446Strhodes * 1299135446Strhodes * Requires: 1300170222Sdougb *\li msg is a valid parsed message. 1301135446Strhodes * 1302135446Strhodes * Returns: 1303170222Sdougb *\li NULL if there is no saved message. 1304135446Strhodes * a pointer to a region which refers the dns message. 1305135446Strhodes */ 1306135446Strhodes 1307135446Strhodesvoid 1308135446Strhodesdns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, 1309165071Sdougb const void *order_arg); 1310170222Sdougb/*%< 1311135446Strhodes * Define the order in which RR sets get rendered by 1312135446Strhodes * dns_message_rendersection() to be the ascending order 1313135446Strhodes * defined by the integer value returned by 'order' when 1314135446Strhodes * given each RR and 'arg' as arguments. If 'order' and 1315135446Strhodes * 'order_arg' are NULL, a default order is used. 1316135446Strhodes * 1317135446Strhodes * Requires: 1318170222Sdougb *\li msg be a valid message. 1319170222Sdougb *\li order_arg is NULL if and only if order is NULL. 1320135446Strhodes */ 1321135446Strhodes 1322193149Sdougbvoid 1323135446Strhodesdns_message_settimeadjust(dns_message_t *msg, int timeadjust); 1324170222Sdougb/*%< 1325135446Strhodes * Adjust the time used to sign/verify a message by timeadjust. 1326135446Strhodes * Currently only TSIG. 1327135446Strhodes * 1328135446Strhodes * Requires: 1329170222Sdougb *\li msg be a valid message. 1330135446Strhodes */ 1331135446Strhodes 1332193149Sdougbint 1333135446Strhodesdns_message_gettimeadjust(dns_message_t *msg); 1334170222Sdougb/*%< 1335135446Strhodes * Return the current time adjustment. 1336135446Strhodes * 1337135446Strhodes * Requires: 1338170222Sdougb *\li msg be a valid message. 1339135446Strhodes */ 1340135446Strhodes 1341135446StrhodesISC_LANG_ENDDECLS 1342135446Strhodes 1343135446Strhodes#endif /* DNS_MESSAGE_H */ 1344