]> git.ipfire.org Git - thirdparty/ldns.git/commitdiff
drill ixfr=<serial> (by maintaining a serial var in the resolver struct)
authorMatthijs Mekking <github@pletterpet.nl>
Tue, 18 Feb 2014 13:55:00 +0000 (14:55 +0100)
committerMatthijs Mekking <github@pletterpet.nl>
Tue, 18 Feb 2014 13:55:00 +0000 (14:55 +0100)
drill/drill.c
ldns/resolver.h
resolver.c

index 84469b1db0d40db3c8022df6dd5007f25028bd8c..ea3602412c2e9e74b7451e8b5a9fe08ae6889114 100644 (file)
 /* 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", 
index cbc331433998d18b4b2a07ea508b37cbcfa51169..f8400c51e2dac49d7131145d9ea7483810e2552b 100644 (file)
@@ -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
index ea5283f6193ed682a93fd697319363e5ada874a6..38042da37d75f038aa50298cbc1a4c6cd283a426 100644 (file)
@@ -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)