15185a700Sflorian /* 25185a700Sflorian * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 35185a700Sflorian * 45185a700Sflorian * Permission to use, copy, modify, and/or distribute this software for any 55185a700Sflorian * purpose with or without fee is hereby granted, provided that the above 65185a700Sflorian * copyright notice and this permission notice appear in all copies. 75185a700Sflorian * 85185a700Sflorian * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 95185a700Sflorian * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 105185a700Sflorian * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 115185a700Sflorian * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 125185a700Sflorian * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 135185a700Sflorian * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 145185a700Sflorian * PERFORMANCE OF THIS SOFTWARE. 155185a700Sflorian */ 165185a700Sflorian 175185a700Sflorian #ifndef DNS_MESSAGE_H 185185a700Sflorian #define DNS_MESSAGE_H 1 195185a700Sflorian 205185a700Sflorian /*** 215185a700Sflorian *** Imports 225185a700Sflorian ***/ 235185a700Sflorian 245185a700Sflorian #include <dns/compress.h> 255185a700Sflorian #include <dns/masterdump.h> 265185a700Sflorian #include <dns/types.h> 275185a700Sflorian 285185a700Sflorian #include <dst/dst.h> 295185a700Sflorian 305185a700Sflorian /*! \file dns/message.h 315185a700Sflorian * \brief Message Handling Module 325185a700Sflorian * 335185a700Sflorian * How this beast works: 345185a700Sflorian * 355185a700Sflorian * When a dns message is received in a buffer, dns_message_parse() is called 365185a700Sflorian * on the memory region. Various items are checked including the format 375185a700Sflorian * of the message (if counts are right, if counts consume the entire sections, 385185a700Sflorian * and if sections consume the entire message) and known pseudo-RRs in the 395185a700Sflorian * additional data section are analyzed and removed. 405185a700Sflorian * 415185a700Sflorian * TSIG checking is also done at this layer, and any DNSSEC transaction 425185a700Sflorian * signatures should also be checked here. 435185a700Sflorian * 445185a700Sflorian * Notes on using the gettemp*() and puttemp*() functions: 455185a700Sflorian * 465185a700Sflorian * These functions return items (names, rdatasets, etc) allocated from some 475185a700Sflorian * internal state of the dns_message_t. 485185a700Sflorian * 495185a700Sflorian * Names and rdatasets must be put back into the dns_message_t in 505185a700Sflorian * one of two ways. Assume a name was allocated via 515185a700Sflorian * dns_message_gettempname(): 525185a700Sflorian * 535185a700Sflorian *\li (1) insert it into a section, using dns_message_addname(). 545185a700Sflorian * 555185a700Sflorian *\li (2) return it to the message using dns_message_puttempname(). 565185a700Sflorian * 575185a700Sflorian * The same applies to rdatasets. 585185a700Sflorian * 595185a700Sflorian * On the other hand, offsets, rdatalists and rdatas allocated using 605185a700Sflorian * dns_message_gettemp*() will always be freed automatically 615185a700Sflorian * when the message is reset or destroyed; calling dns_message_puttemp*() 625185a700Sflorian * on rdatalists and rdatas is optional and serves only to enable the item 635185a700Sflorian * to be reused multiple times during the lifetime of the message; offsets 645185a700Sflorian * cannot be reused. 655185a700Sflorian * 665185a700Sflorian * Buffers allocated using isc_buffer_allocate() can be automatically freed 675185a700Sflorian * as well by giving the buffer to the message using dns_message_takebuffer(). 685185a700Sflorian * Doing this will cause the buffer to be freed using isc_buffer_free() 695185a700Sflorian * when the section lists are cleared, such as in a reset or in a destroy. 705185a700Sflorian * Since the buffer itself exists until the message is destroyed, this sort 715185a700Sflorian * of code can be written: 725185a700Sflorian * 735185a700Sflorian * \code 745185a700Sflorian * buffer = isc_buffer_allocate(mctx, 512); 755185a700Sflorian * name = NULL; 765185a700Sflorian * name = dns_message_gettempname(message, &name); 775185a700Sflorian * dns_name_init(name, NULL); 785185a700Sflorian * result = dns_name_fromtext(name, &source, dns_rootname, 0, buffer); 795185a700Sflorian * dns_message_takebuffer(message, &buffer); 805185a700Sflorian * \endcode 815185a700Sflorian * 825185a700Sflorian * 835185a700Sflorian * TODO: 845185a700Sflorian * 855185a700Sflorian * XXX Needed: ways to set and retrieve EDNS information, add rdata to a 865185a700Sflorian * section, move rdata from one section to another, remove rdata, etc. 875185a700Sflorian */ 885185a700Sflorian 895185a700Sflorian #define DNS_MESSAGEFLAG_QR 0x8000U 905185a700Sflorian #define DNS_MESSAGEFLAG_AA 0x0400U 915185a700Sflorian #define DNS_MESSAGEFLAG_TC 0x0200U 925185a700Sflorian #define DNS_MESSAGEFLAG_RD 0x0100U 935185a700Sflorian #define DNS_MESSAGEFLAG_RA 0x0080U 945185a700Sflorian #define DNS_MESSAGEFLAG_AD 0x0020U 955185a700Sflorian #define DNS_MESSAGEFLAG_CD 0x0010U 965185a700Sflorian 975185a700Sflorian /*%< EDNS0 extended message flags */ 985185a700Sflorian #define DNS_MESSAGEEXTFLAG_DO 0x8000U 995185a700Sflorian 1005185a700Sflorian /*%< EDNS0 extended OPT codes */ 1015185a700Sflorian #define DNS_OPT_NSID 3 /*%< NSID opt code */ 1025185a700Sflorian #define DNS_OPT_CLIENT_SUBNET 8 /*%< client subnet opt code */ 1035185a700Sflorian #define DNS_OPT_EXPIRE 9 /*%< EXPIRE opt code */ 1045185a700Sflorian #define DNS_OPT_COOKIE 10 /*%< COOKIE opt code */ 1055185a700Sflorian #define DNS_OPT_PAD 12 /*%< PAD opt code */ 1065185a700Sflorian #define DNS_OPT_KEY_TAG 14 /*%< Key tag opt code */ 107fabbbca0Sflorian #define DNS_OPT_EDE 15 /* RFC 8914 */ 108*9835a5e1Sflorian #define DNS_OPT_ZONEVERSION 19 /* RFC 9660 */ 1095185a700Sflorian 1105185a700Sflorian /*%< The number of EDNS options we know about. */ 1115185a700Sflorian #define DNS_EDNSOPTIONS 4 1125185a700Sflorian 1135185a700Sflorian #define DNS_MESSAGE_REPLYPRESERVE (DNS_MESSAGEFLAG_RD|DNS_MESSAGEFLAG_CD) 1145185a700Sflorian #define DNS_MESSAGEEXTFLAG_REPLYPRESERVE (DNS_MESSAGEEXTFLAG_DO) 1155185a700Sflorian 1165185a700Sflorian #define DNS_MESSAGE_HEADERLEN 12 /*%< 6 uint16_t's */ 1175185a700Sflorian 1185185a700Sflorian /* 1195185a700Sflorian * Ordering here matters. DNS_SECTION_ANY must be the lowest and negative, 1205185a700Sflorian * and DNS_SECTION_MAX must be one greater than the last used section. 1215185a700Sflorian */ 1225185a700Sflorian typedef int dns_section_t; 1235185a700Sflorian #define DNS_SECTION_ANY (-1) 1245185a700Sflorian #define DNS_SECTION_QUESTION 0 1255185a700Sflorian #define DNS_SECTION_ANSWER 1 1265185a700Sflorian #define DNS_SECTION_AUTHORITY 2 1275185a700Sflorian #define DNS_SECTION_ADDITIONAL 3 1285185a700Sflorian #define DNS_SECTION_MAX 4 1295185a700Sflorian 1305185a700Sflorian typedef int dns_pseudosection_t; 1315185a700Sflorian #define DNS_PSEUDOSECTION_ANY (-1) 1325185a700Sflorian #define DNS_PSEUDOSECTION_OPT 0 1335185a700Sflorian #define DNS_PSEUDOSECTION_TSIG 1 1345185a700Sflorian #define DNS_PSEUDOSECTION_SIG0 2 1355185a700Sflorian #define DNS_PSEUDOSECTION_MAX 3 1365185a700Sflorian 1375185a700Sflorian typedef int dns_messagetextflag_t; 1385185a700Sflorian #define DNS_MESSAGETEXTFLAG_NOCOMMENTS 0x0001 1395185a700Sflorian #define DNS_MESSAGETEXTFLAG_NOHEADERS 0x0002 1405185a700Sflorian #define DNS_MESSAGETEXTFLAG_ONESOA 0x0004 1415185a700Sflorian #define DNS_MESSAGETEXTFLAG_OMITSOA 0x0008 1425185a700Sflorian 1435185a700Sflorian /* 1445185a700Sflorian * Dynamic update names for these sections. 1455185a700Sflorian */ 1465185a700Sflorian #define DNS_SECTION_ZONE DNS_SECTION_QUESTION 1475185a700Sflorian #define DNS_SECTION_PREREQUISITE DNS_SECTION_ANSWER 1485185a700Sflorian #define DNS_SECTION_UPDATE DNS_SECTION_AUTHORITY 1495185a700Sflorian 1505185a700Sflorian /* 1515185a700Sflorian * These tell the message library how the created dns_message_t will be used. 1525185a700Sflorian */ 1535185a700Sflorian #define DNS_MESSAGE_INTENTUNKNOWN 0 /*%< internal use only */ 1545185a700Sflorian #define DNS_MESSAGE_INTENTPARSE 1 /*%< parsing messages */ 1555185a700Sflorian #define DNS_MESSAGE_INTENTRENDER 2 /*%< rendering */ 1565185a700Sflorian 1575185a700Sflorian /* 1585185a700Sflorian * Control behavior of parsing 1595185a700Sflorian */ 1605185a700Sflorian #define DNS_MESSAGEPARSE_BESTEFFORT 0x0002 /*%< return a message if a 1615185a700Sflorian recoverable parse error 1625185a700Sflorian occurs */ 1635185a700Sflorian #define DNS_MESSAGEPARSE_IGNORETRUNCATION 0x0008 /*%< truncation errors are 1645185a700Sflorian * not fatal. */ 1655185a700Sflorian 1665185a700Sflorian typedef struct dns_msgblock dns_msgblock_t; 1675185a700Sflorian 1685185a700Sflorian struct dns_message { 1695185a700Sflorian /* public from here down */ 1705185a700Sflorian dns_messageid_t id; 1715185a700Sflorian unsigned int flags; 1725185a700Sflorian dns_rcode_t rcode; 1735185a700Sflorian dns_opcode_t opcode; 1745185a700Sflorian dns_rdataclass_t rdclass; 1755185a700Sflorian 1765185a700Sflorian /* 4 real, 1 pseudo */ 1775185a700Sflorian unsigned int counts[DNS_SECTION_MAX]; 1785185a700Sflorian 1795185a700Sflorian /* private from here down */ 1805185a700Sflorian dns_namelist_t sections[DNS_SECTION_MAX]; 1815185a700Sflorian dns_name_t *cursors[DNS_SECTION_MAX]; 1825185a700Sflorian dns_rdataset_t *opt; 1835185a700Sflorian dns_rdataset_t *sig0; 1845185a700Sflorian dns_rdataset_t *tsig; 1855185a700Sflorian 1865185a700Sflorian int state; 1875185a700Sflorian unsigned int from_to_wire : 2; 1885185a700Sflorian unsigned int header_ok : 1; 1895185a700Sflorian unsigned int question_ok : 1; 1905185a700Sflorian unsigned int tcp_continuation : 1; 1915185a700Sflorian unsigned int verified_sig : 1; 1925185a700Sflorian unsigned int verify_attempted : 1; 1935185a700Sflorian unsigned int free_query : 1; 1945185a700Sflorian unsigned int free_saved : 1; 1955185a700Sflorian unsigned int sitok : 1; 1965185a700Sflorian unsigned int sitbad : 1; 1975185a700Sflorian unsigned int tkey : 1; 1985185a700Sflorian unsigned int rdclass_set : 1; 1995185a700Sflorian 2005185a700Sflorian unsigned int opt_reserved; 2015185a700Sflorian unsigned int sig_reserved; 2025185a700Sflorian unsigned int reserved; /* reserved space (render) */ 2035185a700Sflorian 2045185a700Sflorian isc_buffer_t *buffer; 2055185a700Sflorian dns_compress_t *cctx; 2065185a700Sflorian 2075185a700Sflorian isc_bufferlist_t scratchpad; 2085185a700Sflorian isc_bufferlist_t cleanup; 2095185a700Sflorian 2105185a700Sflorian ISC_LIST(dns_msgblock_t) rdatas; 2115185a700Sflorian ISC_LIST(dns_msgblock_t) rdatalists; 2125185a700Sflorian ISC_LIST(dns_msgblock_t) offsets; 2135185a700Sflorian 2145185a700Sflorian ISC_LIST(dns_rdata_t) freerdata; 2155185a700Sflorian ISC_LIST(dns_rdatalist_t) freerdatalist; 2165185a700Sflorian 2175185a700Sflorian dns_rcode_t tsigstatus; 2185185a700Sflorian dns_rcode_t querytsigstatus; 2195185a700Sflorian dns_name_t *tsigname; /* Owner name of TSIG, if any */ 2205185a700Sflorian dns_rdataset_t *querytsig; 2215185a700Sflorian dns_tsigkey_t *tsigkey; 2225185a700Sflorian dst_context_t *tsigctx; 2235185a700Sflorian int sigstart; 2245185a700Sflorian int timeadjust; 2255185a700Sflorian 2265185a700Sflorian dns_name_t *sig0name; /* Owner name of SIG0, if any */ 2275185a700Sflorian dns_rcode_t sig0status; 2285185a700Sflorian isc_region_t query; 2295185a700Sflorian isc_region_t saved; 2305185a700Sflorian }; 2315185a700Sflorian 2325185a700Sflorian struct dns_ednsopt { 2335185a700Sflorian uint16_t code; 2345185a700Sflorian uint16_t length; 2355185a700Sflorian unsigned char *value; 2365185a700Sflorian }; 2375185a700Sflorian 2385185a700Sflorian /*** 2395185a700Sflorian *** Functions 2405185a700Sflorian ***/ 2415185a700Sflorian 2425185a700Sflorian isc_result_t 2435185a700Sflorian dns_message_create(unsigned int intent, dns_message_t **msgp); 2445185a700Sflorian 2455185a700Sflorian /*%< 2465185a700Sflorian * Create msg structure. 2475185a700Sflorian * 2485185a700Sflorian * This function will allocate some internal blocks of memory that are 2495185a700Sflorian * expected to be needed for parsing or rendering nearly any type of message. 2505185a700Sflorian * 2515185a700Sflorian * Requires: 2525185a700Sflorian *\li 'mctx' be a valid memory context. 2535185a700Sflorian * 2545185a700Sflorian *\li 'msgp' be non-null and '*msg' be NULL. 2555185a700Sflorian * 2565185a700Sflorian *\li 'intent' must be one of DNS_MESSAGE_INTENTPARSE or 2575185a700Sflorian * #DNS_MESSAGE_INTENTRENDER. 2585185a700Sflorian * 2595185a700Sflorian * Ensures: 2605185a700Sflorian *\li The data in "*msg" is set to indicate an unused and empty msg 2615185a700Sflorian * structure. 2625185a700Sflorian * 2635185a700Sflorian * Returns: 2645185a700Sflorian *\li #ISC_R_NOMEMORY -- out of memory 2655185a700Sflorian *\li #ISC_R_SUCCESS -- success 2665185a700Sflorian */ 2675185a700Sflorian 2685185a700Sflorian void 2695185a700Sflorian dns_message_destroy(dns_message_t **msgp); 2705185a700Sflorian /*%< 2715185a700Sflorian * Destroy all state in the message. 2725185a700Sflorian * 2735185a700Sflorian * Requires: 2745185a700Sflorian * 2755185a700Sflorian *\li 'msgp' be valid. 2765185a700Sflorian * 2775185a700Sflorian * Ensures: 2785185a700Sflorian *\li '*msgp' == NULL 2795185a700Sflorian */ 2805185a700Sflorian 2815185a700Sflorian isc_result_t 2825185a700Sflorian dns_message_sectiontotext(dns_message_t *msg, dns_section_t section, 2835185a700Sflorian const dns_master_style_t *style, 2845185a700Sflorian dns_messagetextflag_t flags, 2855185a700Sflorian isc_buffer_t *target); 2865185a700Sflorian 2875185a700Sflorian isc_result_t 2885185a700Sflorian dns_message_pseudosectiontotext(dns_message_t *msg, 2895185a700Sflorian dns_pseudosection_t section, 2905185a700Sflorian const dns_master_style_t *style, 2915185a700Sflorian dns_messagetextflag_t flags, 292*9835a5e1Sflorian const char *textname, 2935185a700Sflorian isc_buffer_t *target); 2945185a700Sflorian /*%< 2955185a700Sflorian * Convert section 'section' or 'pseudosection' of message 'msg' to 2965185a700Sflorian * a cleartext representation 2975185a700Sflorian * 2985185a700Sflorian * Notes: 2995185a700Sflorian * \li See dns_message_totext for meanings of flags. 3005185a700Sflorian * 3015185a700Sflorian * Requires: 3025185a700Sflorian * 3035185a700Sflorian *\li 'msg' is a valid message. 3045185a700Sflorian * 3055185a700Sflorian *\li 'style' is a valid master dump style. 3065185a700Sflorian * 3075185a700Sflorian *\li 'target' is a valid buffer. 3085185a700Sflorian * 3095185a700Sflorian *\li 'section' is a valid section label. 3105185a700Sflorian * 3115185a700Sflorian * Ensures: 3125185a700Sflorian * 3135185a700Sflorian *\li If the result is success: 3145185a700Sflorian * The used space in 'target' is updated. 3155185a700Sflorian * 3165185a700Sflorian * Returns: 3175185a700Sflorian * 3185185a700Sflorian *\li #ISC_R_SUCCESS 3195185a700Sflorian *\li #ISC_R_NOSPACE 3205185a700Sflorian *\li #ISC_R_NOMORE 3215185a700Sflorian * 3225185a700Sflorian *\li Note: On error return, *target may be partially filled with data. 3235185a700Sflorian */ 3245185a700Sflorian 3255185a700Sflorian isc_result_t 3265185a700Sflorian dns_message_parse(dns_message_t *msg, isc_buffer_t *source, 3275185a700Sflorian unsigned int options); 3285185a700Sflorian /*%< 3295185a700Sflorian * Parse raw wire data in 'source' as a DNS message. 3305185a700Sflorian * 3315185a700Sflorian * OPT records are detected and stored in the pseudo-section "opt". 3325185a700Sflorian * TSIGs are detected and stored in the pseudo-section "tsig". 3335185a700Sflorian * 334a9a8f5b3Sflorian * A separate dns_name_t object will be created for each RR in the 3355185a700Sflorian * message. Each such dns_name_t will have a single rdataset containing the 3365185a700Sflorian * single RR, and the order of the RRs in the message is preserved. 3375185a700Sflorian * 3385185a700Sflorian * If #DNS_MESSAGEPARSE_BESTEFFORT is set, errors in message content will 3395185a700Sflorian * not be considered FORMERRs. If the entire message can be parsed, it 3405185a700Sflorian * will be returned and DNS_R_RECOVERABLE will be returned. 3415185a700Sflorian * 3425185a700Sflorian * If #DNS_MESSAGEPARSE_IGNORETRUNCATION is set then return as many complete 3435185a700Sflorian * RR's as possible, DNS_R_RECOVERABLE will be returned. 3445185a700Sflorian * 3455185a700Sflorian * 3465185a700Sflorian * Requires: 3475185a700Sflorian *\li "msg" be valid. 3485185a700Sflorian * 3495185a700Sflorian *\li "buffer" be a wire format buffer. 3505185a700Sflorian * 3515185a700Sflorian * Ensures: 3525185a700Sflorian *\li The buffer's data format is correct. 3535185a700Sflorian * 3545185a700Sflorian *\li The buffer's contents verify as correct regarding header bits, buffer 3555185a700Sflorian * and rdata sizes, etc. 3565185a700Sflorian * 3575185a700Sflorian * Returns: 3585185a700Sflorian *\li #ISC_R_SUCCESS -- all is well 3595185a700Sflorian *\li #ISC_R_NOMEMORY -- no memory 3605185a700Sflorian *\li #DNS_R_RECOVERABLE -- the message parsed properly, but contained 3615185a700Sflorian * errors. 3625185a700Sflorian *\li Many other errors possible XXXMLG 3635185a700Sflorian */ 3645185a700Sflorian 3655185a700Sflorian isc_result_t 3665185a700Sflorian dns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx, 3675185a700Sflorian isc_buffer_t *buffer); 3685185a700Sflorian /*%< 3695185a700Sflorian * Begin rendering on a message. Only one call can be made to this function 3705185a700Sflorian * per message. 3715185a700Sflorian * 3725185a700Sflorian * The compression context is "owned" by the message library until 3735185a700Sflorian * dns_message_renderend() is called. It must be invalidated by the caller. 3745185a700Sflorian * 3755185a700Sflorian * The buffer is "owned" by the message library until dns_message_renderend() 3765185a700Sflorian * is called. 3775185a700Sflorian * 3785185a700Sflorian * Requires: 3795185a700Sflorian * 3805185a700Sflorian *\li 'msg' be valid. 3815185a700Sflorian * 3825185a700Sflorian *\li 'cctx' be valid. 3835185a700Sflorian * 3845185a700Sflorian *\li 'buffer' is a valid buffer. 3855185a700Sflorian * 3865185a700Sflorian * Side Effects: 3875185a700Sflorian * 3885185a700Sflorian *\li The buffer is cleared before it is used. 3895185a700Sflorian * 3905185a700Sflorian * Returns: 3915185a700Sflorian *\li #ISC_R_SUCCESS -- all is well 3925185a700Sflorian *\li #ISC_R_NOSPACE -- output buffer is too small 3935185a700Sflorian */ 3945185a700Sflorian 3955185a700Sflorian isc_result_t 3965185a700Sflorian dns_message_renderreserve(dns_message_t *msg, unsigned int space); 3975185a700Sflorian /*%< 3985185a700Sflorian * XXXMLG should use size_t rather than unsigned int once the buffer 3995185a700Sflorian * API is cleaned up 4005185a700Sflorian * 4015185a700Sflorian * Reserve "space" bytes in the given buffer. 4025185a700Sflorian * 4035185a700Sflorian * Requires: 4045185a700Sflorian * 4055185a700Sflorian *\li 'msg' be valid. 4065185a700Sflorian * 4075185a700Sflorian *\li dns_message_renderbegin() was called. 4085185a700Sflorian * 4095185a700Sflorian * Returns: 4105185a700Sflorian *\li #ISC_R_SUCCESS -- all is well. 4115185a700Sflorian *\li #ISC_R_NOSPACE -- not enough free space in the buffer. 4125185a700Sflorian */ 4135185a700Sflorian 4145185a700Sflorian void 4155185a700Sflorian dns_message_renderrelease(dns_message_t *msg, unsigned int space); 4165185a700Sflorian /*%< 4175185a700Sflorian * XXXMLG should use size_t rather than unsigned int once the buffer 4185185a700Sflorian * API is cleaned up 4195185a700Sflorian * 4205185a700Sflorian * Release "space" bytes in the given buffer that was previously reserved. 4215185a700Sflorian * 4225185a700Sflorian * Requires: 4235185a700Sflorian * 4245185a700Sflorian *\li 'msg' be valid. 4255185a700Sflorian * 4265185a700Sflorian *\li 'space' is less than or equal to the total amount of space reserved 4275185a700Sflorian * via prior calls to dns_message_renderreserve(). 4285185a700Sflorian * 4295185a700Sflorian *\li dns_message_renderbegin() was called. 4305185a700Sflorian */ 4315185a700Sflorian 4325185a700Sflorian isc_result_t 4337d5fc286Sflorian dns_message_rendersection(dns_message_t *msg, dns_section_t section); 4345185a700Sflorian /*%< 4355185a700Sflorian * Render all names, rdatalists, etc from the given section at the 4365185a700Sflorian * specified priority or higher. 4375185a700Sflorian * 4385185a700Sflorian * Requires: 4395185a700Sflorian *\li 'msg' be valid. 4405185a700Sflorian * 4415185a700Sflorian *\li 'section' be a valid section. 4425185a700Sflorian * 4435185a700Sflorian *\li dns_message_renderbegin() was called. 4445185a700Sflorian * 4455185a700Sflorian * Returns: 4465185a700Sflorian *\li #ISC_R_SUCCESS -- all records were written, and there are 4475185a700Sflorian * no more records for this section. 4485185a700Sflorian *\li #ISC_R_NOSPACE -- Not enough room in the buffer to write 4495185a700Sflorian * all records requested. 4505185a700Sflorian *\li #DNS_R_MOREDATA -- All requested records written, and there 4515185a700Sflorian * are records remaining for this section. 4525185a700Sflorian */ 4535185a700Sflorian 4545185a700Sflorian void 4555185a700Sflorian dns_message_renderheader(dns_message_t *msg, isc_buffer_t *target); 4565185a700Sflorian /*%< 4575185a700Sflorian * Render the message header. This is implicitly called by 4585185a700Sflorian * dns_message_renderend(). 4595185a700Sflorian * 4605185a700Sflorian * Requires: 4615185a700Sflorian * 4625185a700Sflorian *\li 'msg' be a valid message. 4635185a700Sflorian * 4645185a700Sflorian *\li dns_message_renderbegin() was called. 4655185a700Sflorian * 4665185a700Sflorian *\li 'target' is a valid buffer with enough space to hold a message header 4675185a700Sflorian */ 4685185a700Sflorian 4695185a700Sflorian isc_result_t 4705185a700Sflorian dns_message_renderend(dns_message_t *msg); 4715185a700Sflorian /*%< 4725185a700Sflorian * Finish rendering to the buffer. Note that more data can be in the 4735185a700Sflorian * 'msg' structure. Destroying the structure will free this, or in a multi- 4745185a700Sflorian * part EDNS1 message this data can be rendered to another buffer later. 4755185a700Sflorian * 4765185a700Sflorian * Requires: 4775185a700Sflorian * 4785185a700Sflorian *\li 'msg' be a valid message. 4795185a700Sflorian * 4805185a700Sflorian *\li dns_message_renderbegin() was called. 4815185a700Sflorian * 4825185a700Sflorian * Returns: 4835185a700Sflorian *\li #ISC_R_SUCCESS -- all is well. 4845185a700Sflorian */ 4855185a700Sflorian 4865185a700Sflorian void 4875185a700Sflorian dns_message_renderreset(dns_message_t *msg); 4885185a700Sflorian /*%< 4895185a700Sflorian * Reset the message so that it may be rendered again. 4905185a700Sflorian * 4915185a700Sflorian * Notes: 4925185a700Sflorian * 4935185a700Sflorian *\li If dns_message_renderbegin() has been called, dns_message_renderend() 4945185a700Sflorian * must be called before calling this function. 4955185a700Sflorian * 4965185a700Sflorian * Requires: 4975185a700Sflorian * 4985185a700Sflorian *\li 'msg' be a valid message with rendering intent. 4995185a700Sflorian */ 5005185a700Sflorian 5015185a700Sflorian isc_result_t 5025185a700Sflorian dns_message_firstname(dns_message_t *msg, dns_section_t section); 5035185a700Sflorian /*%< 5045185a700Sflorian * Set internal per-section name pointer to the beginning of the section. 5055185a700Sflorian * 5065185a700Sflorian * The functions dns_message_firstname() and dns_message_nextname() may 5075185a700Sflorian * be used for iterating over the owner names in a section. 5085185a700Sflorian * 5095185a700Sflorian * Requires: 5105185a700Sflorian * 5115185a700Sflorian *\li 'msg' be valid. 5125185a700Sflorian * 5135185a700Sflorian *\li 'section' be a valid section. 5145185a700Sflorian * 5155185a700Sflorian * Returns: 5165185a700Sflorian *\li #ISC_R_SUCCESS -- All is well. 5175185a700Sflorian *\li #ISC_R_NOMORE -- No names on given section. 5185185a700Sflorian */ 5195185a700Sflorian 5205185a700Sflorian isc_result_t 5215185a700Sflorian dns_message_nextname(dns_message_t *msg, dns_section_t section); 5225185a700Sflorian /*%< 5235185a700Sflorian * Sets the internal per-section name pointer to point to the next name 5245185a700Sflorian * in that section. 5255185a700Sflorian * 5265185a700Sflorian * Requires: 5275185a700Sflorian * 5285185a700Sflorian * \li 'msg' be valid. 5295185a700Sflorian * 5305185a700Sflorian *\li 'section' be a valid section. 5315185a700Sflorian * 5325185a700Sflorian *\li dns_message_firstname() must have been called on this section, 5335185a700Sflorian * and the result was ISC_R_SUCCESS. 5345185a700Sflorian * 5355185a700Sflorian * Returns: 5365185a700Sflorian *\li #ISC_R_SUCCESS -- All is well. 5375185a700Sflorian *\li #ISC_R_NOMORE -- No more names in given section. 5385185a700Sflorian */ 5395185a700Sflorian 5405185a700Sflorian void 5415185a700Sflorian dns_message_currentname(dns_message_t *msg, dns_section_t section, 5425185a700Sflorian dns_name_t **name); 5435185a700Sflorian /*%< 5445185a700Sflorian * Sets 'name' to point to the name where the per-section internal name 5455185a700Sflorian * pointer is currently set. 5465185a700Sflorian * 5475185a700Sflorian * This function returns the name in the database, so any data associated 5485185a700Sflorian * with it (via the name's "list" member) contains the actual rdatasets. 5495185a700Sflorian * 5505185a700Sflorian * Requires: 5515185a700Sflorian * 5525185a700Sflorian *\li 'msg' be valid. 5535185a700Sflorian * 5545185a700Sflorian *\li 'name' be non-NULL, and *name be NULL. 5555185a700Sflorian * 5565185a700Sflorian *\li 'section' be a valid section. 5575185a700Sflorian * 5585185a700Sflorian *\li dns_message_firstname() must have been called on this section, 5595185a700Sflorian * and the result of it and any dns_message_nextname() calls was 5605185a700Sflorian * #ISC_R_SUCCESS. 5615185a700Sflorian */ 5625185a700Sflorian 5635185a700Sflorian isc_result_t 5645185a700Sflorian dns_message_findname(dns_message_t *msg, dns_section_t section, 5655185a700Sflorian dns_name_t *target, dns_rdatatype_t type, 5665185a700Sflorian dns_rdatatype_t covers, dns_name_t **foundname, 5675185a700Sflorian dns_rdataset_t **rdataset); 5685185a700Sflorian /*%< 5695185a700Sflorian * Search for a name in the specified section. If it is found, *name is 5705185a700Sflorian * set to point to the name, and *rdataset is set to point to the found 5715185a700Sflorian * rdataset (if type is specified as other than dns_rdatatype_any). 5725185a700Sflorian * 5735185a700Sflorian * Requires: 5745185a700Sflorian *\li 'msg' be valid. 5755185a700Sflorian * 5765185a700Sflorian *\li 'section' be a valid section. 5775185a700Sflorian * 5785185a700Sflorian *\li If a pointer to the name is desired, 'foundname' should be non-NULL. 5795185a700Sflorian * If it is non-NULL, '*foundname' MUST be NULL. 5805185a700Sflorian * 5815185a700Sflorian *\li If a type other than dns_datatype_any is searched for, 'rdataset' 5825185a700Sflorian * may be non-NULL, '*rdataset' be NULL, and will point at the found 5835185a700Sflorian * rdataset. If the type is dns_datatype_any, 'rdataset' must be NULL. 5845185a700Sflorian * 5855185a700Sflorian *\li 'target' be a valid name. 5865185a700Sflorian * 5875185a700Sflorian *\li 'type' be a valid type. 5885185a700Sflorian * 5895185a700Sflorian *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 5905185a700Sflorian * Otherwise it should be 0. 5915185a700Sflorian * 5925185a700Sflorian * Returns: 5935185a700Sflorian *\li #ISC_R_SUCCESS -- all is well. 5945185a700Sflorian *\li #DNS_R_NXDOMAIN -- name does not exist in that section. 5955185a700Sflorian *\li #DNS_R_NXRRSET -- The name does exist, but the desired 5965185a700Sflorian * type does not. 5975185a700Sflorian */ 5985185a700Sflorian 5995185a700Sflorian isc_result_t 6005185a700Sflorian dns_message_findtype(dns_name_t *name, dns_rdatatype_t type, 6015185a700Sflorian dns_rdatatype_t covers, dns_rdataset_t **rdataset); 6025185a700Sflorian /*%< 6035185a700Sflorian * Search the name for the specified type. If it is found, *rdataset is 6045185a700Sflorian * filled in with a pointer to that rdataset. 6055185a700Sflorian * 6065185a700Sflorian * Requires: 6075185a700Sflorian *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. 6085185a700Sflorian * 6095185a700Sflorian *\li 'type' be a valid type, and NOT dns_rdatatype_any. 6105185a700Sflorian * 6115185a700Sflorian *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 6125185a700Sflorian * Otherwise it should be 0. 6135185a700Sflorian * 6145185a700Sflorian * Returns: 6155185a700Sflorian *\li #ISC_R_SUCCESS -- all is well. 6165185a700Sflorian *\li #ISC_R_NOTFOUND -- the desired type does not exist. 6175185a700Sflorian */ 6185185a700Sflorian 6195185a700Sflorian isc_result_t 6205185a700Sflorian dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass, 6215185a700Sflorian dns_rdatatype_t type, dns_rdatatype_t covers, 6225185a700Sflorian dns_rdataset_t **rdataset); 6235185a700Sflorian /*%< 6245185a700Sflorian * Search the name for the specified rdclass and type. If it is found, 6255185a700Sflorian * *rdataset is filled in with a pointer to that rdataset. 6265185a700Sflorian * 6275185a700Sflorian * Requires: 6285185a700Sflorian *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. 6295185a700Sflorian * 6305185a700Sflorian *\li 'type' be a valid type, and NOT dns_rdatatype_any. 6315185a700Sflorian * 6325185a700Sflorian *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. 6335185a700Sflorian * Otherwise it should be 0. 6345185a700Sflorian * 6355185a700Sflorian * Returns: 6365185a700Sflorian *\li #ISC_R_SUCCESS -- all is well. 6375185a700Sflorian *\li #ISC_R_NOTFOUND -- the desired type does not exist. 6385185a700Sflorian */ 6395185a700Sflorian 6405185a700Sflorian void 6415185a700Sflorian dns_message_addname(dns_message_t *msg, dns_name_t *name, 6425185a700Sflorian dns_section_t section); 6435185a700Sflorian /*%< 6445185a700Sflorian * Adds the name to the given section. 6455185a700Sflorian * 6465185a700Sflorian * It is the caller's responsibility to enforce any unique name requirements 6475185a700Sflorian * in a section. 6485185a700Sflorian * 6495185a700Sflorian * Requires: 6505185a700Sflorian * 6515185a700Sflorian *\li 'msg' be valid, and be a renderable message. 6525185a700Sflorian * 6535185a700Sflorian *\li 'name' be a valid absolute name. 6545185a700Sflorian * 6555185a700Sflorian *\li 'section' be a named section. 6565185a700Sflorian */ 6575185a700Sflorian 6585185a700Sflorian /* 6595185a700Sflorian * LOANOUT FUNCTIONS 6605185a700Sflorian * 6615185a700Sflorian * Each of these functions loan a particular type of data to the caller. 6625185a700Sflorian * The storage for these will vanish when the message is destroyed or 6635185a700Sflorian * reset, and must NOT be used after these operations. 6645185a700Sflorian */ 6655185a700Sflorian 6665185a700Sflorian isc_result_t 6675185a700Sflorian dns_message_gettempname(dns_message_t *msg, dns_name_t **item); 6685185a700Sflorian /*%< 6695185a700Sflorian * Return a name that can be used for any temporary purpose, including 6705185a700Sflorian * inserting into the message's linked lists. The name must be returned 6715185a700Sflorian * to the message code using dns_message_puttempname() or inserted into 6725185a700Sflorian * one of the message's sections before the message is destroyed. 6735185a700Sflorian * 6745185a700Sflorian * It is the caller's responsibility to initialize this name. 6755185a700Sflorian * 6765185a700Sflorian * Requires: 6775185a700Sflorian *\li msg be a valid message 6785185a700Sflorian * 6795185a700Sflorian *\li item != NULL && *item == NULL 6805185a700Sflorian * 6815185a700Sflorian * Returns: 6825185a700Sflorian *\li #ISC_R_SUCCESS -- All is well. 6835185a700Sflorian *\li #ISC_R_NOMEMORY -- No item can be allocated. 6845185a700Sflorian */ 6855185a700Sflorian 6865185a700Sflorian isc_result_t 6875185a700Sflorian dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item); 6885185a700Sflorian /*%< 6895185a700Sflorian * Return a rdata that can be used for any temporary purpose, including 6905185a700Sflorian * inserting into the message's linked lists. The rdata will be freed 6915185a700Sflorian * when the message is destroyed or reset. 6925185a700Sflorian * 6935185a700Sflorian * Requires: 6945185a700Sflorian *\li msg be a valid message 6955185a700Sflorian * 6965185a700Sflorian *\li item != NULL && *item == NULL 6975185a700Sflorian * 6985185a700Sflorian * Returns: 6995185a700Sflorian *\li #ISC_R_SUCCESS -- All is well. 7005185a700Sflorian *\li #ISC_R_NOMEMORY -- No item can be allocated. 7015185a700Sflorian */ 7025185a700Sflorian 7035185a700Sflorian isc_result_t 7045185a700Sflorian dns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item); 7055185a700Sflorian /*%< 7065185a700Sflorian * Return a rdataset that can be used for any temporary purpose, including 7075185a700Sflorian * inserting into the message's linked lists. The name must be returned 7085185a700Sflorian * to the message code using dns_message_puttempname() or inserted into 7095185a700Sflorian * one of the message's sections before the message is destroyed. 7105185a700Sflorian * 7115185a700Sflorian * Requires: 7125185a700Sflorian *\li msg be a valid message 7135185a700Sflorian * 7145185a700Sflorian *\li item != NULL && *item == NULL 7155185a700Sflorian * 7165185a700Sflorian * Returns: 7175185a700Sflorian *\li #ISC_R_SUCCESS -- All is well. 7185185a700Sflorian *\li #ISC_R_NOMEMORY -- No item can be allocated. 7195185a700Sflorian */ 7205185a700Sflorian 7215185a700Sflorian isc_result_t 7225185a700Sflorian dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); 7235185a700Sflorian /*%< 7245185a700Sflorian * Return a rdatalist that can be used for any temporary purpose, including 7255185a700Sflorian * inserting into the message's linked lists. The rdatalist will be 7265185a700Sflorian * destroyed when the message is destroyed or reset. 7275185a700Sflorian * 7285185a700Sflorian * Requires: 7295185a700Sflorian *\li msg be a valid message 7305185a700Sflorian * 7315185a700Sflorian *\li item != NULL && *item == NULL 7325185a700Sflorian * 7335185a700Sflorian * Returns: 7345185a700Sflorian *\li #ISC_R_SUCCESS -- All is well. 7355185a700Sflorian *\li #ISC_R_NOMEMORY -- No item can be allocated. 7365185a700Sflorian */ 7375185a700Sflorian 7385185a700Sflorian void 7395185a700Sflorian dns_message_puttempname(dns_message_t *msg, dns_name_t **item); 7405185a700Sflorian /*%< 7415185a700Sflorian * Return a borrowed name to the message's name free list. 7425185a700Sflorian * 7435185a700Sflorian * Requires: 7445185a700Sflorian *\li msg be a valid message 7455185a700Sflorian * 7465185a700Sflorian *\li item != NULL && *item point to a name returned by 7475185a700Sflorian * dns_message_gettempname() 7485185a700Sflorian * 7495185a700Sflorian * Ensures: 7505185a700Sflorian *\li *item == NULL 7515185a700Sflorian */ 7525185a700Sflorian 7535185a700Sflorian void 7545185a700Sflorian dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item); 7555185a700Sflorian /*%< 7565185a700Sflorian * Return a borrowed rdata to the message's rdata free list. 7575185a700Sflorian * 7585185a700Sflorian * Requires: 7595185a700Sflorian *\li msg be a valid message 7605185a700Sflorian * 7615185a700Sflorian *\li item != NULL && *item point to a rdata returned by 7625185a700Sflorian * dns_message_gettemprdata() 7635185a700Sflorian * 7645185a700Sflorian * Ensures: 7655185a700Sflorian *\li *item == NULL 7665185a700Sflorian */ 7675185a700Sflorian 7685185a700Sflorian void 7695185a700Sflorian dns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item); 7705185a700Sflorian /*%< 7715185a700Sflorian * Return a borrowed rdataset to the message's rdataset free list. 7725185a700Sflorian * 7735185a700Sflorian * Requires: 7745185a700Sflorian *\li msg be a valid message 7755185a700Sflorian * 7765185a700Sflorian *\li item != NULL && *item point to a rdataset returned by 7775185a700Sflorian * dns_message_gettemprdataset() 7785185a700Sflorian * 7795185a700Sflorian * Ensures: 7805185a700Sflorian *\li *item == NULL 7815185a700Sflorian */ 7825185a700Sflorian 7835185a700Sflorian void 7845185a700Sflorian dns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item); 7855185a700Sflorian /*%< 7865185a700Sflorian * Return a borrowed rdatalist to the message's rdatalist free list. 7875185a700Sflorian * 7885185a700Sflorian * Requires: 7895185a700Sflorian *\li msg be a valid message 7905185a700Sflorian * 7915185a700Sflorian *\li item != NULL && *item point to a rdatalist returned by 7925185a700Sflorian * dns_message_gettemprdatalist() 7935185a700Sflorian * 7945185a700Sflorian * Ensures: 7955185a700Sflorian *\li *item == NULL 7965185a700Sflorian */ 7975185a700Sflorian 7985185a700Sflorian isc_result_t 7995185a700Sflorian dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp, 8005185a700Sflorian unsigned int *flagsp); 8015185a700Sflorian /*%< 8025185a700Sflorian * Assume the remaining region of "source" is a DNS message. Peek into 8035185a700Sflorian * it and fill in "*idp" with the message id, and "*flagsp" with the flags. 8045185a700Sflorian * 8055185a700Sflorian * Requires: 8065185a700Sflorian * 8075185a700Sflorian *\li source != NULL 8085185a700Sflorian * 8095185a700Sflorian * Ensures: 8105185a700Sflorian * 8115185a700Sflorian *\li if (idp != NULL) *idp == message id. 8125185a700Sflorian * 8135185a700Sflorian *\li if (flagsp != NULL) *flagsp == message flags. 8145185a700Sflorian * 8155185a700Sflorian * Returns: 8165185a700Sflorian * 8175185a700Sflorian *\li #ISC_R_SUCCESS -- all is well. 8185185a700Sflorian * 8195185a700Sflorian *\li #ISC_R_UNEXPECTEDEND -- buffer doesn't contain enough for a header. 8205185a700Sflorian */ 8215185a700Sflorian 8225185a700Sflorian dns_rdataset_t * 8235185a700Sflorian dns_message_getopt(dns_message_t *msg); 8245185a700Sflorian /*%< 8255185a700Sflorian * Get the OPT record for 'msg'. 8265185a700Sflorian * 8275185a700Sflorian * Requires: 8285185a700Sflorian * 8295185a700Sflorian *\li 'msg' is a valid message. 8305185a700Sflorian * 8315185a700Sflorian * Returns: 8325185a700Sflorian * 8335185a700Sflorian *\li The OPT rdataset of 'msg', or NULL if there isn't one. 8345185a700Sflorian */ 8355185a700Sflorian 8365185a700Sflorian isc_result_t 8375185a700Sflorian dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt); 8385185a700Sflorian /*%< 8395185a700Sflorian * Set the OPT record for 'msg'. 8405185a700Sflorian * 8415185a700Sflorian * Requires: 8425185a700Sflorian * 8435185a700Sflorian *\li 'msg' is a valid message with rendering intent 8445185a700Sflorian * and no sections have been rendered. 8455185a700Sflorian * 8465185a700Sflorian *\li 'opt' is a valid OPT record. 8475185a700Sflorian * 8485185a700Sflorian * Ensures: 8495185a700Sflorian * 8505185a700Sflorian *\li The OPT record has either been freed or ownership of it has 8515185a700Sflorian * been transferred to the message. 8525185a700Sflorian * 8535185a700Sflorian *\li If ISC_R_SUCCESS was returned, the OPT record will be rendered 8545185a700Sflorian * when dns_message_renderend() is called. 8555185a700Sflorian * 8565185a700Sflorian * Returns: 8575185a700Sflorian * 8585185a700Sflorian *\li #ISC_R_SUCCESS -- all is well. 8595185a700Sflorian * 8605185a700Sflorian *\li #ISC_R_NOSPACE -- there is no space for the OPT record. 8615185a700Sflorian */ 8625185a700Sflorian 8635185a700Sflorian dns_rdataset_t * 8645185a700Sflorian dns_message_gettsig(dns_message_t *msg, dns_name_t **owner); 8655185a700Sflorian /*%< 8665185a700Sflorian * Get the TSIG record and owner for 'msg'. 8675185a700Sflorian * 8685185a700Sflorian * Requires: 8695185a700Sflorian * 8705185a700Sflorian *\li 'msg' is a valid message. 8715185a700Sflorian *\li 'owner' is NULL or *owner is NULL. 8725185a700Sflorian * 8735185a700Sflorian * Returns: 8745185a700Sflorian * 8755185a700Sflorian *\li The TSIG rdataset of 'msg', or NULL if there isn't one. 8765185a700Sflorian * 8775185a700Sflorian * Ensures: 8785185a700Sflorian * 8795185a700Sflorian * \li If 'owner' is not NULL, it will point to the owner name. 8805185a700Sflorian */ 8815185a700Sflorian 8825185a700Sflorian isc_result_t 8835185a700Sflorian dns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key); 8845185a700Sflorian /*%< 8855185a700Sflorian * Set the tsig key for 'msg'. This is only necessary for when rendering a 8865185a700Sflorian * query or parsing a response. The key (if non-NULL) is attached to, and 8875185a700Sflorian * will be detached when the message is destroyed. 8885185a700Sflorian * 8895185a700Sflorian * Requires: 8905185a700Sflorian * 8915185a700Sflorian *\li 'msg' is a valid message with rendering intent, 8925185a700Sflorian * dns_message_renderbegin() has been called, and no sections have been 8935185a700Sflorian * rendered. 8945185a700Sflorian *\li 'key' is a valid tsig key or NULL. 8955185a700Sflorian * 8965185a700Sflorian * Returns: 8975185a700Sflorian * 8985185a700Sflorian *\li #ISC_R_SUCCESS -- all is well. 8995185a700Sflorian * 9005185a700Sflorian *\li #ISC_R_NOSPACE -- there is no space for the TSIG record. 9015185a700Sflorian */ 9025185a700Sflorian 9035185a700Sflorian dns_tsigkey_t * 9045185a700Sflorian dns_message_gettsigkey(dns_message_t *msg); 9055185a700Sflorian /*%< 9065185a700Sflorian * Gets the tsig key for 'msg'. 9075185a700Sflorian * 9085185a700Sflorian * Requires: 9095185a700Sflorian * 9105185a700Sflorian *\li 'msg' is a valid message 9115185a700Sflorian */ 9125185a700Sflorian 9135185a700Sflorian isc_result_t 9145185a700Sflorian dns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig); 9155185a700Sflorian /*%< 9165185a700Sflorian * Indicates that 'querytsig' is the TSIG from the signed query for which 9175185a700Sflorian * 'msg' is the response. This is also used for chained TSIGs in TCP 9185185a700Sflorian * responses. 9195185a700Sflorian * 9205185a700Sflorian * Requires: 9215185a700Sflorian * 9225185a700Sflorian *\li 'querytsig' is a valid buffer as returned by dns_message_getquerytsig() 9235185a700Sflorian * or NULL 9245185a700Sflorian * 9255185a700Sflorian *\li 'msg' is a valid message 9265185a700Sflorian * 9275185a700Sflorian * Returns: 9285185a700Sflorian * 9295185a700Sflorian *\li #ISC_R_SUCCESS 9305185a700Sflorian *\li #ISC_R_NOMEMORY 9315185a700Sflorian */ 9325185a700Sflorian 9335185a700Sflorian isc_result_t 9345185a700Sflorian dns_message_getquerytsig(dns_message_t *msg, isc_buffer_t **querytsig); 9355185a700Sflorian /*%< 9365185a700Sflorian * Gets the tsig from the TSIG from the signed query 'msg'. This is also used 9375185a700Sflorian * for chained TSIGs in TCP responses. Unlike dns_message_gettsig, this makes 9385185a700Sflorian * a copy of the data, so can be used if the message is destroyed. 9395185a700Sflorian * 9405185a700Sflorian * Requires: 9415185a700Sflorian * 9425185a700Sflorian *\li 'msg' is a valid signed message 9435185a700Sflorian *\li 'mctx' is a valid memory context 9445185a700Sflorian *\li querytsig != NULL && *querytsig == NULL 9455185a700Sflorian * 9465185a700Sflorian * Returns: 9475185a700Sflorian * 9485185a700Sflorian *\li #ISC_R_SUCCESS 9495185a700Sflorian *\li #ISC_R_NOMEMORY 9505185a700Sflorian * 9515185a700Sflorian * Ensures: 9525185a700Sflorian *\li 'tsig' points to NULL or an allocated buffer which must be freed 9535185a700Sflorian * by the caller. 9545185a700Sflorian */ 9555185a700Sflorian 9565185a700Sflorian dns_rdataset_t * 9575185a700Sflorian dns_message_getsig0(dns_message_t *msg, dns_name_t **owner); 9585185a700Sflorian /*%< 9595185a700Sflorian * Get the SIG(0) record and owner for 'msg'. 9605185a700Sflorian * 9615185a700Sflorian * Requires: 9625185a700Sflorian * 9635185a700Sflorian *\li 'msg' is a valid message. 9645185a700Sflorian *\li 'owner' is NULL or *owner is NULL. 9655185a700Sflorian * 9665185a700Sflorian * Returns: 9675185a700Sflorian * 9685185a700Sflorian *\li The SIG(0) rdataset of 'msg', or NULL if there isn't one. 9695185a700Sflorian * 9705185a700Sflorian * Ensures: 9715185a700Sflorian * 9725185a700Sflorian * \li If 'owner' is not NULL, it will point to the owner name. 9735185a700Sflorian */ 9745185a700Sflorian 9755185a700Sflorian void 9765185a700Sflorian dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer); 9775185a700Sflorian /*%< 9785185a700Sflorian * Give the *buffer to the message code to clean up when it is no 9795185a700Sflorian * longer needed. This is usually when the message is reset or 9805185a700Sflorian * destroyed. 9815185a700Sflorian * 9825185a700Sflorian * Requires: 9835185a700Sflorian * 9845185a700Sflorian *\li msg be a valid message. 9855185a700Sflorian * 9865185a700Sflorian *\li buffer != NULL && *buffer is a valid isc_buffer_t, which was 9875185a700Sflorian * dynamically allocated via isc_buffer_allocate(). 9885185a700Sflorian */ 9895185a700Sflorian 9905185a700Sflorian isc_result_t 9915185a700Sflorian dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt, 9925185a700Sflorian unsigned int version, uint16_t udpsize, 9935185a700Sflorian unsigned int flags, dns_ednsopt_t *ednsopts, size_t count); 9945185a700Sflorian /*%< 9955185a700Sflorian * Built a opt record. 9965185a700Sflorian * 9975185a700Sflorian * Requires: 9985185a700Sflorian * \li msg be a valid message. 9995185a700Sflorian * \li opt to be a non NULL and *opt to be NULL. 10005185a700Sflorian * 10015185a700Sflorian * Returns: 10025185a700Sflorian * \li ISC_R_SUCCESS on success. 10035185a700Sflorian * \li ISC_R_NOMEMORY 10045185a700Sflorian * \li ISC_R_NOSPACE 10055185a700Sflorian * \li other. 10065185a700Sflorian */ 10075185a700Sflorian 10085185a700Sflorian #endif /* DNS_MESSAGE_H */ 1009