1*ee791febSAntonio Huete Jimenez /* 2*ee791febSAntonio Huete Jimenez * edns.h 3*ee791febSAntonio Huete Jimenez * 4*ee791febSAntonio Huete Jimenez * 5*ee791febSAntonio Huete Jimenez * a Net::DNS like library for C 6*ee791febSAntonio Huete Jimenez * 7*ee791febSAntonio Huete Jimenez * (c) NLnet Labs, 2004-2022 8*ee791febSAntonio Huete Jimenez * 9*ee791febSAntonio Huete Jimenez * See the file LICENSE for the license 10*ee791febSAntonio Huete Jimenez */ 11*ee791febSAntonio Huete Jimenez 12*ee791febSAntonio Huete Jimenez #ifndef LDNS_EDNS_H 13*ee791febSAntonio Huete Jimenez #define LDNS_EDNS_H 14*ee791febSAntonio Huete Jimenez 15*ee791febSAntonio Huete Jimenez #include <ldns/common.h> 16*ee791febSAntonio Huete Jimenez 17*ee791febSAntonio Huete Jimenez #ifdef __cplusplus 18*ee791febSAntonio Huete Jimenez extern "C" { 19*ee791febSAntonio Huete Jimenez #endif 20*ee791febSAntonio Huete Jimenez 21*ee791febSAntonio Huete Jimenez 22*ee791febSAntonio Huete Jimenez 23*ee791febSAntonio Huete Jimenez /** 24*ee791febSAntonio Huete Jimenez * EDNS option codes 25*ee791febSAntonio Huete Jimenez */ 26*ee791febSAntonio Huete Jimenez enum ldns_enum_edns_option 27*ee791febSAntonio Huete Jimenez { 28*ee791febSAntonio Huete Jimenez LDNS_EDNS_LLQ = 1, /* RFC8764 */ 29*ee791febSAntonio Huete Jimenez LDNS_EDNS_UL = 2, /* http://files.dns-sd.org/draft-sekar-dns-ul.txt */ 30*ee791febSAntonio Huete Jimenez LDNS_EDNS_NSID = 3, /* RFC5001 */ 31*ee791febSAntonio Huete Jimenez /* 4 draft-cheshire-edns0-owner-option */ 32*ee791febSAntonio Huete Jimenez LDNS_EDNS_DAU = 5, /* RFC6975 */ 33*ee791febSAntonio Huete Jimenez LDNS_EDNS_DHU = 6, /* RFC6975 */ 34*ee791febSAntonio Huete Jimenez LDNS_EDNS_N3U = 7, /* RFC6975 */ 35*ee791febSAntonio Huete Jimenez LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */ 36*ee791febSAntonio Huete Jimenez LDNS_EDNS_EXPIRE = 9, /* RFC7314 */ 37*ee791febSAntonio Huete Jimenez LDNS_EDNS_COOKIE = 10, /* RFC7873 */ 38*ee791febSAntonio Huete Jimenez LDNS_EDNS_KEEPALIVE = 11, /* RFC7828*/ 39*ee791febSAntonio Huete Jimenez LDNS_EDNS_PADDING = 12, /* RFC7830 */ 40*ee791febSAntonio Huete Jimenez LDNS_EDNS_CHAIN = 13, /* RFC7901 */ 41*ee791febSAntonio Huete Jimenez LDNS_EDNS_KEY_TAG = 14, /* RFC8145 */ 42*ee791febSAntonio Huete Jimenez LDNS_EDNS_EDE = 15, /* RFC8914 */ 43*ee791febSAntonio Huete Jimenez LDNS_EDNS_CLIENT_TAG = 16, /* draft-bellis-dnsop-edns-tags-01 */ 44*ee791febSAntonio Huete Jimenez LDNS_EDNS_SERVER_TAG = 17 /* draft-bellis-dnsop-edns-tags-01 */ 45*ee791febSAntonio Huete Jimenez }; 46*ee791febSAntonio Huete Jimenez typedef enum ldns_enum_edns_option ldns_edns_option_code; 47*ee791febSAntonio Huete Jimenez 48*ee791febSAntonio Huete Jimenez /** 49*ee791febSAntonio Huete Jimenez * Extended DNS Error (RFC 8914) codes 50*ee791febSAntonio Huete Jimenez */ 51*ee791febSAntonio Huete Jimenez enum ldns_edns_enum_ede_code 52*ee791febSAntonio Huete Jimenez { 53*ee791febSAntonio Huete Jimenez LDNS_EDE_OTHER = 0, 54*ee791febSAntonio Huete Jimenez LDNS_EDE_UNSUPPORTED_DNSKEY_ALG = 1, 55*ee791febSAntonio Huete Jimenez LDNS_EDE_UNSUPPORTED_DS_DIGEST = 2, 56*ee791febSAntonio Huete Jimenez LDNS_EDE_STALE_ANSWER = 3, 57*ee791febSAntonio Huete Jimenez LDNS_EDE_FORGED_ANSWER = 4, 58*ee791febSAntonio Huete Jimenez LDNS_EDE_DNSSEC_INDETERMINATE = 5, 59*ee791febSAntonio Huete Jimenez LDNS_EDE_DNSSEC_BOGUS = 6, 60*ee791febSAntonio Huete Jimenez LDNS_EDE_SIGNATURE_EXPIRED = 7, 61*ee791febSAntonio Huete Jimenez LDNS_EDE_SIGNATURE_NOT_YET_VALID = 8, 62*ee791febSAntonio Huete Jimenez LDNS_EDE_DNSKEY_MISSING = 9, 63*ee791febSAntonio Huete Jimenez LDNS_EDE_RRSIGS_MISSING = 10, 64*ee791febSAntonio Huete Jimenez LDNS_EDE_NO_ZONE_KEY_BIT_SET = 11, 65*ee791febSAntonio Huete Jimenez LDNS_EDE_NSEC_MISSING = 12, 66*ee791febSAntonio Huete Jimenez LDNS_EDE_CACHED_ERROR = 13, 67*ee791febSAntonio Huete Jimenez LDNS_EDE_NOT_READY = 14, 68*ee791febSAntonio Huete Jimenez LDNS_EDE_BLOCKED = 15, 69*ee791febSAntonio Huete Jimenez LDNS_EDE_CENSORED = 16, 70*ee791febSAntonio Huete Jimenez LDNS_EDE_FILTERED = 17, 71*ee791febSAntonio Huete Jimenez LDNS_EDE_PROHIBITED = 18, 72*ee791febSAntonio Huete Jimenez LDNS_EDE_STALE_NXDOMAIN_ANSWER = 19, 73*ee791febSAntonio Huete Jimenez LDNS_EDE_NOT_AUTHORITATIVE = 20, 74*ee791febSAntonio Huete Jimenez LDNS_EDE_NOT_SUPPORTED = 21, 75*ee791febSAntonio Huete Jimenez LDNS_EDE_NO_REACHABLE_AUTHORITY = 22, 76*ee791febSAntonio Huete Jimenez LDNS_EDE_NETWORK_ERROR = 23, 77*ee791febSAntonio Huete Jimenez LDNS_EDE_INVALID_DATA = 24, 78*ee791febSAntonio Huete Jimenez LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID = 25, 79*ee791febSAntonio Huete Jimenez LDNS_EDE_TOO_EARLY = 26 80*ee791febSAntonio Huete Jimenez }; 81*ee791febSAntonio Huete Jimenez typedef enum ldns_edns_enum_ede_code ldns_edns_ede_code; 82*ee791febSAntonio Huete Jimenez 83*ee791febSAntonio Huete Jimenez /** 84*ee791febSAntonio Huete Jimenez * The struct that stores an ordered EDNS option. 85*ee791febSAntonio Huete Jimenez * An EDNS option is structed as follows: 86*ee791febSAntonio Huete Jimenez +0 (MSB) +1 (LSB) 87*ee791febSAntonio Huete Jimenez +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 88*ee791febSAntonio Huete Jimenez 0: | OPTION-CODE | 89*ee791febSAntonio Huete Jimenez +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 90*ee791febSAntonio Huete Jimenez 2: | OPTION-LENGTH | 91*ee791febSAntonio Huete Jimenez +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 92*ee791febSAntonio Huete Jimenez 4: | | 93*ee791febSAntonio Huete Jimenez / OPTION-DATA / 94*ee791febSAntonio Huete Jimenez / / 95*ee791febSAntonio Huete Jimenez +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ 96*ee791febSAntonio Huete Jimenez */ 97*ee791febSAntonio Huete Jimenez struct ldns_struct_edns_option { 98*ee791febSAntonio Huete Jimenez ldns_edns_option_code _code; 99*ee791febSAntonio Huete Jimenez size_t _size; 100*ee791febSAntonio Huete Jimenez void *_data; 101*ee791febSAntonio Huete Jimenez }; 102*ee791febSAntonio Huete Jimenez typedef struct ldns_struct_edns_option ldns_edns_option; 103*ee791febSAntonio Huete Jimenez 104*ee791febSAntonio Huete Jimenez 105*ee791febSAntonio Huete Jimenez /* 106*ee791febSAntonio Huete Jimenez * Array structure to store multiple EDNS options 107*ee791febSAntonio Huete Jimenez */ 108*ee791febSAntonio Huete Jimenez struct ldns_struct_edns_option_list 109*ee791febSAntonio Huete Jimenez { 110*ee791febSAntonio Huete Jimenez size_t _option_count; /* the number of EDNS options in the list */ 111*ee791febSAntonio Huete Jimenez size_t _option_capacity; /* the amount of options that fit into the list */ 112*ee791febSAntonio Huete Jimenez size_t _options_size; /* the total size of the options serialized */ 113*ee791febSAntonio Huete Jimenez ldns_edns_option **_options; 114*ee791febSAntonio Huete Jimenez }; 115*ee791febSAntonio Huete Jimenez typedef struct ldns_struct_edns_option_list ldns_edns_option_list; 116*ee791febSAntonio Huete Jimenez 117*ee791febSAntonio Huete Jimenez /* 118*ee791febSAntonio Huete Jimenez * Access functions 119*ee791febSAntonio Huete Jimenez * do this as functions to get type checking 120*ee791febSAntonio Huete Jimenez */ 121*ee791febSAntonio Huete Jimenez 122*ee791febSAntonio Huete Jimenez /** 123*ee791febSAntonio Huete Jimenez * returns the size of the EDNS data. 124*ee791febSAntonio Huete Jimenez * \param[in] *edns the EDNS struct to read from 125*ee791febSAntonio Huete Jimenez * \return uint16_t with the size 126*ee791febSAntonio Huete Jimenez */ 127*ee791febSAntonio Huete Jimenez size_t ldns_edns_get_size(const ldns_edns_option *edns); 128*ee791febSAntonio Huete Jimenez 129*ee791febSAntonio Huete Jimenez /** 130*ee791febSAntonio Huete Jimenez * returns the option code of the EDNS data. 131*ee791febSAntonio Huete Jimenez * \param[in] *edns the EDNS struct to read from 132*ee791febSAntonio Huete Jimenez * \return uint16_t with the size 133*ee791febSAntonio Huete Jimenez */ 134*ee791febSAntonio Huete Jimenez ldns_edns_option_code ldns_edns_get_code(const ldns_edns_option *edns); 135*ee791febSAntonio Huete Jimenez 136*ee791febSAntonio Huete Jimenez /** 137*ee791febSAntonio Huete Jimenez * returns the EDNS option data. 138*ee791febSAntonio Huete Jimenez * \param[in] *edns the EDNS option to read from 139*ee791febSAntonio Huete Jimenez * \return uint8_t* pointer to the EDNS option's data 140*ee791febSAntonio Huete Jimenez */ 141*ee791febSAntonio Huete Jimenez uint8_t *ldns_edns_get_data(const ldns_edns_option *edns); 142*ee791febSAntonio Huete Jimenez 143*ee791febSAntonio Huete Jimenez 144*ee791febSAntonio Huete Jimenez /** 145*ee791febSAntonio Huete Jimenez * serialise the EDNS option into wireformat. 146*ee791febSAntonio Huete Jimenez * \param[in] *edns the EDNS option to read from 147*ee791febSAntonio Huete Jimenez * \return ldns_buffer* the buffer containing the data 148*ee791febSAntonio Huete Jimenez */ 149*ee791febSAntonio Huete Jimenez ldns_buffer *ldns_edns_get_wireformat_buffer(const ldns_edns_option *edns); 150*ee791febSAntonio Huete Jimenez 151*ee791febSAntonio Huete Jimenez /* Constructors and destructors*/ 152*ee791febSAntonio Huete Jimenez 153*ee791febSAntonio Huete Jimenez /** 154*ee791febSAntonio Huete Jimenez * allocates a new EDNS structure and fills it. This function *DOES NOT* copy 155*ee791febSAntonio Huete Jimenez * the contents from the data parameter. 156*ee791febSAntonio Huete Jimenez * \param[in] code the EDNS code 157*ee791febSAntonio Huete Jimenez * \param[in] size size of the buffer 158*ee791febSAntonio Huete Jimenez * \param[in] data pointer to the buffer to be assigned 159*ee791febSAntonio Huete Jimenez * \return the new EDNS structure or NULL on failure 160*ee791febSAntonio Huete Jimenez */ 161*ee791febSAntonio Huete Jimenez ldns_edns_option *ldns_edns_new(ldns_edns_option_code code, size_t size, void *data); 162*ee791febSAntonio Huete Jimenez 163*ee791febSAntonio Huete Jimenez /** 164*ee791febSAntonio Huete Jimenez * allocates a new EDNS structure and fills it. This function *DOES* copy 165*ee791febSAntonio Huete Jimenez * the contents from the data parameter. 166*ee791febSAntonio Huete Jimenez * \param[in] code the EDNS code 167*ee791febSAntonio Huete Jimenez * \param[in] size size of the buffer 168*ee791febSAntonio Huete Jimenez * \param[in] data pointer to the buffer to be assigned 169*ee791febSAntonio Huete Jimenez * \return the new EDNS structure or NULL on failure 170*ee791febSAntonio Huete Jimenez */ 171*ee791febSAntonio Huete Jimenez ldns_edns_option *ldns_edns_new_from_data(ldns_edns_option_code code, size_t size, const void *data); 172*ee791febSAntonio Huete Jimenez 173*ee791febSAntonio Huete Jimenez /** 174*ee791febSAntonio Huete Jimenez * clone an EDNS option 175*ee791febSAntonio Huete Jimenez * \param[in] edns the EDNS option 176*ee791febSAntonio Huete Jimenez * \return the new EDNS structure 177*ee791febSAntonio Huete Jimenez */ 178*ee791febSAntonio Huete Jimenez ldns_edns_option *ldns_edns_clone(ldns_edns_option *edns); 179*ee791febSAntonio Huete Jimenez 180*ee791febSAntonio Huete Jimenez /** 181*ee791febSAntonio Huete Jimenez * free the EDNS option. Use deep_free if the _data member is allocated. 182*ee791febSAntonio Huete Jimenez * \param[in] edns the EDNS option to free 183*ee791febSAntonio Huete Jimenez */ 184*ee791febSAntonio Huete Jimenez void ldns_edns_deep_free(ldns_edns_option *edns); 185*ee791febSAntonio Huete Jimenez void ldns_edns_free(ldns_edns_option *edns); 186*ee791febSAntonio Huete Jimenez 187*ee791febSAntonio Huete Jimenez /** 188*ee791febSAntonio Huete Jimenez * allocates space for a new list of EDNS options 189*ee791febSAntonio Huete Jimenez * \return the new EDNS option list or NULL on failure 190*ee791febSAntonio Huete Jimenez */ 191*ee791febSAntonio Huete Jimenez ldns_edns_option_list* ldns_edns_option_list_new(void); 192*ee791febSAntonio Huete Jimenez 193*ee791febSAntonio Huete Jimenez /** 194*ee791febSAntonio Huete Jimenez * clone the EDNS options list and it's contents 195*ee791febSAntonio Huete Jimenez * \param[in] options_list the EDNS options_list to read from 196*ee791febSAntonio Huete Jimenez * \return the new EDNS option list 197*ee791febSAntonio Huete Jimenez */ 198*ee791febSAntonio Huete Jimenez ldns_edns_option_list *ldns_edns_option_list_clone(ldns_edns_option_list *options_list); 199*ee791febSAntonio Huete Jimenez 200*ee791febSAntonio Huete Jimenez /** 201*ee791febSAntonio Huete Jimenez * free the EDNS option list. Use deep_free to free the options options 202*ee791febSAntonio Huete Jimenez * in the list as well. 203*ee791febSAntonio Huete Jimenez * \param[in] options_list the EDNS option to free 204*ee791febSAntonio Huete Jimenez */ 205*ee791febSAntonio Huete Jimenez void ldns_edns_option_list_free(ldns_edns_option_list *options_list); 206*ee791febSAntonio Huete Jimenez void ldns_edns_option_list_deep_free(ldns_edns_option_list *options_list); 207*ee791febSAntonio Huete Jimenez 208*ee791febSAntonio Huete Jimenez /* edns_option_list functions */ 209*ee791febSAntonio Huete Jimenez 210*ee791febSAntonio Huete Jimenez /** 211*ee791febSAntonio Huete Jimenez * returns the number of options in the EDNS options list. 212*ee791febSAntonio Huete Jimenez * \param[in] options_list the EDNS options_list to read from 213*ee791febSAntonio Huete Jimenez * \return the number of EDNS options 214*ee791febSAntonio Huete Jimenez */ 215*ee791febSAntonio Huete Jimenez size_t ldns_edns_option_list_get_count(const ldns_edns_option_list *options_list); 216*ee791febSAntonio Huete Jimenez 217*ee791febSAntonio Huete Jimenez /** 218*ee791febSAntonio Huete Jimenez * returns the EDNS option as the specified index in the list of EDNS options. 219*ee791febSAntonio Huete Jimenez * \param[in] options_list the EDNS options_list to read from 220*ee791febSAntonio Huete Jimenez * \param[in] index the location of the EDNS option to get in the list 221*ee791febSAntonio Huete Jimenez * \return the EDNS option located at the index or NULL on failure 222*ee791febSAntonio Huete Jimenez */ 223*ee791febSAntonio Huete Jimenez ldns_edns_option* ldns_edns_option_list_get_option(const ldns_edns_option_list *options_list, 224*ee791febSAntonio Huete Jimenez size_t index); 225*ee791febSAntonio Huete Jimenez 226*ee791febSAntonio Huete Jimenez 227*ee791febSAntonio Huete Jimenez /** 228*ee791febSAntonio Huete Jimenez * returns the total size of all the individual EDNS options in the EDNS list. 229*ee791febSAntonio Huete Jimenez * \param[in] options_list the EDNS options_list to read from 230*ee791febSAntonio Huete Jimenez * \return the total size of the options combined 231*ee791febSAntonio Huete Jimenez */ 232*ee791febSAntonio Huete Jimenez size_t ldns_edns_option_list_get_options_size(const ldns_edns_option_list *options_list); 233*ee791febSAntonio Huete Jimenez 234*ee791febSAntonio Huete Jimenez /** 235*ee791febSAntonio Huete Jimenez * adds an EDNS option to the list of options at the specified index. Also 236*ee791febSAntonio Huete Jimenez * returns the option that was previously at that index. 237*ee791febSAntonio Huete Jimenez * \param[in] options_list the EDNS options_list to add to 238*ee791febSAntonio Huete Jimenez * \param[in] option the EDNS option to add to the list 239*ee791febSAntonio Huete Jimenez * \param[in] index the index in the list where to set the option 240*ee791febSAntonio Huete Jimenez * \return the EDNS option previously located at the index 241*ee791febSAntonio Huete Jimenez */ 242*ee791febSAntonio Huete Jimenez ldns_edns_option *ldns_edns_option_list_set_option(ldns_edns_option_list *options_list, 243*ee791febSAntonio Huete Jimenez ldns_edns_option *option, size_t index); 244*ee791febSAntonio Huete Jimenez 245*ee791febSAntonio Huete Jimenez /** 246*ee791febSAntonio Huete Jimenez * adds an EDNS option at the end of the list of options. 247*ee791febSAntonio Huete Jimenez * \param[in] options_list the EDNS options_list to add to 248*ee791febSAntonio Huete Jimenez * \param[in] option the (non-NULL) EDNS option to add to the list 249*ee791febSAntonio Huete Jimenez * \return true on success and false of failure 250*ee791febSAntonio Huete Jimenez */ 251*ee791febSAntonio Huete Jimenez bool ldns_edns_option_list_push(ldns_edns_option_list *options_list, 252*ee791febSAntonio Huete Jimenez ldns_edns_option *option); 253*ee791febSAntonio Huete Jimenez 254*ee791febSAntonio Huete Jimenez /** 255*ee791febSAntonio Huete Jimenez * removes and returns the EDNS option at the end of the list of options. 256*ee791febSAntonio Huete Jimenez * \param[in] options_list the EDNS options_list to add to 257*ee791febSAntonio Huete Jimenez * \return the EDNS option at the end of the list, or NULL on failure 258*ee791febSAntonio Huete Jimenez */ 259*ee791febSAntonio Huete Jimenez ldns_edns_option* ldns_edns_option_list_pop(ldns_edns_option_list *options_list); 260*ee791febSAntonio Huete Jimenez 261*ee791febSAntonio Huete Jimenez /** 262*ee791febSAntonio Huete Jimenez * serializes all the EDNS options into a single wireformat buffer 263*ee791febSAntonio Huete Jimenez * \param[in] option_list the EDNS options_list to combine into one wireformat 264*ee791febSAntonio Huete Jimenez * \return the filled buffer or NULL on failure 265*ee791febSAntonio Huete Jimenez */ 266*ee791febSAntonio Huete Jimenez ldns_buffer *ldns_edns_option_list2wireformat_buffer(const ldns_edns_option_list *option_list); 267*ee791febSAntonio Huete Jimenez 268*ee791febSAntonio Huete Jimenez #ifdef __cplusplus 269*ee791febSAntonio Huete Jimenez } 270*ee791febSAntonio Huete Jimenez #endif 271*ee791febSAntonio Huete Jimenez 272*ee791febSAntonio Huete Jimenez #endif /* LDNS_EDNS_H */ 273