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