]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
add functions to edns lib
authorTCY16 <tom@nlnetlabs.nl>
Fri, 1 Apr 2022 13:54:01 +0000 (15:54 +0200)
committerTCY16 <tom@nlnetlabs.nl>
Fri, 1 Apr 2022 13:54:01 +0000 (15:54 +0200)
edns.c
ldns/edns.h

diff --git a/edns.c b/edns.c
index 2f6d809832264728c6d6a0ffb3fe018a63560f61..099ea23244d8968e3bac91f8f4d9d0930559e437 100644 (file)
--- 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;
+}
+
index e7100509b2d5ed05ef642b6ecd2b8b8862becc4c..5fbd9f493d0001a743a99770417c72231da170bf 100644 (file)
@@ -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