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 */
*/
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
* 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
*/
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
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,
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)
{
}
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;
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;
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
*/
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);
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);
}
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);