1135446Strhodes/* 2254402Serwin * Copyright (C) 2004-2010, 2012, 2013 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 18135446Strhodes#ifndef DNS_MESSAGE_H 19135446Strhodes#define DNS_MESSAGE_H 1 20135446Strhodes 21135446Strhodes/*** 22135446Strhodes *** Imports 23135446Strhodes ***/ 24135446Strhodes 25135446Strhodes#include <isc/lang.h> 26135446Strhodes#include <isc/magic.h> 27135446Strhodes 28135446Strhodes#include <dns/compress.h> 29135446Strhodes#include <dns/masterdump.h> 30135446Strhodes#include <dns/types.h> 31135446Strhodes 32135446Strhodes#include <dst/dst.h> 33135446Strhodes 34193149Sdougb/*! \file dns/message.h 35170222Sdougb * \brief Message Handling Module 36170222Sdougb * 37135446Strhodes * How this beast works: 38135446Strhodes * 39135446Strhodes * When a dns message is received in a buffer, dns_message_fromwire() is called 40135446Strhodes * on the memory region. Various items are checked including the format 41135446Strhodes * of the message (if counts are right, if counts consume the entire sections, 42135446Strhodes * and if sections consume the entire message) and known pseudo-RRs in the 43135446Strhodes * additional data section are analyzed and removed. 44135446Strhodes * 45135446Strhodes * TSIG checking is also done at this layer, and any DNSSEC transaction 46135446Strhodes * signatures should also be checked here. 47135446Strhodes * 48135446Strhodes * Notes on using the gettemp*() and puttemp*() functions: 49135446Strhodes * 50135446Strhodes * These functions return items (names, rdatasets, etc) allocated from some 51135446Strhodes * internal state of the dns_message_t. 52135446Strhodes * 53135446Strhodes * Names and rdatasets must be put back into the dns_message_t in 54135446Strhodes * one of two ways. Assume a name was allocated via 55135446Strhodes * dns_message_gettempname(): 56135446Strhodes * 57170222Sdougb *\li (1) insert it into a section, using dns_message_addname(). 58135446Strhodes * 59170222Sdougb *\li (2) return it to the message using dns_message_puttempname(). 60135446Strhodes * 61135446Strhodes * The same applies to rdatasets. 62135446Strhodes * 63135446Strhodes * On the other hand, offsets, rdatalists and rdatas allocated using 64135446Strhodes * dns_message_gettemp*() will always be freed automatically 65135446Strhodes * when the message is reset or destroyed; calling dns_message_puttemp*() 66135446Strhodes * on rdatalists and rdatas is optional and serves only to enable the item 67135446Strhodes * to be reused multiple times during the lifetime of the message; offsets 68135446Strhodes * cannot be reused. 69135446Strhodes * 70135446Strhodes * Buffers allocated using isc_buffer_allocate() can be automatically freed 71135446Strhodes * as well by giving the buffer to the message using dns_message_takebuffer(). 72135446Strhodes * Doing this will cause the buffer to be freed using isc_buffer_free() 73135446Strhodes * when the section lists are cleared, such as in a reset or in a destroy. 74135446Strhodes * Since the buffer itself exists until the message is destroyed, this sort 75135446Strhodes * of code can be written: 76135446Strhodes * 77170222Sdougb * \code 78135446Strhodes * buffer = isc_buffer_allocate(mctx, 512); 79135446Strhodes * name = NULL; 80135446Strhodes * name = dns_message_gettempname(message, &name); 81135446Strhodes * dns_name_init(name, NULL); 82224092Sdougb * result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer); 83135446Strhodes * dns_message_takebuffer(message, &buffer); 84170222Sdougb * \endcode 85135446Strhodes * 86135446Strhodes * 87135446Strhodes * TODO: 88135446Strhodes * 89135446Strhodes * XXX Needed: ways to set and retrieve EDNS information, add rdata to a 90135446Strhodes * section, move rdata from one section to another, remove rdata, etc. 91135446Strhodes */ 92135446Strhodes 93135446Strhodes#define DNS_MESSAGEFLAG_QR 0x8000U 94135446Strhodes#define DNS_MESSAGEFLAG_AA 0x0400U 95135446Strhodes#define DNS_MESSAGEFLAG_TC 0x0200U 96135446Strhodes#define DNS_MESSAGEFLAG_RD 0x0100U 97135446Strhodes#define DNS_MESSAGEFLAG_RA 0x0080U 98135446Strhodes#define DNS_MESSAGEFLAG_AD 0x0020U 99135446Strhodes#define DNS_MESSAGEFLAG_CD 0x0010U 100135446Strhodes 101193149Sdougb/*%< EDNS0 extended message flags */ 102135446Strhodes#define DNS_MESSAGEEXTFLAG_DO 0x8000U 103135446Strhodes 104193149Sdougb/*%< EDNS0 extended OPT codes */ 105193149Sdougb#define DNS_OPT_NSID 0x0003 /*%< NSID opt code */ 106262706Serwin#define DNS_OPT_CLIENT_SUBNET 0x0008 /*%< client subnet opt code */ 107193149Sdougb 108135446Strhodes#define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD) 109135446Strhodes#define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO) 110135446Strhodes 111170222Sdougb#define DNS_MESSAGE_HEADERLEN 12 /*%< 6 isc_uint16_t's */ 112135446Strhodes 113135446Strhodes#define DNS_MESSAGE_MAGIC ISC_MAGIC('M','S','G','@') 114135446Strhodes#define DNS_MESSAGE_VALID(msg) ISC_MAGIC_VALID(msg, DNS_MESSAGE_MAGIC) 115135446Strhodes 116135446Strhodes/* 117135446Strhodes * Ordering here matters. DNS_SECTION_ANY must be the lowest and negative, 118135446Strhodes * and DNS_SECTION_MAX must be one greater than the last used section. 119135446Strhodes */ 120135446Strhodestypedef int dns_section_t; 121135446Strhodes#define DNS_SECTION_ANY (-1) 122135446Strhodes#define DNS_SECTION_QUESTION 0 123135446Strhodes#define DNS_SECTION_ANSWER 1 124135446Strhodes#define DNS_SECTION_AUTHORITY 2 125135446Strhodes#define DNS_SECTION_ADDITIONAL 3 126135446Strhodes#define DNS_SECTION_MAX 4 127135446Strhodes 128135446Strhodestypedef int dns_pseudosection_t; 129135446Strhodes#define DNS_PSEUDOSECTION_ANY (-1) 130135446Strhodes#define DNS_PSEUDOSECTION_OPT 0 131135446Strhodes#define DNS_PSEUDOSECTION_TSIG 1 132135446Strhodes#define DNS_PSEUDOSECTION_SIG0 2 133135446Strhodes#define DNS_PSEUDOSECTION_MAX 3 134135446Strhodes 135135446Strhodestypedef int dns_messagetextflag_t; 136135446Strhodes#define DNS_MESSAGETEXTFLAG_NOCOMMENTS 0x0001 137135446Strhodes#define DNS_MESSAGETEXTFLAG_NOHEADERS 0x0002 138224092Sdougb#define DNS_MESSAGETEXTFLAG_ONESOA 0x0004 139224092Sdougb#define DNS_MESSAGETEXTFLAG_OMITSOA 0x0008 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. */ 177224092Sdougb#ifdef ALLOW_FILTER_AAAA_ON_V4 178224092Sdougb#define DNS_MESSAGERENDER_FILTER_AAAA 0x0020 /*%< filter AAAA records */ 179224092Sdougb#endif 180135446Strhodes 181135446Strhodestypedef struct dns_msgblock dns_msgblock_t; 182135446Strhodes 183135446Strhodesstruct dns_message { 184135446Strhodes /* public from here down */ 185135446Strhodes unsigned int magic; 186135446Strhodes 187135446Strhodes dns_messageid_t id; 188135446Strhodes unsigned int flags; 189135446Strhodes dns_rcode_t rcode; 190135446Strhodes unsigned int opcode; 191135446Strhodes dns_rdataclass_t rdclass; 192135446Strhodes 193135446Strhodes /* 4 real, 1 pseudo */ 194135446Strhodes unsigned int counts[DNS_SECTION_MAX]; 195135446Strhodes 196135446Strhodes /* private from here down */ 197135446Strhodes dns_namelist_t sections[DNS_SECTION_MAX]; 198135446Strhodes dns_name_t *cursors[DNS_SECTION_MAX]; 199135446Strhodes dns_rdataset_t *opt; 200135446Strhodes dns_rdataset_t *sig0; 201135446Strhodes dns_rdataset_t *tsig; 202135446Strhodes 203135446Strhodes int state; 204135446Strhodes unsigned int from_to_wire : 2; 205135446Strhodes unsigned int header_ok : 1; 206135446Strhodes unsigned int question_ok : 1; 207135446Strhodes unsigned int tcp_continuation : 1; 208135446Strhodes unsigned int verified_sig : 1; 209135446Strhodes unsigned int verify_attempted : 1; 210135446Strhodes unsigned int free_query : 1; 211135446Strhodes unsigned int free_saved : 1; 212292321Sdelphij unsigned int tkey : 1; 213292321Sdelphij unsigned int rdclass_set : 1; 214135446Strhodes 215135446Strhodes unsigned int opt_reserved; 216135446Strhodes unsigned int sig_reserved; 217135446Strhodes unsigned int reserved; /* reserved space (render) */ 218135446Strhodes 219135446Strhodes isc_buffer_t *buffer; 220135446Strhodes dns_compress_t *cctx; 221135446Strhodes 222135446Strhodes isc_mem_t *mctx; 223135446Strhodes isc_mempool_t *namepool; 224135446Strhodes isc_mempool_t *rdspool; 225135446Strhodes 226135446Strhodes isc_bufferlist_t scratchpad; 227135446Strhodes isc_bufferlist_t cleanup; 228135446Strhodes 229135446Strhodes ISC_LIST(dns_msgblock_t) rdatas; 230135446Strhodes ISC_LIST(dns_msgblock_t) rdatalists; 231135446Strhodes ISC_LIST(dns_msgblock_t) offsets; 232135446Strhodes 233135446Strhodes ISC_LIST(dns_rdata_t) freerdata; 234135446Strhodes ISC_LIST(dns_rdatalist_t) freerdatalist; 235135446Strhodes 236135446Strhodes dns_rcode_t tsigstatus; 237135446Strhodes dns_rcode_t querytsigstatus; 238135446Strhodes dns_name_t *tsigname; /* Owner name of TSIG, if any */ 239135446Strhodes dns_rdataset_t *querytsig; 240135446Strhodes dns_tsigkey_t *tsigkey; 241135446Strhodes dst_context_t *tsigctx; 242135446Strhodes int sigstart; 243135446Strhodes int timeadjust; 244135446Strhodes 245135446Strhodes dns_name_t *sig0name; /* Owner name of SIG0, if any */ 246135446Strhodes dst_key_t *sig0key; 247135446Strhodes dns_rcode_t sig0status; 248135446Strhodes isc_region_t query; 249135446Strhodes isc_region_t saved; 250135446Strhodes 251135446Strhodes dns_rdatasetorderfunc_t order; 252165071Sdougb const void * order_arg; 253135446Strhodes}; 254135446Strhodes 255254402Serwinstruct dns_ednsopt { 256254402Serwin isc_uint16_t code; 257254402Serwin isc_uint16_t length; 258254402Serwin unsigned char *value; 259254402Serwin}; 260254402Serwin 261135446Strhodes/*** 262135446Strhodes *** Functions 263135446Strhodes ***/ 264135446Strhodes 265135446StrhodesISC_LANG_BEGINDECLS 266135446Strhodes 267135446Strhodesisc_result_t 268135446Strhodesdns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp); 269135446Strhodes 270170222Sdougb/*%< 271135446Strhodes * Create msg structure. 272135446Strhodes * 273135446Strhodes * This function will allocate some internal blocks of memory that are 274135446Strhodes * expected to be needed for parsing or rendering nearly any type of message. 275135446Strhodes * 276135446Strhodes * Requires: 277170222Sdougb *\li 'mctx' be a valid memory context. 278135446Strhodes * 279170222Sdougb *\li 'msgp' be non-null and '*msg' be NULL. 280135446Strhodes * 281170222Sdougb *\li 'intent' must be one of DNS_MESSAGE_INTENTPARSE or 282170222Sdougb * #DNS_MESSAGE_INTENTRENDER. 283135446Strhodes * 284135446Strhodes * Ensures: 285170222Sdougb *\li The data in "*msg" is set to indicate an unused and empty msg 286135446Strhodes * structure. 287135446Strhodes * 288135446Strhodes * Returns: 289170222Sdougb *\li #ISC_R_NOMEMORY -- out of memory 290170222Sdougb *\li #ISC_R_SUCCESS -- success 291135446Strhodes */ 292135446Strhodes 293135446Strhodesvoid 294135446Strhodesdns_message_reset(dns_message_t *msg, unsigned int intent); 295170222Sdougb/*%< 296135446Strhodes * Reset a message structure to default state. All internal lists are freed 297135446Strhodes * or reset to a default state as well. This is simply a more efficient 298135446Strhodes * way to call dns_message_destroy() followed by dns_message_allocate(), 299135446Strhodes * since it avoid many memory allocations. 300135446Strhodes * 301135446Strhodes * If any data loanouts (buffers, names, rdatas, etc) were requested, 302135446Strhodes * the caller must no longer use them after this call. 303135446Strhodes * 304135446Strhodes * The intended next use of the message will be 'intent'. 305135446Strhodes * 306135446Strhodes * Requires: 307135446Strhodes * 308170222Sdougb *\li 'msg' be valid. 309135446Strhodes * 310170222Sdougb *\li 'intent' is DNS_MESSAGE_INTENTPARSE or DNS_MESSAGE_INTENTRENDER 311135446Strhodes */ 312135446Strhodes 313135446Strhodesvoid 314135446Strhodesdns_message_destroy(dns_message_t **msgp); 315170222Sdougb/*%< 316135446Strhodes * Destroy all state in the message. 317135446Strhodes * 318135446Strhodes * Requires: 319135446Strhodes * 320170222Sdougb *\li 'msgp' be valid. 321135446Strhodes * 322135446Strhodes * Ensures: 323170222Sdougb *\li '*msgp' == NULL 324135446Strhodes */ 325135446Strhodes 326135446Strhodesisc_result_t 327135446Strhodesdns_message_sectiontotext(dns_message_t *msg, dns_section_t section, 328135446Strhodes const dns_master_style_t *style, 329135446Strhodes dns_messagetextflag_t flags, 330135446Strhodes isc_buffer_t *target); 331135446Strhodes 332135446Strhodesisc_result_t 333135446Strhodesdns_message_pseudosectiontotext(dns_message_t *msg, 334135446Strhodes dns_pseudosection_t section, 335135446Strhodes const dns_master_style_t *style, 336135446Strhodes dns_messagetextflag_t flags, 337135446Strhodes isc_buffer_t *target); 338170222Sdougb/*%< 339135446Strhodes * Convert section 'section' or 'pseudosection' of message 'msg' to 340135446Strhodes * a cleartext representation 341135446Strhodes * 342135446Strhodes * Notes: 343170222Sdougb * \li See dns_message_totext for meanings of flags. 344135446Strhodes * 345135446Strhodes * Requires: 346135446Strhodes * 347170222Sdougb *\li 'msg' is a valid message. 348135446Strhodes * 349170222Sdougb *\li 'style' is a valid master dump style. 350135446Strhodes * 351170222Sdougb *\li 'target' is a valid buffer. 352135446Strhodes * 353170222Sdougb *\li 'section' is a valid section label. 354135446Strhodes * 355135446Strhodes * Ensures: 356135446Strhodes * 357170222Sdougb *\li If the result is success: 358135446Strhodes * The used space in 'target' is updated. 359135446Strhodes * 360135446Strhodes * Returns: 361135446Strhodes * 362170222Sdougb *\li #ISC_R_SUCCESS 363170222Sdougb *\li #ISC_R_NOSPACE 364170222Sdougb *\li #ISC_R_NOMORE 365135446Strhodes * 366170222Sdougb *\li Note: On error return, *target may be partially filled with data. 367135446Strhodes*/ 368135446Strhodes 369135446Strhodesisc_result_t 370135446Strhodesdns_message_totext(dns_message_t *msg, const dns_master_style_t *style, 371135446Strhodes dns_messagetextflag_t flags, isc_buffer_t *target); 372170222Sdougb/*%< 373135446Strhodes * Convert all sections of message 'msg' to a cleartext representation 374135446Strhodes * 375135446Strhodes * Notes: 376170222Sdougb * \li In flags, If #DNS_MESSAGETEXTFLAG_OMITDOT is set, then the 377135446Strhodes * final '.' in absolute names will not be emitted. If 378170222Sdougb * #DNS_MESSAGETEXTFLAG_NOCOMMENTS is cleared, lines beginning 379135446Strhodes * with ";;" will be emitted indicating section name. If 380170222Sdougb * #DNS_MESSAGETEXTFLAG_NOHEADERS is cleared, header lines will 381135446Strhodes * be emitted. 382135446Strhodes * 383224092Sdougb * If #DNS_MESSAGETEXTFLAG_ONESOA is set then only print the 384224092Sdougb * first SOA record in the answer section. If 385224092Sdougb * #DNS_MESSAGETEXTFLAG_OMITSOA is set don't print any SOA records 386224092Sdougb * in the answer section. These are useful for suppressing the 387224092Sdougb * display of the second SOA record in a AXFR by setting 388224092Sdougb * #DNS_MESSAGETEXTFLAG_ONESOA on the first message in a AXFR stream 389224092Sdougb * and #DNS_MESSAGETEXTFLAG_OMITSOA on subsequent messages. 390224092Sdougb * 391135446Strhodes * Requires: 392135446Strhodes * 393170222Sdougb *\li 'msg' is a valid message. 394135446Strhodes * 395170222Sdougb *\li 'style' is a valid master dump style. 396135446Strhodes * 397170222Sdougb *\li 'target' is a valid buffer. 398135446Strhodes * 399135446Strhodes * Ensures: 400135446Strhodes * 401170222Sdougb *\li If the result is success: 402135446Strhodes * The used space in 'target' is updated. 403135446Strhodes * 404135446Strhodes * Returns: 405135446Strhodes * 406170222Sdougb *\li #ISC_R_SUCCESS 407170222Sdougb *\li #ISC_R_NOSPACE 408170222Sdougb *\li #ISC_R_NOMORE 409135446Strhodes * 410170222Sdougb *\li Note: On error return, *target may be partially filled with data. 411135446Strhodes */ 412135446Strhodes 413135446Strhodesisc_result_t 414135446Strhodesdns_message_parse(dns_message_t *msg, isc_buffer_t *source, 415135446Strhodes unsigned int options); 416170222Sdougb/*%< 417135446Strhodes * Parse raw wire data in 'source' as a DNS message. 418135446Strhodes * 419135446Strhodes * OPT records are detected and stored in the pseudo-section "opt". 420135446Strhodes * TSIGs are detected and stored in the pseudo-section "tsig". 421135446Strhodes * 422170222Sdougb * If #DNS_MESSAGEPARSE_PRESERVEORDER is set, or if the opcode of the message 423135446Strhodes * is UPDATE, a separate dns_name_t object will be created for each RR in the 424135446Strhodes * message. Each such dns_name_t will have a single rdataset containing the 425135446Strhodes * single RR, and the order of the RRs in the message is preserved. 426135446Strhodes * Otherwise, only one dns_name_t object will be created for each unique 427135446Strhodes * owner name in the section, and each such dns_name_t will have a list 428135446Strhodes * of rdatasets. To access the names and their data, use 429135446Strhodes * dns_message_firstname() and dns_message_nextname(). 430135446Strhodes * 431170222Sdougb * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will 432135446Strhodes * not be considered FORMERRs. If the entire message can be parsed, it 433135446Strhodes * will be returned and DNS_R_RECOVERABLE will be returned. 434135446Strhodes * 435170222Sdougb * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete 436135446Strhodes * RR's as possible, DNS_R_RECOVERABLE will be returned. 437135446Strhodes * 438135446Strhodes * OPT and TSIG records are always handled specially, regardless of the 439135446Strhodes * 'preserve_order' setting. 440135446Strhodes * 441135446Strhodes * Requires: 442170222Sdougb *\li "msg" be valid. 443135446Strhodes * 444170222Sdougb *\li "buffer" be a wire format buffer. 445135446Strhodes * 446135446Strhodes * Ensures: 447170222Sdougb *\li The buffer's data format is correct. 448135446Strhodes * 449170222Sdougb *\li The buffer's contents verify as correct regarding header bits, buffer 450135446Strhodes * and rdata sizes, etc. 451135446Strhodes * 452135446Strhodes * Returns: 453170222Sdougb *\li #ISC_R_SUCCESS -- all is well 454170222Sdougb *\li #ISC_R_NOMEMORY -- no memory 455170222Sdougb *\li #DNS_R_RECOVERABLE -- the message parsed properly, but contained 456135446Strhodes * errors. 457170222Sdougb *\li Many other errors possible XXXMLG 458135446Strhodes */ 459135446Strhodes 460135446Strhodesisc_result_t 461135446Strhodesdns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx, 462135446Strhodes isc_buffer_t *buffer); 463170222Sdougb/*%< 464135446Strhodes * Begin rendering on a message. Only one call can be made to this function 465135446Strhodes * per message. 466135446Strhodes * 467135446Strhodes * The compression context is "owned" by the message library until 468135446Strhodes * dns_message_renderend() is called. It must be invalidated by the caller. 469135446Strhodes * 470135446Strhodes * The buffer is "owned" by the message library until dns_message_renderend() 471135446Strhodes * is called. 472135446Strhodes * 473135446Strhodes * Requires: 474135446Strhodes * 475170222Sdougb *\li 'msg' be valid. 476135446Strhodes * 477170222Sdougb *\li 'cctx' be valid. 478135446Strhodes * 479170222Sdougb *\li 'buffer' is a valid buffer. 480135446Strhodes * 481135446Strhodes * Side Effects: 482135446Strhodes * 483170222Sdougb *\li The buffer is cleared before it is used. 484135446Strhodes * 485135446Strhodes * Returns: 486170222Sdougb *\li #ISC_R_SUCCESS -- all is well 487170222Sdougb *\li #ISC_R_NOSPACE -- output buffer is too small 488135446Strhodes */ 489135446Strhodes 490135446Strhodesisc_result_t 491135446Strhodesdns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer); 492170222Sdougb/*%< 493135446Strhodes * Reset the buffer. This can be used after growing the old buffer 494135446Strhodes * on a ISC_R_NOSPACE return from most of the render functions. 495135446Strhodes * 496135446Strhodes * On successful completion, the old buffer is no longer used by the 497135446Strhodes * library. The new buffer is owned by the library until 498135446Strhodes * dns_message_renderend() is called. 499135446Strhodes * 500135446Strhodes * Requires: 501135446Strhodes * 502170222Sdougb *\li 'msg' be valid. 503135446Strhodes * 504170222Sdougb *\li dns_message_renderbegin() was called. 505135446Strhodes * 506170222Sdougb *\li buffer != NULL. 507135446Strhodes * 508135446Strhodes * Returns: 509170222Sdougb *\li #ISC_R_NOSPACE -- new buffer is too small 510170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 511135446Strhodes */ 512135446Strhodes 513135446Strhodesisc_result_t 514135446Strhodesdns_message_renderreserve(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 * Reserve "space" bytes in the given buffer. 520135446Strhodes * 521135446Strhodes * Requires: 522135446Strhodes * 523170222Sdougb *\li 'msg' be valid. 524135446Strhodes * 525170222Sdougb *\li dns_message_renderbegin() was called. 526135446Strhodes * 527135446Strhodes * Returns: 528170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 529170222Sdougb *\li #ISC_R_NOSPACE -- not enough free space in the buffer. 530135446Strhodes */ 531135446Strhodes 532135446Strhodesvoid 533135446Strhodesdns_message_renderrelease(dns_message_t *msg, unsigned int space); 534170222Sdougb/*%< 535135446Strhodes * XXXMLG should use size_t rather than unsigned int once the buffer 536135446Strhodes * API is cleaned up 537135446Strhodes * 538135446Strhodes * Release "space" bytes in the given buffer that was previously reserved. 539135446Strhodes * 540135446Strhodes * Requires: 541135446Strhodes * 542170222Sdougb *\li 'msg' be valid. 543135446Strhodes * 544170222Sdougb *\li 'space' is less than or equal to the total amount of space reserved 545135446Strhodes * via prior calls to dns_message_renderreserve(). 546135446Strhodes * 547170222Sdougb *\li dns_message_renderbegin() was called. 548135446Strhodes */ 549135446Strhodes 550135446Strhodesisc_result_t 551135446Strhodesdns_message_rendersection(dns_message_t *msg, dns_section_t section, 552135446Strhodes unsigned int options); 553170222Sdougb/*%< 554135446Strhodes * Render all names, rdatalists, etc from the given section at the 555135446Strhodes * specified priority or higher. 556135446Strhodes * 557135446Strhodes * Requires: 558170222Sdougb *\li 'msg' be valid. 559135446Strhodes * 560170222Sdougb *\li 'section' be a valid section. 561135446Strhodes * 562170222Sdougb *\li dns_message_renderbegin() was called. 563135446Strhodes * 564135446Strhodes * Returns: 565170222Sdougb *\li #ISC_R_SUCCESS -- all records were written, and there are 566135446Strhodes * no more records for this section. 567170222Sdougb *\li #ISC_R_NOSPACE -- Not enough room in the buffer to write 568135446Strhodes * all records requested. 569170222Sdougb *\li #DNS_R_MOREDATA -- All requested records written, and there 570135446Strhodes * are records remaining for this section. 571135446Strhodes */ 572135446Strhodes 573135446Strhodesvoid 574135446Strhodesdns_message_renderheader(dns_message_t *msg, isc_buffer_t *target); 575170222Sdougb/*%< 576135446Strhodes * Render the message header. This is implicitly called by 577135446Strhodes * dns_message_renderend(). 578135446Strhodes * 579135446Strhodes * Requires: 580135446Strhodes * 581170222Sdougb *\li 'msg' be a valid message. 582135446Strhodes * 583170222Sdougb *\li dns_message_renderbegin() was called. 584135446Strhodes * 585170222Sdougb *\li 'target' is a valid buffer with enough space to hold a message header 586135446Strhodes */ 587135446Strhodes 588135446Strhodesisc_result_t 589135446Strhodesdns_message_renderend(dns_message_t *msg); 590170222Sdougb/*%< 591135446Strhodes * Finish rendering to the buffer. Note that more data can be in the 592135446Strhodes * 'msg' structure. Destroying the structure will free this, or in a multi- 593135446Strhodes * part EDNS1 message this data can be rendered to another buffer later. 594135446Strhodes * 595135446Strhodes * Requires: 596135446Strhodes * 597170222Sdougb *\li 'msg' be a valid message. 598135446Strhodes * 599170222Sdougb *\li dns_message_renderbegin() was called. 600135446Strhodes * 601135446Strhodes * Returns: 602170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 603135446Strhodes */ 604135446Strhodes 605135446Strhodesvoid 606135446Strhodesdns_message_renderreset(dns_message_t *msg); 607170222Sdougb/*%< 608135446Strhodes * Reset the message so that it may be rendered again. 609135446Strhodes * 610135446Strhodes * Notes: 611135446Strhodes * 612170222Sdougb *\li If dns_message_renderbegin() has been called, dns_message_renderend() 613135446Strhodes * must be called before calling this function. 614135446Strhodes * 615135446Strhodes * Requires: 616135446Strhodes * 617170222Sdougb *\li 'msg' be a valid message with rendering intent. 618135446Strhodes */ 619135446Strhodes 620135446Strhodesisc_result_t 621135446Strhodesdns_message_firstname(dns_message_t *msg, dns_section_t section); 622170222Sdougb/*%< 623135446Strhodes * Set internal per-section name pointer to the beginning of the section. 624135446Strhodes * 625135446Strhodes * The functions dns_message_firstname() and dns_message_nextname() may 626135446Strhodes * be used for iterating over the owner names in a section. 627135446Strhodes * 628135446Strhodes * Requires: 629135446Strhodes * 630170222Sdougb *\li 'msg' be valid. 631135446Strhodes * 632170222Sdougb *\li 'section' be a valid section. 633135446Strhodes * 634135446Strhodes * Returns: 635170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 636170222Sdougb *\li #ISC_R_NOMORE -- No names on given section. 637135446Strhodes */ 638135446Strhodes 639135446Strhodesisc_result_t 640135446Strhodesdns_message_nextname(dns_message_t *msg, dns_section_t section); 641170222Sdougb/*%< 642135446Strhodes * Sets the internal per-section name pointer to point to the next name 643135446Strhodes * in that section. 644135446Strhodes * 645135446Strhodes * Requires: 646135446Strhodes * 647170222Sdougb * \li 'msg' be valid. 648135446Strhodes * 649170222Sdougb *\li 'section' be a valid section. 650135446Strhodes * 651170222Sdougb *\li dns_message_firstname() must have been called on this section, 652135446Strhodes * and the result was ISC_R_SUCCESS. 653135446Strhodes * 654135446Strhodes * Returns: 655170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 656170222Sdougb *\li #ISC_R_NOMORE -- No more names in given section. 657135446Strhodes */ 658135446Strhodes 659135446Strhodesvoid 660135446Strhodesdns_message_currentname(dns_message_t *msg, dns_section_t section, 661135446Strhodes dns_name_t **name); 662170222Sdougb/*%< 663135446Strhodes * Sets 'name' to point to the name where the per-section internal name 664135446Strhodes * pointer is currently set. 665135446Strhodes * 666135446Strhodes * This function returns the name in the database, so any data associated 667135446Strhodes * with it (via the name's "list" member) contains the actual rdatasets. 668135446Strhodes * 669135446Strhodes * Requires: 670135446Strhodes * 671170222Sdougb *\li 'msg' be valid. 672135446Strhodes * 673170222Sdougb *\li 'name' be non-NULL, and *name be NULL. 674135446Strhodes * 675170222Sdougb *\li 'section' be a valid section. 676135446Strhodes * 677170222Sdougb *\li dns_message_firstname() must have been called on this section, 678135446Strhodes * and the result of it and any dns_message_nextname() calls was 679170222Sdougb * #ISC_R_SUCCESS. 680135446Strhodes */ 681135446Strhodes 682135446Strhodesisc_result_t 683135446Strhodesdns_message_findname(dns_message_t *msg, dns_section_t section, 684135446Strhodes dns_name_t *target, dns_rdatatype_t type, 685135446Strhodes dns_rdatatype_t covers, dns_name_t **foundname, 686135446Strhodes dns_rdataset_t **rdataset); 687170222Sdougb/*%< 688135446Strhodes * Search for a name in the specified section. If it is found, *name is 689135446Strhodes * set to point to the name, and *rdataset is set to point to the found 690135446Strhodes * rdataset (if type is specified as other than dns_rdatatype_any). 691135446Strhodes * 692135446Strhodes * Requires: 693170222Sdougb *\li 'msg' be valid. 694135446Strhodes * 695170222Sdougb *\li 'section' be a valid section. 696135446Strhodes * 697170222Sdougb *\li If a pointer to the name is desired, 'foundname' should be non-NULL. 698135446Strhodes * If it is non-NULL, '*foundname' MUST be NULL. 699135446Strhodes * 700170222Sdougb *\li If a type other than dns_datatype_any is searched for, 'rdataset' 701135446Strhodes * may be non-NULL, '*rdataset' be NULL, and will point at the found 702135446Strhodes * rdataset. If the type is dns_datatype_any, 'rdataset' must be NULL. 703135446Strhodes * 704170222Sdougb *\li 'target' be a valid name. 705135446Strhodes * 706170222Sdougb *\li 'type' be a valid type. 707135446Strhodes * 708170222Sdougb *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 709135446Strhodes * Otherwise it should be 0. 710135446Strhodes * 711135446Strhodes * Returns: 712170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 713170222Sdougb *\li #DNS_R_NXDOMAIN -- name does not exist in that section. 714170222Sdougb *\li #DNS_R_NXRRSET -- The name does exist, but the desired 715135446Strhodes * type does not. 716135446Strhodes */ 717135446Strhodes 718135446Strhodesisc_result_t 719135446Strhodesdns_message_findtype(dns_name_t *name, dns_rdatatype_t type, 720135446Strhodes dns_rdatatype_t covers, dns_rdataset_t **rdataset); 721170222Sdougb/*%< 722135446Strhodes * Search the name for the specified type. If it is found, *rdataset is 723135446Strhodes * filled in with a pointer to that rdataset. 724135446Strhodes * 725135446Strhodes * Requires: 726170222Sdougb *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. 727135446Strhodes * 728170222Sdougb *\li 'type' be a valid type, and NOT dns_rdatatype_any. 729135446Strhodes * 730170222Sdougb *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 731135446Strhodes * Otherwise it should be 0. 732135446Strhodes * 733135446Strhodes * Returns: 734170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 735170222Sdougb *\li #ISC_R_NOTFOUND -- the desired type does not exist. 736135446Strhodes */ 737135446Strhodes 738165071Sdougbisc_result_t 739165071Sdougbdns_message_find(dns_name_t *name, dns_rdataclass_t rdclass, 740165071Sdougb dns_rdatatype_t type, dns_rdatatype_t covers, 741165071Sdougb dns_rdataset_t **rdataset); 742165071Sdougb/*%< 743165071Sdougb * Search the name for the specified rdclass and type. If it is found, 744165071Sdougb * *rdataset is filled in with a pointer to that rdataset. 745165071Sdougb * 746165071Sdougb * Requires: 747165071Sdougb *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. 748165071Sdougb * 749165071Sdougb *\li 'type' be a valid type, and NOT dns_rdatatype_any. 750165071Sdougb * 751165071Sdougb *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 752165071Sdougb * Otherwise it should be 0. 753165071Sdougb * 754165071Sdougb * Returns: 755165071Sdougb *\li #ISC_R_SUCCESS -- all is well. 756165071Sdougb *\li #ISC_R_NOTFOUND -- the desired type does not exist. 757165071Sdougb */ 758165071Sdougb 759135446Strhodesvoid 760135446Strhodesdns_message_movename(dns_message_t *msg, dns_name_t *name, 761135446Strhodes dns_section_t fromsection, 762135446Strhodes dns_section_t tosection); 763170222Sdougb/*%< 764135446Strhodes * Move a name from one section to another. 765135446Strhodes * 766135446Strhodes * Requires: 767135446Strhodes * 768170222Sdougb *\li 'msg' be valid. 769135446Strhodes * 770170222Sdougb *\li 'name' must be a name already in 'fromsection'. 771135446Strhodes * 772170222Sdougb *\li 'fromsection' must be a valid section. 773135446Strhodes * 774170222Sdougb *\li 'tosection' must be a valid section. 775135446Strhodes */ 776135446Strhodes 777135446Strhodesvoid 778135446Strhodesdns_message_addname(dns_message_t *msg, dns_name_t *name, 779135446Strhodes dns_section_t section); 780170222Sdougb/*%< 781135446Strhodes * Adds the name to the given section. 782135446Strhodes * 783135446Strhodes * It is the caller's responsibility to enforce any unique name requirements 784135446Strhodes * in a section. 785135446Strhodes * 786135446Strhodes * Requires: 787135446Strhodes * 788170222Sdougb *\li 'msg' be valid, and be a renderable message. 789135446Strhodes * 790170222Sdougb *\li 'name' be a valid absolute name. 791135446Strhodes * 792170222Sdougb *\li 'section' be a named section. 793135446Strhodes */ 794135446Strhodes 795170222Sdougbvoid 796170222Sdougbdns_message_removename(dns_message_t *msg, dns_name_t *name, 797193149Sdougb dns_section_t section); 798170222Sdougb/*%< 799170222Sdougb * Remove a existing name from a given section. 800170222Sdougb * 801170222Sdougb * It is the caller's responsibility to ensure the name is part of the 802170222Sdougb * given section. 803170222Sdougb * 804170222Sdougb * Requires: 805170222Sdougb * 806170222Sdougb *\li 'msg' be valid, and be a renderable message. 807170222Sdougb * 808170222Sdougb *\li 'name' be a valid absolute name. 809170222Sdougb * 810170222Sdougb *\li 'section' be a named section. 811170222Sdougb */ 812170222Sdougb 813170222Sdougb 814135446Strhodes/* 815135446Strhodes * LOANOUT FUNCTIONS 816135446Strhodes * 817135446Strhodes * Each of these functions loan a particular type of data to the caller. 818135446Strhodes * The storage for these will vanish when the message is destroyed or 819135446Strhodes * reset, and must NOT be used after these operations. 820135446Strhodes */ 821135446Strhodes 822135446Strhodesisc_result_t 823135446Strhodesdns_message_gettempname(dns_message_t *msg, dns_name_t **item); 824170222Sdougb/*%< 825135446Strhodes * Return a name that can be used for any temporary purpose, including 826135446Strhodes * inserting into the message's linked lists. The name must be returned 827135446Strhodes * to the message code using dns_message_puttempname() or inserted into 828135446Strhodes * one of the message's sections before the message is destroyed. 829135446Strhodes * 830135446Strhodes * It is the caller's responsibility to initialize this name. 831135446Strhodes * 832135446Strhodes * Requires: 833170222Sdougb *\li msg be a valid message 834135446Strhodes * 835170222Sdougb *\li item != NULL && *item == NULL 836135446Strhodes * 837135446Strhodes * Returns: 838170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 839170222Sdougb *\li #ISC_R_NOMEMORY -- No item can be allocated. 840135446Strhodes */ 841135446Strhodes 842135446Strhodesisc_result_t 843135446Strhodesdns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item); 844170222Sdougb/*%< 845135446Strhodes * Return an offsets array that can be used for any temporary purpose, 846135446Strhodes * such as attaching to a temporary name. The offsets will be freed 847135446Strhodes * when the message is destroyed or reset. 848135446Strhodes * 849135446Strhodes * Requires: 850170222Sdougb *\li msg be a valid message 851135446Strhodes * 852170222Sdougb *\li item != NULL && *item == NULL 853135446Strhodes * 854135446Strhodes * Returns: 855170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 856170222Sdougb *\li #ISC_R_NOMEMORY -- No item can be allocated. 857135446Strhodes */ 858135446Strhodes 859135446Strhodesisc_result_t 860135446Strhodesdns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item); 861170222Sdougb/*%< 862135446Strhodes * Return a rdata that can be used for any temporary purpose, including 863135446Strhodes * inserting into the message's linked lists. The rdata will be freed 864135446Strhodes * when the message is destroyed or reset. 865135446Strhodes * 866135446Strhodes * Requires: 867170222Sdougb *\li msg be a valid message 868135446Strhodes * 869170222Sdougb *\li item != NULL && *item == NULL 870135446Strhodes * 871135446Strhodes * Returns: 872170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 873170222Sdougb *\li #ISC_R_NOMEMORY -- No item can be allocated. 874135446Strhodes */ 875135446Strhodes 876135446Strhodesisc_result_t 877135446Strhodesdns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item); 878170222Sdougb/*%< 879135446Strhodes * Return a rdataset that can be used for any temporary purpose, including 880135446Strhodes * inserting into the message's linked lists. The name must be returned 881135446Strhodes * to the message code using dns_message_puttempname() or inserted into 882135446Strhodes * one of the message's sections before the message is destroyed. 883135446Strhodes * 884135446Strhodes * Requires: 885170222Sdougb *\li msg be a valid message 886135446Strhodes * 887170222Sdougb *\li item != NULL && *item == NULL 888135446Strhodes * 889135446Strhodes * Returns: 890170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 891170222Sdougb *\li #ISC_R_NOMEMORY -- No item can be allocated. 892135446Strhodes */ 893135446Strhodes 894135446Strhodesisc_result_t 895135446Strhodesdns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); 896170222Sdougb/*%< 897135446Strhodes * Return a rdatalist that can be used for any temporary purpose, including 898135446Strhodes * inserting into the message's linked lists. The rdatalist will be 899135446Strhodes * destroyed when the message is destroyed or reset. 900135446Strhodes * 901135446Strhodes * Requires: 902170222Sdougb *\li msg be a valid message 903135446Strhodes * 904170222Sdougb *\li item != NULL && *item == NULL 905135446Strhodes * 906135446Strhodes * Returns: 907170222Sdougb *\li #ISC_R_SUCCESS -- All is well. 908170222Sdougb *\li #ISC_R_NOMEMORY -- No item can be allocated. 909135446Strhodes */ 910135446Strhodes 911135446Strhodesvoid 912135446Strhodesdns_message_puttempname(dns_message_t *msg, dns_name_t **item); 913170222Sdougb/*%< 914135446Strhodes * Return a borrowed name to the message's name free list. 915135446Strhodes * 916135446Strhodes * Requires: 917170222Sdougb *\li msg be a valid message 918135446Strhodes * 919170222Sdougb *\li item != NULL && *item point to a name returned by 920135446Strhodes * dns_message_gettempname() 921135446Strhodes * 922135446Strhodes * Ensures: 923170222Sdougb *\li *item == NULL 924135446Strhodes */ 925135446Strhodes 926135446Strhodesvoid 927135446Strhodesdns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item); 928170222Sdougb/*%< 929135446Strhodes * Return a borrowed rdata to the message's rdata free list. 930135446Strhodes * 931135446Strhodes * Requires: 932170222Sdougb *\li msg be a valid message 933135446Strhodes * 934170222Sdougb *\li item != NULL && *item point to a rdata returned by 935135446Strhodes * dns_message_gettemprdata() 936135446Strhodes * 937135446Strhodes * Ensures: 938170222Sdougb *\li *item == NULL 939135446Strhodes */ 940135446Strhodes 941135446Strhodesvoid 942135446Strhodesdns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item); 943170222Sdougb/*%< 944135446Strhodes * Return a borrowed rdataset to the message's rdataset free list. 945135446Strhodes * 946135446Strhodes * Requires: 947170222Sdougb *\li msg be a valid message 948135446Strhodes * 949170222Sdougb *\li item != NULL && *item point to a rdataset returned by 950135446Strhodes * dns_message_gettemprdataset() 951135446Strhodes * 952135446Strhodes * Ensures: 953170222Sdougb *\li *item == NULL 954135446Strhodes */ 955135446Strhodes 956135446Strhodesvoid 957135446Strhodesdns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); 958170222Sdougb/*%< 959135446Strhodes * Return a borrowed rdatalist to the message's rdatalist free list. 960135446Strhodes * 961135446Strhodes * Requires: 962170222Sdougb *\li msg be a valid message 963135446Strhodes * 964170222Sdougb *\li item != NULL && *item point to a rdatalist returned by 965135446Strhodes * dns_message_gettemprdatalist() 966135446Strhodes * 967135446Strhodes * Ensures: 968170222Sdougb *\li *item == NULL 969135446Strhodes */ 970135446Strhodes 971135446Strhodesisc_result_t 972135446Strhodesdns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp, 973135446Strhodes unsigned int *flagsp); 974170222Sdougb/*%< 975135446Strhodes * Assume the remaining region of "source" is a DNS message. Peek into 976135446Strhodes * it and fill in "*idp" with the message id, and "*flagsp" with the flags. 977135446Strhodes * 978135446Strhodes * Requires: 979135446Strhodes * 980170222Sdougb *\li source != NULL 981135446Strhodes * 982135446Strhodes * Ensures: 983135446Strhodes * 984170222Sdougb *\li if (idp != NULL) *idp == message id. 985135446Strhodes * 986170222Sdougb *\li if (flagsp != NULL) *flagsp == message flags. 987135446Strhodes * 988135446Strhodes * Returns: 989135446Strhodes * 990170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 991135446Strhodes * 992170222Sdougb *\li #ISC_R_UNEXPECTEDEND -- buffer doesn't contain enough for a header. 993135446Strhodes */ 994135446Strhodes 995135446Strhodesisc_result_t 996135446Strhodesdns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section); 997170222Sdougb/*%< 998135446Strhodes * Start formatting a reply to the query in 'msg'. 999135446Strhodes * 1000135446Strhodes * Requires: 1001135446Strhodes * 1002170222Sdougb *\li 'msg' is a valid message with parsing intent, and contains a query. 1003135446Strhodes * 1004135446Strhodes * Ensures: 1005135446Strhodes * 1006170222Sdougb *\li The message will have a rendering intent. If 'want_question_section' 1007135446Strhodes * is true, the message opcode is query or notify, and the question 1008135446Strhodes * section is present and properly formatted, then the question section 1009135446Strhodes * will be included in the reply. All other sections will be cleared. 1010135446Strhodes * The QR flag will be set, the RD flag will be preserved, and all other 1011135446Strhodes * flags will be cleared. 1012135446Strhodes * 1013135446Strhodes * Returns: 1014135446Strhodes * 1015170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 1016135446Strhodes * 1017170222Sdougb *\li #DNS_R_FORMERR -- the header or question section of the 1018135446Strhodes * message is invalid, replying is impossible. 1019135446Strhodes * If DNS_R_FORMERR is returned when 1020135446Strhodes * want_question_section is ISC_FALSE, then 1021135446Strhodes * it's the header section that's bad; 1022135446Strhodes * otherwise either of the header or question 1023135446Strhodes * sections may be bad. 1024135446Strhodes */ 1025135446Strhodes 1026135446Strhodesdns_rdataset_t * 1027135446Strhodesdns_message_getopt(dns_message_t *msg); 1028170222Sdougb/*%< 1029135446Strhodes * Get the OPT record for 'msg'. 1030135446Strhodes * 1031135446Strhodes * Requires: 1032135446Strhodes * 1033170222Sdougb *\li 'msg' is a valid message. 1034135446Strhodes * 1035135446Strhodes * Returns: 1036135446Strhodes * 1037170222Sdougb *\li The OPT rdataset of 'msg', or NULL if there isn't one. 1038135446Strhodes */ 1039135446Strhodes 1040135446Strhodesisc_result_t 1041135446Strhodesdns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt); 1042170222Sdougb/*%< 1043135446Strhodes * Set the OPT record for 'msg'. 1044135446Strhodes * 1045135446Strhodes * Requires: 1046135446Strhodes * 1047170222Sdougb *\li 'msg' is a valid message with rendering intent 1048135446Strhodes * and no sections have been rendered. 1049135446Strhodes * 1050170222Sdougb *\li 'opt' is a valid OPT record. 1051135446Strhodes * 1052135446Strhodes * Ensures: 1053135446Strhodes * 1054170222Sdougb *\li The OPT record has either been freed or ownership of it has 1055135446Strhodes * been transferred to the message. 1056135446Strhodes * 1057193149Sdougb *\li If ISC_R_SUCCESS was returned, the OPT record will be rendered 1058135446Strhodes * when dns_message_renderend() is called. 1059135446Strhodes * 1060135446Strhodes * Returns: 1061135446Strhodes * 1062170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 1063135446Strhodes * 1064170222Sdougb *\li #ISC_R_NOSPACE -- there is no space for the OPT record. 1065135446Strhodes */ 1066135446Strhodes 1067135446Strhodesdns_rdataset_t * 1068135446Strhodesdns_message_gettsig(dns_message_t *msg, dns_name_t **owner); 1069170222Sdougb/*%< 1070135446Strhodes * Get the TSIG record and owner for 'msg'. 1071135446Strhodes * 1072135446Strhodes * Requires: 1073135446Strhodes * 1074170222Sdougb *\li 'msg' is a valid message. 1075170222Sdougb *\li 'owner' is NULL or *owner is NULL. 1076135446Strhodes * 1077135446Strhodes * Returns: 1078135446Strhodes * 1079170222Sdougb *\li The TSIG rdataset of 'msg', or NULL if there isn't one. 1080135446Strhodes * 1081135446Strhodes * Ensures: 1082135446Strhodes * 1083170222Sdougb * \li If 'owner' is not NULL, it will point to the owner name. 1084135446Strhodes */ 1085135446Strhodes 1086135446Strhodesisc_result_t 1087135446Strhodesdns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key); 1088170222Sdougb/*%< 1089135446Strhodes * Set the tsig key for 'msg'. This is only necessary for when rendering a 1090135446Strhodes * query or parsing a response. The key (if non-NULL) is attached to, and 1091135446Strhodes * will be detached when the message is destroyed. 1092135446Strhodes * 1093135446Strhodes * Requires: 1094135446Strhodes * 1095170222Sdougb *\li 'msg' is a valid message with rendering intent, 1096135446Strhodes * dns_message_renderbegin() has been called, and no sections have been 1097135446Strhodes * rendered. 1098170222Sdougb *\li 'key' is a valid tsig key or NULL. 1099135446Strhodes * 1100135446Strhodes * Returns: 1101135446Strhodes * 1102170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 1103135446Strhodes * 1104170222Sdougb *\li #ISC_R_NOSPACE -- there is no space for the TSIG record. 1105135446Strhodes */ 1106135446Strhodes 1107135446Strhodesdns_tsigkey_t * 1108135446Strhodesdns_message_gettsigkey(dns_message_t *msg); 1109170222Sdougb/*%< 1110135446Strhodes * Gets the tsig key for 'msg'. 1111135446Strhodes * 1112135446Strhodes * Requires: 1113135446Strhodes * 1114170222Sdougb *\li 'msg' is a valid message 1115135446Strhodes */ 1116135446Strhodes 1117135446Strhodesisc_result_t 1118135446Strhodesdns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig); 1119170222Sdougb/*%< 1120135446Strhodes * Indicates that 'querytsig' is the TSIG from the signed query for which 1121135446Strhodes * 'msg' is the response. This is also used for chained TSIGs in TCP 1122135446Strhodes * responses. 1123135446Strhodes * 1124135446Strhodes * Requires: 1125135446Strhodes * 1126170222Sdougb *\li 'querytsig' is a valid buffer as returned by dns_message_getquerytsig() 1127135446Strhodes * or NULL 1128135446Strhodes * 1129170222Sdougb *\li 'msg' is a valid message 1130135446Strhodes * 1131135446Strhodes * Returns: 1132135446Strhodes * 1133170222Sdougb *\li #ISC_R_SUCCESS 1134170222Sdougb *\li #ISC_R_NOMEMORY 1135135446Strhodes */ 1136135446Strhodes 1137135446Strhodesisc_result_t 1138135446Strhodesdns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx, 1139135446Strhodes isc_buffer_t **querytsig); 1140170222Sdougb/*%< 1141135446Strhodes * Gets the tsig from the TSIG from the signed query 'msg'. This is also used 1142135446Strhodes * for chained TSIGs in TCP responses. Unlike dns_message_gettsig, this makes 1143135446Strhodes * a copy of the data, so can be used if the message is destroyed. 1144135446Strhodes * 1145135446Strhodes * Requires: 1146135446Strhodes * 1147170222Sdougb *\li 'msg' is a valid signed message 1148170222Sdougb *\li 'mctx' is a valid memory context 1149170222Sdougb *\li querytsig != NULL && *querytsig == NULL 1150135446Strhodes * 1151135446Strhodes * Returns: 1152135446Strhodes * 1153170222Sdougb *\li #ISC_R_SUCCESS 1154170222Sdougb *\li #ISC_R_NOMEMORY 1155135446Strhodes * 1156135446Strhodes * Ensures: 1157170222Sdougb *\li 'tsig' points to NULL or an allocated buffer which must be freed 1158135446Strhodes * by the caller. 1159135446Strhodes */ 1160135446Strhodes 1161135446Strhodesdns_rdataset_t * 1162135446Strhodesdns_message_getsig0(dns_message_t *msg, dns_name_t **owner); 1163170222Sdougb/*%< 1164135446Strhodes * Get the SIG(0) record and owner for 'msg'. 1165135446Strhodes * 1166135446Strhodes * Requires: 1167135446Strhodes * 1168170222Sdougb *\li 'msg' is a valid message. 1169170222Sdougb *\li 'owner' is NULL or *owner is NULL. 1170135446Strhodes * 1171135446Strhodes * Returns: 1172135446Strhodes * 1173170222Sdougb *\li The SIG(0) rdataset of 'msg', or NULL if there isn't one. 1174135446Strhodes * 1175135446Strhodes * Ensures: 1176135446Strhodes * 1177170222Sdougb * \li If 'owner' is not NULL, it will point to the owner name. 1178135446Strhodes */ 1179135446Strhodes 1180135446Strhodesisc_result_t 1181135446Strhodesdns_message_setsig0key(dns_message_t *msg, dst_key_t *key); 1182170222Sdougb/*%< 1183135446Strhodes * Set the SIG(0) key for 'msg'. 1184135446Strhodes * 1185135446Strhodes * Requires: 1186135446Strhodes * 1187170222Sdougb *\li 'msg' is a valid message with rendering intent, 1188135446Strhodes * dns_message_renderbegin() has been called, and no sections have been 1189135446Strhodes * rendered. 1190170222Sdougb *\li 'key' is a valid sig key or NULL. 1191135446Strhodes * 1192135446Strhodes * Returns: 1193135446Strhodes * 1194170222Sdougb *\li #ISC_R_SUCCESS -- all is well. 1195135446Strhodes * 1196170222Sdougb *\li #ISC_R_NOSPACE -- there is no space for the SIG(0) record. 1197135446Strhodes */ 1198135446Strhodes 1199135446Strhodesdst_key_t * 1200135446Strhodesdns_message_getsig0key(dns_message_t *msg); 1201170222Sdougb/*%< 1202135446Strhodes * Gets the SIG(0) key for 'msg'. 1203135446Strhodes * 1204135446Strhodes * Requires: 1205135446Strhodes * 1206170222Sdougb *\li 'msg' is a valid message 1207135446Strhodes */ 1208135446Strhodes 1209135446Strhodesvoid 1210135446Strhodesdns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer); 1211170222Sdougb/*%< 1212135446Strhodes * Give the *buffer to the message code to clean up when it is no 1213135446Strhodes * longer needed. This is usually when the message is reset or 1214135446Strhodes * destroyed. 1215135446Strhodes * 1216135446Strhodes * Requires: 1217135446Strhodes * 1218170222Sdougb *\li msg be a valid message. 1219135446Strhodes * 1220170222Sdougb *\li buffer != NULL && *buffer is a valid isc_buffer_t, which was 1221193149Sdougb * dynamically allocated via isc_buffer_allocate(). 1222135446Strhodes */ 1223135446Strhodes 1224135446Strhodesisc_result_t 1225135446Strhodesdns_message_signer(dns_message_t *msg, dns_name_t *signer); 1226170222Sdougb/*%< 1227135446Strhodes * If this message was signed, return the identity of the signer. 1228135446Strhodes * Unless ISC_R_NOTFOUND is returned, signer will reflect the name of the 1229135446Strhodes * key that signed the message. 1230135446Strhodes * 1231135446Strhodes * Requires: 1232135446Strhodes * 1233170222Sdougb *\li msg is a valid parsed message. 1234170222Sdougb *\li signer is a valid name 1235135446Strhodes * 1236135446Strhodes * Returns: 1237135446Strhodes * 1238170222Sdougb *\li #ISC_R_SUCCESS - the message was signed, and *signer 1239135446Strhodes * contains the signing identity 1240135446Strhodes * 1241170222Sdougb *\li #ISC_R_NOTFOUND - no TSIG or SIG(0) record is present in the 1242135446Strhodes * message 1243135446Strhodes * 1244170222Sdougb *\li #DNS_R_TSIGVERIFYFAILURE - the message was signed by a TSIG, but the 1245135446Strhodes * signature failed to verify 1246135446Strhodes * 1247170222Sdougb *\li #DNS_R_TSIGERRORSET - the message was signed by a TSIG and 1248135446Strhodes * verified, but the query was rejected by 1249135446Strhodes * the server 1250135446Strhodes * 1251170222Sdougb *\li #DNS_R_NOIDENTITY - the message was signed by a TSIG and 1252135446Strhodes * verified, but the key has no identity since 1253135446Strhodes * it was generated by an unsigned TKEY process 1254135446Strhodes * 1255170222Sdougb *\li #DNS_R_SIGINVALID - the message was signed by a SIG(0), but 1256135446Strhodes * the signature failed to verify 1257135446Strhodes * 1258170222Sdougb *\li #DNS_R_NOTVERIFIEDYET - the message was signed by a TSIG or SIG(0), 1259135446Strhodes * but the signature has not been verified yet 1260135446Strhodes */ 1261135446Strhodes 1262135446Strhodesisc_result_t 1263135446Strhodesdns_message_checksig(dns_message_t *msg, dns_view_t *view); 1264170222Sdougb/*%< 1265135446Strhodes * If this message was signed, verify the signature. 1266135446Strhodes * 1267135446Strhodes * Requires: 1268135446Strhodes * 1269170222Sdougb *\li msg is a valid parsed message. 1270170222Sdougb *\li view is a valid view or NULL 1271135446Strhodes * 1272135446Strhodes * Returns: 1273135446Strhodes * 1274170222Sdougb *\li #ISC_R_SUCCESS - the message was unsigned, or the message 1275135446Strhodes * was signed correctly. 1276135446Strhodes * 1277170222Sdougb *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen 1278170222Sdougb *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected 1279170222Sdougb *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify 1280135446Strhodes */ 1281135446Strhodes 1282135446Strhodesisc_result_t 1283135446Strhodesdns_message_rechecksig(dns_message_t *msg, dns_view_t *view); 1284170222Sdougb/*%< 1285135446Strhodes * Reset the signature state and then if the message was signed, 1286135446Strhodes * verify the message. 1287135446Strhodes * 1288135446Strhodes * Requires: 1289135446Strhodes * 1290170222Sdougb *\li msg is a valid parsed message. 1291170222Sdougb *\li view is a valid view or NULL 1292135446Strhodes * 1293135446Strhodes * Returns: 1294135446Strhodes * 1295170222Sdougb *\li #ISC_R_SUCCESS - the message was unsigned, or the message 1296135446Strhodes * was signed correctly. 1297135446Strhodes * 1298170222Sdougb *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen 1299170222Sdougb *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected 1300170222Sdougb *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify 1301135446Strhodes */ 1302135446Strhodes 1303135446Strhodesvoid 1304135446Strhodesdns_message_resetsig(dns_message_t *msg); 1305170222Sdougb/*%< 1306135446Strhodes * Reset the signature state. 1307135446Strhodes * 1308135446Strhodes * Requires: 1309170222Sdougb *\li 'msg' is a valid parsed message. 1310135446Strhodes */ 1311135446Strhodes 1312135446Strhodesisc_region_t * 1313135446Strhodesdns_message_getrawmessage(dns_message_t *msg); 1314170222Sdougb/*%< 1315135446Strhodes * Retrieve the raw message in compressed wire format. The message must 1316135446Strhodes * have been successfully parsed for it to have been saved. 1317135446Strhodes * 1318135446Strhodes * Requires: 1319170222Sdougb *\li msg is a valid parsed message. 1320135446Strhodes * 1321135446Strhodes * Returns: 1322170222Sdougb *\li NULL if there is no saved message. 1323135446Strhodes * a pointer to a region which refers the dns message. 1324135446Strhodes */ 1325135446Strhodes 1326135446Strhodesvoid 1327135446Strhodesdns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, 1328165071Sdougb const void *order_arg); 1329170222Sdougb/*%< 1330135446Strhodes * Define the order in which RR sets get rendered by 1331135446Strhodes * dns_message_rendersection() to be the ascending order 1332135446Strhodes * defined by the integer value returned by 'order' when 1333135446Strhodes * given each RR and 'arg' as arguments. If 'order' and 1334135446Strhodes * 'order_arg' are NULL, a default order is used. 1335135446Strhodes * 1336135446Strhodes * Requires: 1337170222Sdougb *\li msg be a valid message. 1338170222Sdougb *\li order_arg is NULL if and only if order is NULL. 1339135446Strhodes */ 1340135446Strhodes 1341193149Sdougbvoid 1342135446Strhodesdns_message_settimeadjust(dns_message_t *msg, int timeadjust); 1343170222Sdougb/*%< 1344135446Strhodes * Adjust the time used to sign/verify a message by timeadjust. 1345135446Strhodes * Currently only TSIG. 1346135446Strhodes * 1347135446Strhodes * Requires: 1348170222Sdougb *\li msg be a valid message. 1349135446Strhodes */ 1350135446Strhodes 1351193149Sdougbint 1352135446Strhodesdns_message_gettimeadjust(dns_message_t *msg); 1353170222Sdougb/*%< 1354135446Strhodes * Return the current time adjustment. 1355135446Strhodes * 1356135446Strhodes * Requires: 1357170222Sdougb *\li msg be a valid message. 1358135446Strhodes */ 1359135446Strhodes 1360254402Serwinisc_result_t 1361254402Serwindns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt, 1362254402Serwin unsigned int version, isc_uint16_t udpsize, 1363254402Serwin unsigned int flags, dns_ednsopt_t *ednsopts, size_t count); 1364254402Serwin/*%< 1365254402Serwin * Built a opt record. 1366254402Serwin * 1367254402Serwin * Requires: 1368254402Serwin * \li msg be a valid message. 1369254402Serwin * \li opt to be a non NULL and *opt to be NULL. 1370254402Serwin * 1371254402Serwin * Returns: 1372254402Serwin * \li ISC_R_SUCCESS on success. 1373254402Serwin * \li ISC_R_NOMEMORY 1374254402Serwin * \li ISC_R_NOSPACE 1375254402Serwin * \li other. 1376254402Serwin */ 1377254402Serwin 1378292321Sdelphijvoid 1379292321Sdelphijdns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass); 1380292321Sdelphij/*%< 1381292321Sdelphij * Set the expected class of records in the response. 1382292321Sdelphij * 1383292321Sdelphij * Requires: 1384292321Sdelphij * \li msg be a valid message with parsing intent. 1385292321Sdelphij */ 1386292321Sdelphij 1387135446StrhodesISC_LANG_ENDDECLS 1388135446Strhodes 1389135446Strhodes#endif /* DNS_MESSAGE_H */ 1390