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