}
/* 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();
}
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);
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);
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++) {
}
}
-
ldns_buffer_printf(output, "\n");
/* add some further fields */
ldns_buffer_printf(output, ";; Query time: %d msec\n",
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));
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);
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)
*/
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
*/
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
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
*/
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
*/
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,
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;
}
}
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;
/* 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));
}
- 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;
}
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);
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);