]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
edns_option_list as part of the packet
authorWillem Toorop <willem@nlnetlabs.nl>
Tue, 12 Jul 2022 13:29:02 +0000 (15:29 +0200)
committerWillem Toorop <willem@nlnetlabs.nl>
Tue, 12 Jul 2022 13:29:02 +0000 (15:29 +0200)
drill/drill.c
edns.c
host2str.c
host2wire.c
ldns/packet.h
packet.c

index f70519b7d58ac3811731601ea3fa9f595219a2fb..5940f7063c8577ec28dbdc61afeb68dae70a40b7 100644 (file)
@@ -460,7 +460,7 @@ main(int argc, char *argv[])
                }
                /* if ^+ then it's an EDNS option */
                if (argv[i][0] == '+') {
-                       if (strstr(argv[i], "nsid")) {
+                       if (strcmp(argv[i]+1, "nsid")) {
                                ldns_edns_option *edns;
                                edns_list = ldns_edns_option_list_new();
 
@@ -902,11 +902,8 @@ main(int argc, char *argv[])
                                        }
 
                                        if (edns_list) {
-                                               /* attach the structed EDNS options for completeness */
+                                               /* attach the structed EDNS options */
                                                ldns_pkt_set_edns_option_list(qpkt, edns_list);
-
-                                               /* write the structured EDNS data to unstructured data */
-                                               ldns_pkt_edns_write_option_list_to_edns_data(qpkt, edns_list);
                                        }
 
                                        status = ldns_resolver_send_pkt(&pkt, res, qpkt);
@@ -1033,7 +1030,6 @@ main(int argc, char *argv[])
        ldns_rr_list_deep_free(key_list);
        ldns_rr_list_deep_free(cmdline_rr_list);
        ldns_rdf_deep_free(trace_start_name);
-       ldns_edns_option_list_deep_free(edns_list);
        xfree(progname);
        xfree(tsig_name);
        xfree(tsig_data);
diff --git a/edns.c b/edns.c
index f77aa73a19eb5980adc0aa900be7e3b4a1eac1c8..b9d1828b3c80e72e0d8765243d1ef5b05efaf060 100644 (file)
--- a/edns.c
+++ b/edns.c
@@ -388,12 +388,17 @@ ldns_edns_option_list2wireformat_buffer(const ldns_edns_option_list *option_list
        ldns_edns_option *edns;
        uint8_t* data = NULL;
 
+       if (!option_list)
+               return NULL;
+
        /* get the number of EDNS options in the list*/
        list_size = ldns_edns_option_list_get_count(option_list);
 
        /* create buffer the size of the total EDNS wireformat options */
        options_size = ldns_edns_option_list_get_options_size(option_list);
        buffer = ldns_buffer_new(options_size);
+       if (!buffer)
+               return NULL;
 
        /* write individual serialized EDNS options to final buffer*/
        for (i = 0; i < list_size; i++) {
index ffb956f17c23894eaa0eec3f7b40f47c2fcd034b..c29f523b20f6884410f580895dca3f047aaff1e7 100644 (file)
@@ -2765,7 +2765,6 @@ ldns_pkt2buffer_str_fmt(ldns_buffer *output,
                        }
 
                }
-
                ldns_buffer_printf(output, "\n");
                /* add some further fields */
                ldns_buffer_printf(output, ";; Query time: %d msec\n",
@@ -2786,17 +2785,15 @@ ldns_pkt2buffer_str_fmt(ldns_buffer *output,
                        ldns_buffer_printf(output, " ; udp: %u\n",
                                           ldns_pkt_edns_udp_size(pkt));
 
-                       if (ldns_pkt_edns_data(pkt)) {
+                       if (pkt->_edns_list)
+                               ldns_edns_option_list2buffer_str(output, pkt->_edns_list);
+
+                       else if (ldns_pkt_edns_data(pkt)) {
                                ldns_edns_option_list* edns_list;
                                /* parse the EDNS data into separate EDNS options
                                 * and add them to the list */
-                               if ((edns_list = ldns_pkt_edns_get_option_list(pkt))) {
+                               if ((edns_list = ldns_pkt_edns_get_option_list((ldns_pkt *)pkt))) {
                                        ldns_edns_option_list2buffer_str(output, edns_list);
-                                       /* TODO: We need to free for now, but maybe we
-                                        * should do this differently eventually
-                                        * use a member in pkt or something...
-                                        */
-                                       ldns_edns_option_list_deep_free(edns_list);
                                } else {
                                        ldns_buffer_printf(output, ";; Data: ");
                                        (void)ldns_rdf2buffer_str(output, ldns_pkt_edns_data(pkt));
index 96fbd6ec54ed75c07d2e26f7dfb24b10ab4d67db..32c9c5454ffc0763a60df451e0c160e563b9d440 100644 (file)
@@ -396,6 +396,9 @@ ldns_pkt2buffer_wire_compress(ldns_buffer *buffer, const ldns_pkt *packet, ldns_
        ldns_rr *edns_rr;
        uint8_t edata[4];
 
+       ldns_buffer *edns_buf = NULL;
+       ldns_rdf    *edns_rdf = NULL;
+
        (void) ldns_hdr2buffer_wire(buffer, packet);
 
        rr_list = ldns_pkt_question(packet);
@@ -440,8 +443,18 @@ ldns_pkt2buffer_wire_compress(ldns_buffer *buffer, const ldns_pkt *packet, ldns_
                ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet));
                ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata));
                /* don't forget to add the edns rdata (if any) */
-               if (packet->_edns_data)
-                       ldns_rr_push_rdf (edns_rr, packet->_edns_data);
+               edns_buf = ldns_edns_option_list2wireformat_buffer(packet->_edns_list);
+               if (edns_buf)
+                       edns_rdf = ldns_rdf_new( LDNS_RDF_TYPE_UNKNOWN
+                                              , ldns_buffer_limit(edns_buf)
+                                              , ldns_buffer_export(edns_buf));
+               ldns_buffer_free(edns_buf);
+               if (edns_rdf) {
+                       ldns_rr_push_rdf(edns_rr, edns_rdf);
+                       ldns_rdf_deep_free(edns_rdf);
+
+               } else if (packet->_edns_data)
+                       ldns_rr_push_rdf(edns_rr, packet->_edns_data);
                (void)ldns_rr2buffer_wire_compress(buffer, edns_rr, LDNS_SECTION_ADDITIONAL, compression_data);
                /* take the edns rdata back out of the rr before we free rr */
                if (packet->_edns_data)
index f383d0ddb3a75dbfec743f6bb041785883344e12..4c07a8558aa670d27a34e685389796eb9b28185b 100644 (file)
@@ -510,6 +510,7 @@ ldns_rr_list *ldns_pkt_rr_list_by_type(const ldns_pkt *p, ldns_rr_type t, ldns_p
  */
 ldns_rr_list *ldns_pkt_rr_list_by_name_and_type(const ldns_pkt *packet, const ldns_rdf *ownername, ldns_rr_type type, ldns_pkt_section sec);
 
+
 /**
  * check to see if an rr exist in the packet
  * \param[in] pkt the packet to examine
@@ -689,19 +690,12 @@ uint8_t ldns_pkt_edns_version(const ldns_pkt *packet);
  */
 uint16_t ldns_pkt_edns_z(const ldns_pkt *packet);
 /**
- * return the packet's arbitrary EDNS data
+ * return the packet's EDNS data
  * \param[in] packet the packet
  * \return the data
  */
 ldns_rdf *ldns_pkt_edns_data(const ldns_pkt *packet);
 
-/**
- * return the packet's structured EDNS data option list
- * \param[in] packet the packet
- * \return the list of EDNS options
- */
-ldns_edns_option_list* ldns_pkt_edns_option_list(const ldns_pkt *packet);
-
 /**
  * return the packet's edns do bit
  * \param[in] packet the packet
@@ -739,21 +733,14 @@ void ldns_pkt_set_edns_unassigned(ldns_pkt *packet, uint16_t value);
 bool ldns_pkt_edns(const ldns_pkt *packet);
 
 /**
- * Returns a list of structured EDNS options
+ * Returns a list of structured EDNS options. The list will be automatically
+ * freed when the packet is freed. The option list can be manipulated and
+ * will be used when converting the packet to wireformat with ldns_pkt2wire.
  *
  * \param[in] packet the packet which contains the EDNS data
  * \return the list of EDNS options
  */
-ldns_edns_option_list* ldns_pkt_edns_get_option_list(const ldns_pkt *packet);
-
-/**
- * Serialize the EDNS options to wireformat and write to the arbitrary EDNS data member
- * \param[in] packet the packet which contains the EDNS data
- * \param[in] edns_list the list of EDNS options
- * \return true if succesful and false if not
- */
-bool ldns_pkt_edns_write_option_list_to_edns_data(ldns_pkt *packet,
-       ldns_edns_option_list* edns_list);
+ldns_edns_option_list* ldns_pkt_edns_get_option_list(ldns_pkt *packet);
 
 /**
  * Set the packet's edns udp size
@@ -780,14 +767,15 @@ void ldns_pkt_set_edns_version(ldns_pkt *packet, uint8_t v);
  */
 void ldns_pkt_set_edns_z(ldns_pkt *packet, uint16_t z);
 /**
- * Set the packet's arbitrary EDNS data
+ * Set the packet's EDNS data
  * \param[in] packet the packet
  * \param[in] data the data
  */
 void ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data);
 
 /**
- * Set the packet's structured EDNS data
+ * Set the packet's structured EDNS data. Once an edns_option_list is set 
+ * (or get), the option list will be used for converting into wireformat. 
  * \param[in] packet the packet
  * \param[in] data the data
  */
index 71d74cfedf017b6c7ec50a6916fe8f98b06199d9..3562b3999662f0441628d18c80cb740ec204d6d5 100644 (file)
--- a/packet.c
+++ b/packet.c
@@ -262,12 +262,6 @@ ldns_pkt_edns_data(const ldns_pkt *packet)
        return packet->_edns_data;
 }
 
-ldns_edns_option_list*
-ldns_pkt_edns_option_list(const ldns_pkt *packet)
-{
-       return packet->_edns_list;
-}
-
 /* return only those rr that share the ownername */
 ldns_rr_list *
 ldns_pkt_rr_list_by_name(const ldns_pkt *packet,
@@ -647,6 +641,8 @@ ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data)
 void
 ldns_pkt_set_edns_option_list(ldns_pkt *packet, ldns_edns_option_list *list)
 {
+       if (packet->_edns_list)
+               ldns_edns_option_list_deep_free(packet->_edns_list);
        packet->_edns_list = list;
 }
 
@@ -762,17 +758,13 @@ ldns_pkt_edns(const ldns_pkt *pkt)
 }
 
 ldns_edns_option_list*
-ldns_pkt_edns_get_option_list(const ldns_pkt *packet)
+ldns_pkt_edns_get_option_list(ldns_pkt *packet)
 {
        size_t pos = 0;
        ldns_edns_option_list* edns_list;
        size_t max;
        const uint8_t* wire;
 
-       if (!ldns_pkt_edns_data(packet)) {
-               return NULL;
-       }
-
        /* return the list if it already exists */
        if (packet->_edns_list != NULL) {
                return packet->_edns_list;
@@ -781,6 +773,9 @@ ldns_pkt_edns_get_option_list(const ldns_pkt *packet)
        /* if the list doesn't exists, we create it by parsing the
         * packet->_edns_data
         */
+       if (!ldns_pkt_edns_data(packet)) {
+               return NULL;
+       }
 
        assert(ldns_pkt_edns_data(packet));
        max = ldns_rdf_size(ldns_pkt_edns_data(packet));
@@ -825,31 +820,8 @@ ldns_pkt_edns_get_option_list(const ldns_pkt *packet)
 
        }
 
-       return edns_list;
-}
-
-bool
-ldns_pkt_edns_write_option_list_to_edns_data(ldns_pkt *packet,
-       ldns_edns_option_list* edns_list)
-{
-       ldns_buffer* buffer;
-       ldns_rdf* edns_rdf;
-
-       /* get the EDNS options in wireformat */
-       buffer = ldns_edns_option_list2wireformat_buffer(edns_list);
-
-       if (buffer == NULL) {
-               return false;
-       }
-
-       /* read the data and create the EDNS RDF */
-       edns_rdf = ldns_rdf_new(LDNS_RDF_TYPE_UNKNOWN, ldns_buffer_limit(buffer),
-               ldns_buffer_export(buffer));
-
-       /* set the new EDNS RDF in the packet */
-       ldns_pkt_set_edns_data(packet, edns_rdf);
-
-       return true;
+       packet->_edns_list = edns_list;
+       return packet->_edns_list;
 }
 
 
@@ -901,7 +873,7 @@ ldns_pkt_new(void)
        ldns_pkt_set_edns_version(packet, 0);
        ldns_pkt_set_edns_z(packet, 0);
        ldns_pkt_set_edns_data(packet, NULL);
-       ldns_pkt_set_edns_option_list(packet, NULL);
+       packet->_edns_list = NULL;
        packet->_edns_present = false;
 
        ldns_pkt_set_tsig(packet, NULL);
@@ -1270,9 +1242,9 @@ ldns_pkt_clone(const ldns_pkt *pkt)
                ldns_pkt_set_edns_data(new_pkt, 
                        ldns_rdf_clone(ldns_pkt_edns_data(pkt)));
        ldns_pkt_set_edns_do(new_pkt, ldns_pkt_edns_do(pkt));
-       if (ldns_pkt_edns_option_list(pkt))
+       if (pkt->_edns_list)
                ldns_pkt_set_edns_option_list(new_pkt,
-                       ldns_edns_option_list_clone(ldns_pkt_edns_get_option_list(pkt)));
+                       ldns_edns_option_list_clone(pkt->_edns_list));
 
        ldns_rr_list_deep_free(new_pkt->_question);
        ldns_rr_list_deep_free(new_pkt->_answer);