From: Matthijs Mekking Date: Tue, 18 Feb 2014 13:55:00 +0000 (+0100) Subject: drill ixfr= (by maintaining a serial var in the resolver struct) X-Git-Tag: release-1.7.0-rc1~165 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0c2f94bb1676d59458920560b4b1cee4a60eb1c7;p=thirdparty%2Fldns.git drill ixfr= (by maintaining a serial var in the resolver struct) --- diff --git a/drill/drill.c b/drill/drill.c index 84469b1d..ea360241 100644 --- a/drill/drill.c +++ b/drill/drill.c @@ -19,6 +19,19 @@ /* query debug, 2 hex dumps */ int verbosity; +static int +is_ixfr_with_serial(const char* name, uint32_t *serial) +{ + char* end; + if (strlen(name) > 5 && + strncasecmp(name, "IXFR", 4) == 0 && + name[4] == '=') { + *serial = (uint32_t) strtol((name+5), &end, 10); + return 1; + } + return 0; +} + static void usage(FILE *stream, const char *progname) { @@ -113,8 +126,8 @@ main(int argc, char *argv[]) ldns_buffer *query_buffer = NULL; ldns_rdf *serv_rdf; ldns_rdf *src_rdf = NULL; - ldns_rr_type type; - ldns_rr_class clas; + ldns_rr_type type; + ldns_rr_class clas; #if 0 ldns_pkt_opcode opcode = LDNS_PACKET_QUERY; #endif @@ -130,7 +143,7 @@ main(int argc, char *argv[]) ldns_rr *axfr_rr; ldns_status status; char *type_str; - + uint32_t serial = 0; /* list of keys used in dnssec operations */ ldns_rr_list *key_list = ldns_rr_list_new(); /* what key verify the current answer */ @@ -453,6 +466,10 @@ main(int argc, char *argv[]) if (type != 0) { int_type = 0; continue; + } else if (is_ixfr_with_serial(argv[i], &serial)) { + type = LDNS_RR_TYPE_IXFR; + int_type = 0; + continue; } } /* if it matches a class, it's a class */ @@ -516,7 +533,7 @@ main(int argc, char *argv[]) if (!serv_rdf) { /* try to resolv the name if possible */ status = ldns_resolver_new_frm_file(&cmdline_res, resolv_conf_file); - + if (status != LDNS_STATUS_OK) { error("%s", "@server ip could not be converted"); } @@ -554,6 +571,7 @@ main(int argc, char *argv[]) } } /* set the resolver options */ + ldns_resolver_set_ixfr_serial(res, serial); ldns_resolver_set_port(res, qport); ldns_resolver_set_source(res, src_rdf); if (verbosity >= 5) { @@ -682,7 +700,6 @@ main(int argc, char *argv[]) if (!qname) { error("%s", "making qname"); } - status = ldns_resolver_prepare_query_pkt(&qpkt, res, qname, type, clas, qflags); if(status != LDNS_STATUS_OK) { error("%s", "making query: %s", diff --git a/ldns/resolver.h b/ldns/resolver.h index cbc33143..f8400c51 100644 --- a/ldns/resolver.h +++ b/ldns/resolver.h @@ -128,6 +128,8 @@ struct ldns_struct_resolver uint16_t _axfr_i; /* EDNS0 available buffer size */ uint16_t _edns_udp_size; + /* serial for IXFR */ + uint32_t _serial; /* Optional tsig key for signing queries, outgoing messages are signed if and only if both are set @@ -754,6 +756,20 @@ bool ldns_axfr_complete(const ldns_resolver *resolver); */ ldns_pkt *ldns_axfr_last_pkt(const ldns_resolver *res); +/** + * Get the serial for requesting IXFR. + * \param[in] r the resolver + * \param[in] serial serial + */ +void ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial); + +/** + * Get the serial for requesting IXFR. + * \param[in] res the resolver + * \return uint32_t serial + */ +uint32_t ldns_resolver_get_ixfr_serial(const ldns_resolver *res); + /** * Randomize the nameserver list in the resolver * \param[in] r the resolver diff --git a/resolver.c b/resolver.c index ea5283f6..38042da3 100644 --- a/resolver.c +++ b/resolver.c @@ -638,6 +638,7 @@ ldns_resolver_new(void) ldns_resolver_set_recursive(r, false); ldns_resolver_set_dnsrch(r, true); ldns_resolver_set_source(r, NULL); + ldns_resolver_set_ixfr_serial(r, 0); /* randomize the nameserver to be queried * when there are multiple @@ -1165,16 +1166,74 @@ ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r, ldns_rr_class c, uint16_t flags) { struct timeval now; + ldns_rr* soa = NULL; /* prepare a question pkt from the parameters * and then send this */ if (t == LDNS_RR_TYPE_IXFR) { + soa = ldns_rr_new(q); + ldns_rdf *owner_rdf; + ldns_rdf *mname_rdf; + ldns_rdf *rname_rdf; + ldns_rdf *serial_rdf; + ldns_rdf *refresh_rdf; + ldns_rdf *retry_rdf; + ldns_rdf *expire_rdf; + ldns_rdf *minimum_rdf; + + if (!soa) { + return LDNS_STATUS_ERR; + } + owner_rdf = ldns_rdf_clone(name); + if (!owner_rdf) { + ldns_rr_free(soa); + return LDNS_STATUS_ERR; + } + ldns_rr_set_owner(soa, owner_rdf); + ldns_rr_set_type(soa, LDNS_RR_TYPE_SOA); + ldns_rr_set_class(soa, c); + ldns_rr_set_question(soa, false); + if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) { + ldns_rr_free(soa); + return LDNS_STATUS_ERR; + } else ldns_rr_push_rdf(soa, mname_rdf); + if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) { + ldns_rr_free(soa); + return LDNS_STATUS_ERR; + } else ldns_rr_push_rdf(soa, rname_rdf); + serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, ldns_resolver_get_ixfr_serial(r)); + if (!serial_rdf) { + ldns_rr_free(soa); + return LDNS_STATUS_ERR; + } else ldns_rr_push_rdf(soa, serial_rdf); + refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); + if (!refresh_rdf) { + ldns_rr_free(soa); + return LDNS_STATUS_ERR; + } else ldns_rr_push_rdf(soa, refresh_rdf); + retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); + if (!retry_rdf) { + ldns_rr_free(soa); + return LDNS_STATUS_ERR; + } else ldns_rr_push_rdf(soa, retry_rdf); + expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); + if (!expire_rdf) { + ldns_rr_free(soa); + return LDNS_STATUS_ERR; + } else ldns_rr_push_rdf(soa, expire_rdf); + minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0); + if (!minimum_rdf) { + ldns_rr_free(soa); + return LDNS_STATUS_ERR; + } else ldns_rr_push_rdf(soa, minimum_rdf); + *query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name), - c, flags, NULL); + c, flags, soa); } else { *query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags); } if (!*query_pkt) { + ldns_rr_free(soa); return LDNS_STATUS_ERR; } @@ -1212,7 +1271,6 @@ ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r, return LDNS_STATUS_OK; } - ldns_status ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags) @@ -1411,6 +1469,19 @@ ldns_axfr_last_pkt(const ldns_resolver *res) return res->_cur_axfr_pkt; } +void +ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial) +{ + r->_serial = serial; +} + +uint32_t +ldns_resolver_get_ixfr_serial(const ldns_resolver *res) +{ + return res->_serial; +} + + /* random isn't really that good */ void ldns_resolver_nameservers_randomize(ldns_resolver *r)