From 2042e6d822dbc99a2470d192e8b37b69059ed2cc Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Tue, 12 Jul 2022 15:29:02 +0200 Subject: [PATCH] edns_option_list as part of the packet --- drill/drill.c | 8 ++------ edns.c | 5 +++++ host2str.c | 13 +++++-------- host2wire.c | 17 +++++++++++++++-- ldns/packet.h | 30 +++++++++--------------------- packet.c | 50 +++++++++++--------------------------------------- 6 files changed, 47 insertions(+), 76 deletions(-) diff --git a/drill/drill.c b/drill/drill.c index f70519b7..5940f706 100644 --- a/drill/drill.c +++ b/drill/drill.c @@ -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 f77aa73a..b9d1828b 100644 --- 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++) { diff --git a/host2str.c b/host2str.c index ffb956f1..c29f523b 100644 --- a/host2str.c +++ b/host2str.c @@ -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)); diff --git a/host2wire.c b/host2wire.c index 96fbd6ec..32c9c545 100644 --- a/host2wire.c +++ b/host2wire.c @@ -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) diff --git a/ldns/packet.h b/ldns/packet.h index f383d0dd..4c07a855 100644 --- a/ldns/packet.h +++ b/ldns/packet.h @@ -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 */ diff --git a/packet.c b/packet.c index 71d74cfe..3562b399 100644 --- 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); -- 2.47.3