From fd2983277b65877efabf0ea37f2acdd2b0cae89a Mon Sep 17 00:00:00 2001 From: Willem Toorop Date: Wed, 26 Nov 2014 13:57:59 +0100 Subject: [PATCH] bugfix #584: ldns-update fixes. - Send update to port 53 - bring manpage in sync with the usage text - 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. --- Changelog | 4 +++ ldns/resolver.h | 9 ++++- resolver.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++ update.c | 23 +++++++----- 4 files changed, 121 insertions(+), 9 deletions(-) diff --git a/Changelog b/Changelog index 8bd84d7f..e07d039e 100644 --- a/Changelog +++ b/Changelog @@ -42,6 +42,10 @@ TBD 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 diff --git a/ldns/resolver.h b/ldns/resolver.h index a0f4b13c..228485c0 100644 --- a/ldns/resolver.h +++ b/ldns/resolver.h @@ -686,10 +686,17 @@ ldns_pkt* ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, ldns /** * 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 diff --git a/resolver.c b/resolver.c index 6bf616ed..5dc97065 100644 --- a/resolver.c +++ b/resolver.c @@ -663,6 +663,100 @@ ldns_resolver_new(void) 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) { diff --git a/update.c b/update.c index 96f72ce1..74e9d192 100644 --- a/update.c +++ b/update.c @@ -135,6 +135,7 @@ ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r, ldns_rdf *ipaddr, *fqdn_rdf, *tmp; ldns_rdf **nslist; ldns_pkt *query, *resp; + ldns_resolver *tmp_r; size_t i; /* @@ -201,8 +202,11 @@ ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r, 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]; @@ -212,11 +216,11 @@ ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r, 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; @@ -224,21 +228,24 @@ ldns_update_soa_zone_mname(const char *fqdn, ldns_resolver *r, 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; -- 2.47.3