From: TCY16 Date: Fri, 1 Apr 2022 13:54:01 +0000 (+0200) Subject: add functions to edns lib X-Git-Tag: 1.8.2-rc.1~3^2~30 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b2f7f3636612803fa79b76f983fea29253bb00f;p=thirdparty%2Fldns.git add functions to edns lib --- diff --git a/edns.c b/edns.c index 2f6d8098..099ea232 100644 --- a/edns.c +++ b/edns.c @@ -96,3 +96,149 @@ ldns_edns_free(ldns_edns_option *edns) LDNS_FREE(edns); } } + +ldns_edns_option_list* +ldns_edns_option_list_new() +{ + ldns_edns_option_list *options_list = LDNS_MALLOC(ldns_edns_option_list); + if(!options_list) { + return NULL; + } + + options_list->_option_count = 0; + options_list->_options = NULL; + return options_list; +} + +void +ldns_edns_option_list_free(ldns_edns_option_list *options_list) +{ + if (options_list) { + LDNS_FREE(options_list->_options); + LDNS_FREE(options_list); + } +} + +void +ldns_edns_option_list_deep_free(ldns_edns_option_list *options_list) +{ + size_t i; + + if (options_list) { + for (i=0; i < ldns_edns_option_list_get_count(options_list); i++) { + ldns_edns_free(ldns_edns_option_list_get_option(options_list, i)); + } + ldns_edns_option_list_free(options_list); + } +} + + +size_t +ldns_edns_option_list_get_count(const ldns_edns_option_list *options_list) +{ + if (options_list) { + return options_list->_option_count; + } else { + return 0; + } +} + +void +ldns_edns_option_list_set_count(ldns_edns_option_list *options_list, size_t count) +{ + assert(options_list); // @TODO does this check need to check more? + options_list->_option_count = count; +} + +ldns_edns_option * +ldns_edns_option_list_get_option(const ldns_edns_option_list *options_list, size_t index) +{ + if (index < ldns_edns_option_list_get_count(options_list)) { + return options_list->_options[index]; + } else { + return NULL; + } +} + +ldns_edns_option * +ldns_edns_option_list_set_option(ldns_edns_option_list *options_list, + const ldns_edns_option *option, size_t index) +{ + ldns_edns_option* old; + + assert(options_list != NULL); + + if (index < ldns_edns_option_list_get_count(options_list)) { + return NULL; + } + + if (option == NULL) { + return NULL; + } + + old = ldns_edns_option_list_get_option(options_list, index); + + /* overwrite the pointer of "old" */ + options_list->_options[index] = (ldns_edns_option*)option; + return old; +} + +bool +ldns_edns_option_list_push(ldns_edns_option_list *options_list, + const ldns_edns_option *option) +{ + assert(options_list != NULL); + + if (option != NULL) { + + // @TODO rethink reallocing per push + + options_list->_options = LDNS_XREALLOC(options_list->_options, ldns_edns_option *, + options_list->_option_count + 1); + if (!options_list) { + return false; + } + ldns_edns_option_list_set_option(options_list, option, + options_list->_option_count); + options_list->_option_count += 1; + + return true; + } + return false; +} + +ldns_edns_option * +ldns_edns_option_list_pop(ldns_edns_option_list *options_list) +{ + ldns_edns_option ** new_list; + ldns_edns_option* pop; + size_t count; + + assert(options_list != NULL); + + count = ldns_edns_option_list_get_count(options_list); + + /* get the last option from the list */ + pop = ldns_edns_option_list_get_option(options_list, count-1); + + if (count <= 0){ + return NULL; + } + + // @TODO rethink reallocing per pop + + /* shrink the array */ + new_list = LDNS_XREALLOC(options_list->_options, ldns_edns_option *, count -1); + if (new_list == NULL){ + return NULL; + // @TODO not sure about returning NULL here, as ldns_rr_list_pop_rr + // just skips the failure + } + + options_list->_options = new_list; + + ldns_edns_option_list_set_count(options_list, count - 1); + + return pop; +} + diff --git a/ldns/edns.h b/ldns/edns.h index e7100509..5fbd9f49 100644 --- a/ldns/edns.h +++ b/ldns/edns.h @@ -41,7 +41,40 @@ enum ldns_enum_edns_option typedef enum ldns_enum_edns_option ldns_edns_option_code; /** - * + * Extended DNS Error (RFC 8914) codes + */ +enum ldns_edns_enum_ede_code +{ + LDNS_EDE_OTHER = 0, + LDNS_EDE_UNSUPPORTED_DNSKEY_ALG = 1, + LDNS_EDE_UNSUPPORTED_DS_DIGEST = 2, + LDNS_EDE_STALE_ANSWER = 3, + LDNS_EDE_FORGED_ANSWER = 4, + LDNS_EDE_DNSSEC_INDETERMINATE = 5, + LDNS_EDE_DNSSEC_BOGUS = 6, + LDNS_EDE_SIGNATURE_EXPIRED = 7, + LDNS_EDE_SIGNATURE_NOT_YET_VALID = 8, + LDNS_EDE_DNSKEY_MISSING = 9, + LDNS_EDE_RRSIGS_MISSING = 10, + LDNS_EDE_NO_ZONE_KEY_BIT_SET = 11, + LDNS_EDE_NSEC_MISSING = 12, + LDNS_EDE_CACHED_ERROR = 13, + LDNS_EDE_NOT_READY = 14, + LDNS_EDE_BLOCKED = 15, + LDNS_EDE_CENSORED = 16, + LDNS_EDE_FILTERED = 17, + LDNS_EDE_PROHIBITED = 18, + LDNS_EDE_STALE_NXDOMAIN_ANSWER = 19, + LDNS_EDE_NOT_AUTHORITATIVE = 20, + LDNS_EDE_NOT_SUPPORTED = 21, + LDNS_EDE_NO_REACHABLE_AUTHORITY = 22, + LDNS_EDE_NETWORK_ERROR = 23, + LDNS_EDE_INVALID_DATA = 24 +}; +typedef enum ldns_edns_enum_ede_code ldns_edns_ede_code; + +/** + * The struct that stores an ordered EDNS option. * An EDNS option is structed as follows: +0 (MSB) +1 (LSB) +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ @@ -53,9 +86,6 @@ typedef enum ldns_enum_edns_option ldns_edns_option_code; / OPTION-DATA / / / +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - * - * - * @TODO write this */ struct ldns_struct_edns_option { ldns_edns_option_code _code; @@ -66,16 +96,14 @@ typedef struct ldns_struct_edns_option ldns_edns_option; /* - * - * @TODO write this + * Array structure to store multiple EDNS options */ struct ldns_struct_edns_option_list { size_t _option_count; - size_t _rr_capacity; // ??? - ldns_rr **_options; + ldns_edns_option **_options; }; -typedef struct ldns_struct_edns_option_list edns_option_list; +typedef struct ldns_struct_edns_option_list ldns_edns_option_list; /* * Access functions @@ -104,17 +132,81 @@ ldns_edns_option_code ldns_edns_get_code(const ldns_edns_option *edns); uint8_t *ldns_edns_get_data(const ldns_edns_option *edns); +/* Constructors and destructors*/ + /** * allocates a new EDNS structure and fills it. - * This function DOES NOT copy the contents from - * the buffer, unlike ldns_rdf_new_frm_data() - * \param[in] type type of the rdf + * This function DOES NOT copy the contents from the buffer + * \param[in] code the EDNS code * \param[in] size size of the buffer * \param[in] data pointer to the buffer to be copied - * \return the new rdf structure or NULL on failure + * \return the new EDNS structure or NULL on failure */ ldns_edns_option *ldns_edns_new(ldns_edns_option_code code, size_t size, void *data); +void ldns_edns_deep_free(ldns_edns_option *edns); +void ldns_edns_free(ldns_edns_option *edns); + + +/** + * allocates space for a new list of EDNS options + * \return the new EDNS option list or NULL on failure + */ +ldns_edns_option_list* ldns_edns_option_list_new(void); +void ldns_edns_option_list_free(ldns_edns_option_list *options_list); +void ldns_edns_list_deep_free(ldns_edns_option_list *options_list); + +/* edns_option_list functions */ + +/** + * returns the number of options in the EDNS options list. + * \param[in] options_list the EDNS options_list to read from + * \return the number of EDNS options + */ +size_t ldns_edns_option_list_get_count(const ldns_edns_option_list *options_list); + +/** + * sets the number of options in the EDNS options list. + * \param[in] options_list the EDNS options_list with the associated counter + * \param[in] count the new cnumber of EDNS options in the list + */ +void ldns_edns_option_list_set_count(ldns_edns_option_list *options_list, size_t count); + +/** + * returns the EDNS option as the specified index in the list of EDNS options. + * \param[in] options_list the EDNS options_list to read from + * \param[in] index the location of the EDNS option to get in the list + * \return the EDNS option located at the index + */ +ldns_edns_option* ldns_edns_option_list_get_option(const ldns_edns_option_list *options_list, + size_t index); + +/** + * adds an EDNS option to the list of options at the specified index. Also + * returns the option that was previously at that index. + * \param[in] options_list the EDNS options_list to add to + * \param[in] option the EDNS option to add to the list + * \return the EDNS option previously located at the index + */ +ldns_edns_option * ldns_edns_option_list_set_option(ldns_edns_option_list *options_list, + const ldns_edns_option *option, size_t index); + +/** + * adds an EDNS option at the end of the list of options. + * \param[in] options_list the EDNS options_list to add to + * \param[in] option the (non-NULL) EDNS option to add to the list + * \return true on success and false of failure + */ +bool ldns_edns_option_list_push(ldns_edns_option_list *options_list, + const ldns_edns_option *option); + +/** + * removes and returns the EDNS option at the end of the list of options. + * \param[in] options_list the EDNS options_list to add to + * \return the EDNS option at the end of the list, or NULL on failure + */ +ldns_edns_option* ldns_edns_option_list_pop(ldns_edns_option_list *options_list); + #ifdef __cplusplus } #endif