From: TCY16 Date: Tue, 12 Apr 2022 11:17:50 +0000 (+0200) Subject: add getters and setters to the new EDNS options list and add serializer function X-Git-Tag: 1.8.2-rc.1~3^2~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f69685dfb83159b688e3d4dddbdae1b9f2650b4c;p=thirdparty%2Fldns.git add getters and setters to the new EDNS options list and add serializer function --- diff --git a/ldns/packet.h b/ldns/packet.h index 5bb0df50..f383d0dd 100644 --- a/ldns/packet.h +++ b/ldns/packet.h @@ -252,12 +252,14 @@ struct ldns_struct_pkt uint8_t _edns_extended_rcode; /** EDNS Version */ uint8_t _edns_version; - /* OPT pseudo-RR presence flag */ - uint8_t _edns_present; + /* OPT pseudo-RR presence flag */ + uint8_t _edns_present; /** Reserved EDNS data bits */ uint16_t _edns_z; /** Arbitrary EDNS rdata */ ldns_rdf *_edns_data; + /** Structed EDNS data */ + ldns_edns_option_list *_edns_list; /** Question section */ ldns_rr_list *_question; /** Answer section */ @@ -687,12 +689,19 @@ uint8_t ldns_pkt_edns_version(const ldns_pkt *packet); */ uint16_t ldns_pkt_edns_z(const ldns_pkt *packet); /** - * return the packet's edns data + * return the packet's arbitrary 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 @@ -733,9 +742,18 @@ bool ldns_pkt_edns(const ldns_pkt *packet); * Returns a list of structured EDNS options * * \param[in] packet the packet which contains the EDNS data - * \return list of ldns_edns_option structs + * \return the list of EDNS options */ -ldns_edns_option_list* ldns_pkt_edns_option_list(const ldns_pkt *packet); +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); /** * Set the packet's edns udp size @@ -762,12 +780,19 @@ 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 edns data + * Set the packet's arbitrary 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 + * \param[in] packet the packet + * \param[in] data the data + */ +void ldns_pkt_set_edns_option_list(ldns_pkt *packet, ldns_edns_option_list *list); + /** * allocates and initializes a ldns_pkt structure. * \return pointer to the new packet diff --git a/packet.c b/packet.c index 9dc32815..b39b0e10 100644 --- a/packet.c +++ b/packet.c @@ -262,6 +262,12 @@ 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, @@ -638,6 +644,13 @@ ldns_pkt_set_edns_data(ldns_pkt *packet, ldns_rdf *data) packet->_edns_data = data; } +void +ldns_pkt_set_edns_option_list(ldns_pkt *packet, ldns_edns_option_list *list) +{ + packet->_edns_list = list; +} + + void ldns_pkt_set_section_count(ldns_pkt *packet, ldns_pkt_section s, uint16_t count) { @@ -749,7 +762,7 @@ ldns_pkt_edns(const ldns_pkt *pkt) } ldns_edns_option_list* -ldns_pkt_edns_option_list(const ldns_pkt *packet) +ldns_pkt_edns_get_option_list(const ldns_pkt *packet) { size_t pos = 0; ldns_edns_option_list* edns_list; @@ -758,12 +771,18 @@ ldns_pkt_edns_option_list(const ldns_pkt *packet) if (!ldns_pkt_edns_data(packet)) return NULL; - + + /* return the list if it already exists */ + if (packet->_edns_list != NULL) { + return packet->_edns_list; + } + + /* if the list doesn't exists, we create it by parsing the _edns_data */ + max = ldns_rdf_size(ldns_pkt_edns_data(packet)); wire = ldns_rdf_data(ldns_pkt_edns_data(packet)); // @TODO do checks so we don't read into un-auth memory (max !< 4) - edns_list = ldns_edns_option_list_new(); if (edns_list == NULL) { return NULL; @@ -805,6 +824,30 @@ ldns_pkt_edns_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; +} + /* Create/destroy/convert functions */ @@ -854,6 +897,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_present = false; ldns_pkt_set_tsig(packet, NULL); @@ -872,6 +916,7 @@ ldns_pkt_free(ldns_pkt *packet) ldns_rr_list_deep_free(packet->_additional); ldns_rr_free(packet->_tsig_rr); ldns_rdf_deep_free(packet->_edns_data); + ldns_edns_option_list_deep_free(packet->_edns_list); ldns_rdf_deep_free(packet->_answerfrom); LDNS_FREE(packet); } @@ -1221,6 +1266,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)) + ldns_pkt_set_edns_option_list(new_pkt, + ldns_edns_option_list_clone(ldns_pkt_edns_get_option_list(pkt))); ldns_rr_list_deep_free(new_pkt->_question); ldns_rr_list_deep_free(new_pkt->_answer);