Thanks Shussain
* bugfix #575: ldns_pkt_clone() does not copy timestamp field
Thanks Calle Dybedahl
+ * bugfix #584: ldns-update fixes. Send update to port 53, bring manpage
+ in sync with the usage text, and don't alter the ldns_resolver passed
+ to ldns_update_soa_zone_mname(). Created a ldns_resolver_clone()
+ function in the process. Thanks Nicholas Riley.
1.6.17 2014-01-10
* Fix ldns_dnssec_zone_new_frm_fp_l to allow the last parsed line of a
/**
* Create a new resolver structure
- * \return ldns_resolver* pointer to new strcture
+ * \return ldns_resolver* pointer to new structure
*/
ldns_resolver* ldns_resolver_new(void);
+/**
+ * Clone a resolver
+ * \param[in] r the resolver to clone
+ * \return ldns_resolver* pointer to new structure
+ */
+ldns_resolver* ldns_resolver_clone(ldns_resolver *r);
+
/**
* Create a resolver structure from a file like /etc/resolv.conf
* \param[out] r the new resolver
return r;
}
+ldns_resolver *
+ldns_resolver_clone(ldns_resolver *src)
+{
+ ldns_resolver *dst;
+ size_t i;
+
+ assert(src);
+
+ if (!(dst = LDNS_MALLOC(ldns_resolver))) return NULL;
+ (void) memcpy(dst, src, sizeof(ldns_resolver));
+
+ if (dst->_searchlist_count == 0)
+ dst->_searchlist = NULL;
+ else {
+ if (!(dst->_searchlist =
+ LDNS_XMALLOC(ldns_rdf *, dst->_searchlist_count)))
+ goto error;
+ for (i = 0; i < dst->_searchlist_count; i++)
+ if (!(dst->_searchlist[i] =
+ ldns_rdf_clone(src->_searchlist[i]))) {
+ dst->_searchlist_count = i;
+ goto error_searchlist;
+ }
+ }
+ if (dst->_nameserver_count == 0) {
+ dst->_nameservers = NULL;
+ dst->_rtt = NULL;
+ } else {
+ if (!(dst->_nameservers =
+ LDNS_XMALLOC(ldns_rdf *, dst->_nameserver_count)))
+ goto error_searchlist;
+ for (i = 0; i < dst->_nameserver_count; i++)
+ if (!(dst->_nameservers[i] =
+ ldns_rdf_clone(src->_nameservers[i]))) {
+ dst->_nameserver_count = i;
+ goto error_nameservers;
+ }
+ if (!(dst->_rtt =
+ LDNS_XMALLOC(size_t, dst->_nameserver_count)))
+ goto error_nameservers;
+ (void) memcpy(dst->_rtt, src->_rtt,
+ sizeof(size_t) * dst->_nameserver_count);
+ }
+ if (dst->_domain && (!(dst->_domain = ldns_rdf_clone(src->_domain))))
+ goto error_rtt;
+
+ if (dst->_tsig_keyname &&
+ (!(dst->_tsig_keyname = strdup(src->_tsig_keyname))))
+ goto error_domain;
+
+ if (dst->_tsig_keydata &&
+ (!(dst->_tsig_keydata = strdup(src->_tsig_keydata))))
+ goto error_tsig_keyname;
+
+ if (dst->_tsig_algorithm &&
+ (!(dst->_tsig_algorithm = strdup(src->_tsig_algorithm))))
+ goto error_tsig_keydata;
+
+ if (dst->_cur_axfr_pkt &&
+ (!(dst->_cur_axfr_pkt = ldns_pkt_clone(src->_cur_axfr_pkt))))
+ goto error_tsig_algorithm;
+
+ if (dst->_dnssec_anchors &&
+ (!(dst->_dnssec_anchors=ldns_rr_list_clone(src->_dnssec_anchors))))
+ goto error_cur_axfr_pkt;
+
+ return dst;
+
+error_cur_axfr_pkt:
+ ldns_pkt_free(dst->_cur_axfr_pkt);
+error_tsig_algorithm:
+ LDNS_FREE(dst->_tsig_algorithm);
+error_tsig_keydata:
+ LDNS_FREE(dst->_tsig_keydata);
+error_tsig_keyname:
+ LDNS_FREE(dst->_tsig_keyname);
+error_domain:
+ ldns_rdf_deep_free(dst->_domain);
+error_rtt:
+ LDNS_FREE(dst->_rtt);
+error_nameservers:
+ for (i = 0; i < dst->_nameserver_count; i++)
+ ldns_rdf_deep_free(dst->_nameservers[i]);
+ LDNS_FREE(dst->_nameservers);
+error_searchlist:
+ for (i = 0; i < dst->_searchlist_count; i++)
+ ldns_rdf_deep_free(dst->_searchlist[i]);
+ LDNS_FREE(dst->_searchlist);
+error:
+ LDNS_FREE(dst);
+ return NULL;
+}
+
+
ldns_status
ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
{
ldns_rdf *ipaddr, *fqdn_rdf, *tmp;
ldns_rdf **nslist;
ldns_pkt *query, *resp;
+ ldns_resolver *tmp_r;
size_t i;
/*
ipaddr = ldns_rr_rdf(rr, 0);
/* Put the SOA mname IP first in the nameserver list. */
- nslist = ldns_resolver_nameservers(r);
- for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
+ if (!(tmp_r = ldns_resolver_clone(r))) {
+ return LDNS_STATUS_MEM_ERR;
+ }
+ nslist = ldns_resolver_nameservers(tmp_r);
+ for (i = 0; i < ldns_resolver_nameserver_count(tmp_r); i++) {
if (ldns_rdf_compare(ipaddr, nslist[i]) == 0) {
if (i) {
tmp = nslist[0];
break;
}
}
- if (i >= ldns_resolver_nameserver_count(r)) {
+ if (i >= ldns_resolver_nameserver_count(tmp_r)) {
/* SOA mname was not part of the resolver so add it first. */
- (void) ldns_resolver_push_nameserver(r, ipaddr);
- nslist = ldns_resolver_nameservers(r);
- i = ldns_resolver_nameserver_count(r) - 1;
+ (void) ldns_resolver_push_nameserver(tmp_r, ipaddr);
+ nslist = ldns_resolver_nameservers(tmp_r);
+ i = ldns_resolver_nameserver_count(tmp_r) - 1;
tmp = nslist[0];
nslist[0] = nslist[i];
nslist[i] = tmp;
ldns_pkt_free(resp);
/* Make sure to ask the first in the list, i.e SOA mname */
- ldns_resolver_set_random(r, false);
+ ldns_resolver_set_random(tmp_r, false);
/* Step 3 - Redo SOA query, sending to SOA MNAME directly. */
fqdn_rdf = ldns_dname_new_frm_str(fqdn);
query = ldns_pkt_query_new(fqdn_rdf, LDNS_RR_TYPE_SOA, c, LDNS_RD);
if (!query) {
+ ldns_resolver_free(tmp_r);
return LDNS_STATUS_ERR;
}
fqdn_rdf = NULL;
ldns_pkt_set_random_id(query);
- if (ldns_resolver_send_pkt(&resp, r, query) != LDNS_STATUS_OK) {
+ if (ldns_resolver_send_pkt(&resp, tmp_r, query) != LDNS_STATUS_OK) {
ldns_pkt_free(query);
+ ldns_resolver_free(tmp_r);
return LDNS_STATUS_ERR;
}
+ ldns_resolver_free(tmp_r);
ldns_pkt_free(query);
if (!resp) {
return LDNS_STATUS_ERR;