size_t
ldns_edns_get_size(const ldns_edns_option *edns)
{
- assert(edns != NULL);
- return edns->_size;
+ assert(edns != NULL);
+ return edns->_size;
}
ldns_edns_option_code
ldns_edns_get_code(const ldns_edns_option *edns)
{
- assert(edns != NULL);
- return edns->_code;
+ assert(edns != NULL);
+ return edns->_code;
}
uint8_t *
ldns_edns_get_data(const ldns_edns_option *edns)
{
- assert(edns != NULL);
- return edns->_data;
+ assert(edns != NULL);
+ return edns->_data;
}
-
/* write */
void
ldns_edns_set_size(ldns_edns_option *edns, size_t size)
{
- assert(edns != NULL);
- edns->_size = size;
+ assert(edns != NULL);
+ edns->_size = size;
}
void
ldns_edns_set_code(ldns_edns_option *edns, ldns_edns_option_code code)
{
- assert(edns != NULL);
- edns->_code = code;
+ assert(edns != NULL);
+ edns->_code = code;
}
void
ldns_edns_set_data(ldns_edns_option *edns, void *data)
{
- /* only copy the pointer */
- assert(edns != NULL);
- edns->_data = data;
+ /* only copy the pointer */
+ assert(edns != NULL);
+ edns->_data = data;
}
/* note: data must be allocated memory */
ldns_edns_option *
ldns_edns_new(ldns_edns_option_code code, size_t size, void *data)
{
- ldns_edns_option *edns;
- edns = LDNS_MALLOC(ldns_edns_option);
- if (!edns) {
- return NULL;
- }
- ldns_edns_set_size(edns, size);
- ldns_edns_set_code(edns, code);
- ldns_edns_set_data(edns, data);
- return edns;
+ ldns_edns_option *edns;
+ edns = LDNS_MALLOC(ldns_edns_option);
+ if (!edns) {
+ return NULL;
+ }
+ ldns_edns_set_size(edns, size);
+ ldns_edns_set_code(edns, code);
+ ldns_edns_set_data(edns, data);
+ return edns;
}
void
ldns_edns_deep_free(ldns_edns_option *edns)
{
- if (edns) {
- if (edns->_data) {
- LDNS_FREE(edns->_data);
- }
- LDNS_FREE(edns);
- }
+ if (edns) {
+ if (edns->_data) {
+ LDNS_FREE(edns->_data);
+ }
+ LDNS_FREE(edns);
+ }
}
void
ldns_edns_free(ldns_edns_option *edns)
{
- if (edns) {
- LDNS_FREE(edns);
- }
+ if (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;
+ ldns_edns_option_list *option_list = LDNS_MALLOC(ldns_edns_option_list);
+ if(!option_list) {
+ return NULL;
+ }
+
+ option_list->_option_count = 0;
+ option_list->_options_size = 0;
+ option_list->_options = NULL;
+ return option_list;
}
void
-ldns_edns_option_list_free(ldns_edns_option_list *options_list)
+ldns_edns_option_list_free(ldns_edns_option_list *option_list)
{
- if (options_list) {
- LDNS_FREE(options_list->_options);
- LDNS_FREE(options_list);
- }
+ if (option_list) {
+ LDNS_FREE(option_list->_options);
+ LDNS_FREE(option_list);
+ }
}
void
-ldns_edns_option_list_deep_free(ldns_edns_option_list *options_list)
+ldns_edns_option_list_deep_free(ldns_edns_option_list *option_list)
{
- size_t i;
-
- if (options_list) {
- for (i=0; i < ldns_edns_option_list_get_count(options_list); i++) {
- ldns_edns_deep_free(ldns_edns_option_list_get_option(options_list, i));
- }
- ldns_edns_option_list_free(options_list);
- }
+ size_t i;
+
+ if (option_list) {
+ for (i=0; i < ldns_edns_option_list_get_count(option_list); i++) {
+ ldns_edns_deep_free(ldns_edns_option_list_get_option(option_list, i));
+ }
+ ldns_edns_option_list_free(option_list);
+ }
}
size_t
-ldns_edns_option_list_get_count(const ldns_edns_option_list *options_list)
+ldns_edns_option_list_get_count(const ldns_edns_option_list *option_list)
{
- if (options_list) {
- return options_list->_option_count;
- } else {
- return 0;
- }
+ if (option_list) {
+ return option_list->_option_count;
+ } else {
+ return 0;
+ }
}
void
-ldns_edns_option_list_set_count(ldns_edns_option_list *options_list, size_t count)
+ldns_edns_option_list_set_count(ldns_edns_option_list *option_list, size_t count)
{
- assert(options_list); // @TODO does this check need to check more?
- options_list->_option_count = count;
+ assert(option_list); // @TODO does this check need to check more?
+ option_list->_option_count = count;
}
ldns_edns_option *
-ldns_edns_option_list_get_option(const ldns_edns_option_list *options_list, size_t index)
+ldns_edns_option_list_get_option(const ldns_edns_option_list *option_list, size_t index)
{
- if (index < ldns_edns_option_list_get_count(options_list)) {
- return options_list->_options[index];
- } else {
- return NULL;
- }
+ if (option_list && index < ldns_edns_option_list_get_count(option_list)) {
+ return option_list->_options[index];
+ } else {
+ return NULL;
+ }
}
+size_t
+ldns_edns_option_list_get_options_size(const ldns_edns_option_list *option_list)
+{
+ if (option_list) {
+ return option_list->_options_size;
+ } else {
+ return 0;
+ }
+}
+
+
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_list_set_option(ldns_edns_option_list *option_list,
+ const ldns_edns_option *option, size_t index)
{
- ldns_edns_option* old;
+ ldns_edns_option* old;
+
+ assert(option_list != NULL);
- assert(options_list != NULL);
+ if (index < ldns_edns_option_list_get_count(option_list)) {
+ return NULL;
+ }
- if (index < ldns_edns_option_list_get_count(options_list)) {
- return NULL;
- }
+ if (option == NULL) {
+ return NULL;
+ }
- if (option == NULL) {
- return NULL;
- }
+ old = ldns_edns_option_list_get_option(option_list, index);
- old = ldns_edns_option_list_get_option(options_list, index);
+ /* shrink the total EDNS size if the old EDNS option exists */
+ if (old != NULL) {
+ option_list->_options_size -= (ldns_edns_get_size(old) + 4);
+ }
- /* overwrite the pointer of "old" */
- options_list->_options[index] = (ldns_edns_option*)option;
- return old;
+ option_list->_options_size += (ldns_edns_get_size(option) + 4);
+
+ /* overwrite the pointer of "old" */
+ option_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)
+ldns_edns_option_list_push(ldns_edns_option_list *option_list,
+ const ldns_edns_option *option)
{
- assert(options_list != NULL);
+ assert(option_list != NULL);
- if (option != NULL) {
+ if (option != NULL) {
- // @TODO rethink reallocing per push
+ // @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;
+ option_list->_options = LDNS_XREALLOC(option_list->_options,
+ ldns_edns_option *, option_list->_option_count + 1);
+ if (!option_list) {
+ return false;
+ }
+ ldns_edns_option_list_set_option(option_list, option,
+ option_list->_option_count);
+ option_list->_option_count += 1;
- return true;
- }
- return false;
+ return true;
+ }
+ return false;
}
ldns_edns_option *
-ldns_edns_option_list_pop(ldns_edns_option_list *options_list)
+ldns_edns_option_list_pop(ldns_edns_option_list *option_list)
{
- ldns_edns_option ** new_list;
- ldns_edns_option* pop;
- size_t count;
+ ldns_edns_option ** new_list;
+ ldns_edns_option* pop;
+ size_t count;
+
+ assert(option_list != NULL);
- assert(options_list != NULL);
+ count = ldns_edns_option_list_get_count(option_list);
- count = ldns_edns_option_list_get_count(options_list);
+ if (count == 0){
+ return NULL;
+ }
+ /* get the last option from the list */
+ pop = ldns_edns_option_list_get_option(option_list, count-1);
- if (count == 0){
- return NULL;
- }
- /* get the last option from the list */
- pop = ldns_edns_option_list_get_option(options_list, count-1);
+ // @TODO rethink reallocing per pop
- // @TODO rethink reallocing per pop
+ /* shrink the array */
+ new_list = LDNS_XREALLOC(option_list->_options, ldns_edns_option *, count -1);
+ if (new_list){
+ option_list->_options = new_list;
+ }
- /* shrink the array */
- new_list = LDNS_XREALLOC(options_list->_options, ldns_edns_option *, count -1);
- if (new_list){
- options_list->_options = new_list;
- }
+ /* shrink the total EDNS size if the popped EDNS option exists */
+ if (pop != NULL) {
+ option_list->_options_size -= (ldns_edns_get_size(pop) + 4);
+ }
- ldns_edns_option_list_set_count(options_list, count - 1);
+ ldns_edns_option_list_set_count(option_list, count - 1);
- return pop;
+ return pop;
}
*/
enum ldns_enum_edns_option
{
- LDNS_EDNS_LLQ = 1, /* RFC8764 */
- LDNS_EDNS_UL = 2, /* http://files.dns-sd.org/draft-sekar-dns-ul.txt */
- LDNS_EDNS_NSID = 3, /* RFC5001 */
- /* 4 draft-cheshire-edns0-owner-option */
- LDNS_EDNS_DAU = 5, /* RFC6975 */
- LDNS_EDNS_DHU = 6, /* RFC6975 */
- LDNS_EDNS_N3U = 7, /* RFC6975 */
- LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
- LDNS_EDNS_EXPIRE = 9, /* RFC7314 */
- LDNS_EDNS_COOKIE = 10, /* RFC7873 */
- LDNS_EDNS_KEEPALIVE = 11, /* RFC7828*/
- LDNS_EDNS_PADDING = 12, /* RFC7830 */
- LDNS_EDNS_CHAIN = 13, /* RFC7901 */
- LDNS_EDNS_KEY_TAG = 14, /* RFC8145 */
- LDNS_EDNS_EDE = 15, /* RFC8914 */
- LDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
- LDNS_EDNS_SERVER_TAG = 17 /* draft-bellis-dnsop-edns-tags-01 */
+ LDNS_EDNS_LLQ = 1, /* RFC8764 */
+ LDNS_EDNS_UL = 2, /* http://files.dns-sd.org/draft-sekar-dns-ul.txt */
+ LDNS_EDNS_NSID = 3, /* RFC5001 */
+ /* 4 draft-cheshire-edns0-owner-option */
+ LDNS_EDNS_DAU = 5, /* RFC6975 */
+ LDNS_EDNS_DHU = 6, /* RFC6975 */
+ LDNS_EDNS_N3U = 7, /* RFC6975 */
+ LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
+ LDNS_EDNS_EXPIRE = 9, /* RFC7314 */
+ LDNS_EDNS_COOKIE = 10, /* RFC7873 */
+ LDNS_EDNS_KEEPALIVE = 11, /* RFC7828*/
+ LDNS_EDNS_PADDING = 12, /* RFC7830 */
+ LDNS_EDNS_CHAIN = 13, /* RFC7901 */
+ LDNS_EDNS_KEY_TAG = 14, /* RFC8145 */
+ LDNS_EDNS_EDE = 15, /* RFC8914 */
+ LDNS_EDNS_CLIENT_TAG = 16, /* draft-bellis-dnsop-edns-tags-01 */
+ LDNS_EDNS_SERVER_TAG = 17 /* draft-bellis-dnsop-edns-tags-01 */
};
typedef enum ldns_enum_edns_option ldns_edns_option_code;
*/
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,
- LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID = 25,
- LDNS_EDE_TOO_EARLY = 26
+ 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,
+ LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID = 25,
+ LDNS_EDE_TOO_EARLY = 26
};
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)
- +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- 0: | OPTION-CODE |
- +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- 2: | OPTION-LENGTH |
- +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- 4: | |
- / OPTION-DATA /
- / /
- +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ +0 (MSB) +1 (LSB)
+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ 0: | OPTION-CODE |
+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ 2: | OPTION-LENGTH |
+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ 4: | |
+ / OPTION-DATA /
+ / /
+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
*/
struct ldns_struct_edns_option {
- ldns_edns_option_code _code;
- size_t _size;
- void *_data;
+ ldns_edns_option_code _code;
+ size_t _size;
+ void *_data;
};
typedef struct ldns_struct_edns_option ldns_edns_option;
*/
struct ldns_struct_edns_option_list
{
- size_t _option_count;
- ldns_edns_option **_options;
+ size_t _option_count;
+ size_t _options_size; /* the total size of the options in the list*/
+ ldns_edns_option **_options;
};
typedef struct ldns_struct_edns_option_list ldns_edns_option_list;
*/
uint8_t *ldns_edns_get_data(const ldns_edns_option *edns);
-
/* Constructors and destructors*/
/**
*/
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);
+void ldns_edns_option_list_deep_free(ldns_edns_option_list *options_list);
/* edns_option_list functions */
* 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
+ * \return the EDNS option located at the index or NULL on failure
*/
ldns_edns_option* ldns_edns_option_list_get_option(const ldns_edns_option_list *options_list,
- size_t index);
+ size_t index);
+
+
+/**
+ * returns the total size of all the individual EDNS options in the EDNS list.
+ * \param[in] options_list the EDNS options_list to read from
+ * \return the total size of the options combined
+ */
+size_t ldns_edns_option_list_get_options_size(const ldns_edns_option_list *options_list);
/**
* adds an EDNS option to the list of options at the specified index. Also
* \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);
+ const ldns_edns_option *option, size_t index);
/**
* adds an EDNS option at the end of the list of options.
* \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);
+ const ldns_edns_option *option);
/**
* removes and returns the EDNS option at the end of the list of options.