]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
+ - fixed memory leaks in libunbound (during cancellation and wait).
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 28 Feb 2008 12:29:00 +0000 (12:29 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 28 Feb 2008 12:29:00 +0000 (12:29 +0000)
+       - libunbound returns the answer packet in full.
+       - snprintf compat update.
+       - harvest performs lookup.
+       - ldns-tarball update with fix for ldns_dname_label.

git-svn-id: file:///svn/unbound/trunk@998 be551aaa-1e26-0410-a405-d3ace91eadb9

compat/snprintf.c
configure
configure.ac
doc/Changelog
doc/libunbound.3
ldns-src.tar.gz
libunbound/libunbound.c
libunbound/libworker.c
libunbound/unbound.h
testcode/asynclook.c
testcode/harvest.c

index 766c119301a70b9e94ca99a1318c71ec6529cd97..72fb2eb94d8758ff40db7764a51eda787b33fdf0 100644 (file)
@@ -528,7 +528,7 @@ static long double abs_val (long double value)
   return result;
 }
 
-static long double pow10 (int exp)
+static long double compat_pow10 (int exp)
 {
   long double result = 1;
 
@@ -541,7 +541,7 @@ static long double pow10 (int exp)
   return result;
 }
 
-static long round (long double value)
+static long compat_round (long double value)
 {
   long intpart;
 
@@ -602,12 +602,12 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
   /* We "cheat" by converting the fractional part to integer by
    * multiplying by a factor of 10
    */
-  fracpart = round ((pow10 (max)) * (ufvalue - intpart));
+  fracpart = compat_round ((compat_pow10 (max)) * (ufvalue - intpart));
 
-  if (fracpart >= pow10 (max))
+  if (fracpart >= compat_pow10 (max))
   {
     intpart++;
-    fracpart -= pow10 (max);
+    fracpart -= compat_pow10 (max);
   }
 
 #ifdef DEBUG_SNPRINTF
index f1bd3c3f6782a4c187d9ce7883c0af0f4e5fa117..703e9d98db07c390421614e464852cc15b4b86e3 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for unbound 1.0.
+# Generated by GNU Autoconf 2.61 for unbound 0.10.
 #
 # Report bugs to <unbound-bugs@nlnetlabs.nl>.
 #
@@ -724,8 +724,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='unbound'
 PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.0'
-PACKAGE_STRING='unbound 1.0'
+PACKAGE_VERSION='0.10'
+PACKAGE_STRING='unbound 0.10'
 PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
 
 # Factoring default headers for most tests.
@@ -1359,7 +1359,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures unbound 1.0 to adapt to many kinds of systems.
+\`configure' configures unbound 0.10 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1424,7 +1424,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of unbound 1.0:";;
+     short | recursive ) echo "Configuration of unbound 0.10:";;
    esac
   cat <<\_ACEOF
 
@@ -1549,7 +1549,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-unbound configure 1.0
+unbound configure 0.10
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1563,7 +1563,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by unbound $as_me 1.0, which was
+It was created by unbound $as_me 0.10, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -25213,7 +25213,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by unbound $as_me 1.0, which was
+This file was extended by unbound $as_me 0.10, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -25262,7 +25262,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-unbound config.status 1.0
+unbound config.status 0.10
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
index 264d8e91e92b8ae3ee7b1d52511777c62259c139..95a7ee4805bd8293dbf12b6048296c443ff581fe 100644 (file)
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.57)
 
-AC_INIT(unbound, 1.0, unbound-bugs@nlnetlabs.nl, unbound)
+AC_INIT(unbound, 0.10, unbound-bugs@nlnetlabs.nl, unbound)
 
 CFLAGS=
 AC_AIX
index 003945675b7451c86e39f8c26b184a4ea30b8fba..2c913de059181afc0127a626e5ecd36f65c85be3 100644 (file)
@@ -1,3 +1,10 @@
+28 February 2008: Wouter
+       - fixed memory leaks in libunbound (during cancellation and wait).
+       - libunbound returns the answer packet in full.
+       - snprintf compat update.
+       - harvest performs lookup.
+       - ldns-tarball update with fix for ldns_dname_label.
+
 27 February 2008: Wouter
        - option to use caps for id randomness.
        - config file option use-caps-for-id: yes
index 81e8de1cadc5b0a7a78688635e8ced6c400aa8bc..96fd854b066fb3c5d3ed8b7235e57cdc529f2e47 100644 (file)
@@ -303,6 +303,8 @@ The result of the DNS resolution and validation is returned as
                int* len;    /* array with lengths of rdata items */
                char* canonname; /* canonical name of result */
                int rcode;   /* additional error code in case of no data */
+               void* answer_packet; /* full network format answer packet */
+               int answer_len; /* length of packet in octets */
                int havedata; /* true if there is data */
                int nxdomain; /* true if nodata because name does not exist */
                int secure;  /* true if result is secure */
index 6eedacbddbcebfe77f1428873565e1acb71b9842..5debe05e5a25d723e9f519867ec6bf78b50aa46c 100644 (file)
Binary files a/ldns-src.tar.gz and b/ldns-src.tar.gz differ
index 0e7d702561f02122e8e6e4846e094fe2dd8e6f5b..2280e4f7df793e5ed9560eb29790a0c5d08da475 100644 (file)
@@ -437,6 +437,9 @@ process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len,
                        libworker_enter_result(*res, buf, region,
                                q->msg_security);
                }
+               (*res)->answer_packet = q->msg;
+               (*res)->answer_len = q->msg_len;
+               q->msg = NULL;
                ldns_buffer_free(buf);
                regional_destroy(region);
        }
@@ -448,6 +451,7 @@ process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len,
        lock_basic_unlock(&ctx->cfglock);
 
        if(*cb) return 2;
+       ub_resolve_free(*res);
        return 1;
 }
 
@@ -537,6 +541,7 @@ ub_wait(struct ub_ctx* ctx)
                        r = process_answer_detail(ctx, msg, len, 
                                &cb, &cbarg, &err, &res);
                        lock_basic_unlock(&ctx->rrpipe_lock);
+                       free(msg);
                        if(r == 0)
                                return UB_PIPE;
                        if(r == 2)
@@ -579,6 +584,9 @@ ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
                lock_basic_unlock(&ctx->cfglock);
                return r;
        }
+       q->res->answer_packet = q->msg;
+       q->res->answer_len = q->msg_len;
+       q->msg = NULL;
        *result = q->res;
        q->res = NULL;
 
@@ -672,8 +680,8 @@ ub_cancel(struct ub_ctx* ctx, int async_id)
        if(!ctx->dothread) { /* if forked */
                (void)rbtree_delete(&ctx->queries, q->node.key);
                ctx->num_async--;
-               context_query_delete(q);
                msg = context_serialize_cancel(q, &len);
+               context_query_delete(q);
                lock_basic_unlock(&ctx->cfglock);
                if(!msg) {
                        return UB_NOMEM;
@@ -706,6 +714,7 @@ ub_resolve_free(struct ub_result* result)
                        free(*p);
        free(result->data);
        free(result->len);
+       free(result->answer_packet);
        free(result);
 }
 
index 446071cff88e7d1416653fc03bec520d3abba1a8..a152b62afa363c604b1d14ba41544745cec4bf7b 100644 (file)
@@ -935,14 +935,18 @@ libworker_read_msg(int fd, uint8_t** buf, uint32_t* len, int nonblock)
        if((r=read(fd, *buf, *len)) == -1) {
                log_err("msg read failed: %s", strerror(errno));
                (void)fd_set_nonblock(fd);
+               free(*buf);
                return 0;
        }
        if(r == 0) { /* EOF */
                (void)fd_set_nonblock(fd);
+               free(*buf);
                return 0;
        }
-       if(!fd_set_nonblock(fd))
+       if(!fd_set_nonblock(fd)) {
+               free(*buf);
                return 0;
+       }
        return 1;
 }
 
index 9ee32b9c05ef2f46278cb66d57c93ee5aada5dab..8e52e47e8f1fbe91787ef651a91e6ee554e6e969 100644 (file)
@@ -139,6 +139,13 @@ struct ub_result {
         */
        int rcode;
 
+       /**
+        * The DNS answer packet. Network formatted. Can contain DNSSEC types.
+        */
+       void* answer_packet;
+       /** length of the answer packet in octets. */
+       int answer_len;
+
        /**
         * If there is any data, this is true.
         * If false, there was no data (nxdomain may be true, rcode can be set).
index 4a5a61960055fc859bd064090dcebe2cf7049597..ae7466eb1505f5313e794d5cd12623e5d501550a 100644 (file)
@@ -216,6 +216,16 @@ ext_check_result(const char* desc, int err, struct ub_result* result)
                                "wrong.\n", desc);
                        exit(1);
                }
+               if(result->answer_packet == NULL) {
+                       printf("%s: error result->answer_packet is NULL.\n", 
+                               desc);
+                       exit(1);
+               }
+               if(result->answer_len != 54) {
+                       printf("%s: error result->answer_len is wrong.\n", 
+                               desc);
+                       exit(1);
+               }
        }
 }
 
@@ -288,6 +298,7 @@ ext_thread(void* arg)
                        r = ub_resolve(inf->ctx, inf->argv[i%inf->argc], 
                                LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &result);
                        ext_check_result("ub_resolve", r, result);
+                       ub_resolve_free(result);
                }
        }
        if(inf->thread_num > NUMTHR/2) {
index 637af47c8bf836a8f2edfb407f6c80f5ba3d287a..c80df6f3495be6321818fc7460c8abc038f8f278 100644 (file)
@@ -232,6 +232,7 @@ lab_create(char* name)
        if(!lab) error_exit("out of memory");
        lab->label = ldns_dname_new_frm_str(name);
        if(!lab->label) error_exit("out of memory");
+       printf("labcount %d\n", ldns_dname_label_count(lab->label));
        lab->name = ldns_dname_new_frm_str(name);
        if(!lab->name) error_exit("out of memory");
        lab->node.key = lab->label;
@@ -264,8 +265,12 @@ find_create_lab(struct harvest_data* data, ldns_rdf* name)
                        /* create it */
                        nextlab = (struct labdata*)calloc(1, sizeof(*lab));
                        if(!nextlab) error_exit("out of memory");
+                       printf("nextcount %d len %d\n", 
+                               ldns_dname_label_count(next),
+                               ldns_rdf_size(next));
                        nextlab->label = ldns_rdf_clone(next);
                        if(!nextlab->label) error_exit("out of memory");
+                       printf("labcount %d\n", ldns_dname_label_count(nextlab->label));
                        nextlab->node.key = nextlab->label;
                        nextlab->node.data = nextlab;
                        nextlab->sublabels = ldns_rbtree_create(lab_cmp);
@@ -342,6 +347,10 @@ new_todo_infra(struct harvest_data* data, struct todo_item* it)
                        LDNS_RR_CLASS_IN, it->depth);
                new_todo_item(data, lab->name, LDNS_RR_TYPE_DS, 
                        LDNS_RR_CLASS_IN, it->depth);
+               new_todo_item(data, lab->name, LDNS_RR_TYPE_A, 
+                       LDNS_RR_CLASS_IN, it->depth);
+               new_todo_item(data, lab->name, LDNS_RR_TYPE_AAAA, 
+                       LDNS_RR_CLASS_IN, it->depth);
                lab->done = 1;
        }
 }
@@ -359,10 +368,63 @@ make_todo(struct harvest_data* data)
        }
 }
 
-/** get result and store it */
+/** store RR and make new work items for it if needed */
+static void
+process_rr(struct harvest_data* data, ldns_rr* rr, int depth)
+{
+       /* must free or store rr */
+       struct labdata* lab = find_create_lab(data, ldns_rr_owner(rr));
+       if(!lab) error_exit("cannot find/create label");
+       /* generate extra queries */
+       if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) {
+               new_todo_item(data, ldns_rr_ns_nsdname(rr), LDNS_RR_TYPE_A, 
+                       LDNS_RR_CLASS_IN, depth+1);
+               new_todo_item(data, ldns_rr_ns_nsdname(rr), LDNS_RR_TYPE_AAAA, 
+                       LDNS_RR_CLASS_IN, depth+1);
+       } else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_MX) {
+               new_todo_item(data, ldns_rr_mx_exchange(rr), LDNS_RR_TYPE_A, 
+                       LDNS_RR_CLASS_IN, depth+1);
+               new_todo_item(data, ldns_rr_mx_exchange(rr), LDNS_RR_TYPE_AAAA, 
+                       LDNS_RR_CLASS_IN, depth+1);
+       } else if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
+               new_todo_item(data, ldns_rr_rdf(rr, 0), LDNS_RR_TYPE_A, 
+                       LDNS_RR_CLASS_IN, depth+1);
+               new_todo_item(data, ldns_rr_rdf(rr, 0), LDNS_RR_TYPE_AAAA, 
+                       LDNS_RR_CLASS_IN, depth+1);
+       }
+       /* store it */
+       if(!ldns_rr_list_contains_rr(lab->rrlist, rr)) {
+               if(hverb) printf("store RR\n");
+               if(!ldns_rr_list_push_rr(lab->rrlist, rr))
+                       error_exit("outofmem ldns_rr_list_push_rr");
+       } else {
+               if(hverb) printf("duplicate RR\n");
+               ldns_rr_free(rr);
+       }
+}
+
+/** store RRs and make new work items if needed */
+static void
+process_pkt(struct harvest_data* data, ldns_pkt* pkt, int depth)
+{
+       size_t i;
+       ldns_rr_list* list;
+       list = ldns_pkt_get_section_clone(pkt, LDNS_SECTION_ANY_NOQUESTION);
+       if(!list) error_exit("outofmemory");
+       for(i=0; i<ldns_rr_list_rr_count(list); i++) {
+               process_rr(data, ldns_rr_list_rr(list, i), depth);
+       }
+       ldns_rr_list_free(list);
+}
+
 static void
 process(struct harvest_data* data, struct todo_item* it)
 {
+       int r;
+       char* nm;
+       struct ub_result* result = NULL;
+       ldns_pkt* pkt = NULL;
+       ldns_status s;
        if(hverb) {
                printf("process: ");
                ldns_rdf_print(stdout, it->qname);
@@ -377,11 +439,36 @@ process(struct harvest_data* data, struct todo_item* it)
                printf("\n");
        }
        /* do lookup */
-
+       nm = ldns_rdf2str(it->qname);
+       if(!nm) error_exit("ldns_rdf2str");
+       r = ub_resolve(data->ctx, nm, it->qtype, it->qclass, &result);
+       if(r != 0) {
+               printf("ub_resolve(%s, %d, %d): %s\n", nm, it->qtype, 
+                       it->qclass, ub_strerror(r));
+               free(nm);
+               return;
+       }
+       /* even if result is a negative, try to store resulting SOA/NSEC */
 
        /* create ldns pkt */
-       /* create recursive todo items */
-       /* store results */
+       s = ldns_wire2pkt(&pkt, result->answer_packet, result->answer_len);
+       if(s != LDNS_STATUS_OK) {
+               printf("ldns_wire2pkt failed! %s %d %d %s", nm, 
+                       it->qtype, it->qclass, ldns_get_errorstr_by_id(s));
+               free(nm);
+               return;
+       }
+       if(hverb >= 2) {
+               printf("answer: ");
+               ldns_pkt_print(stdout, pkt);
+               printf("\n");
+       }
+       /* process results */
+       process_pkt(data, pkt, it->depth);
+
+       ldns_pkt_free(pkt);
+       free(nm);
+       ub_resolve_free(result);
 }
 
 /** perform main harvesting */
@@ -404,6 +491,7 @@ harvest_main(struct harvest_data* data)
                }
                data->numtodo--;
                process(data, it);
+               exit(1);
        }
 }
 
@@ -417,11 +505,11 @@ int main(int argc, char* argv[])
 {
        struct harvest_data data;
        char* nm = argv[0];
-       struct ub_ctx* ctx = ub_ctx_create();
        int c;
 
        /* defaults */
        memset(&data, 0, sizeof(data));
+       data.ctx = ub_ctx_create();
        data.resultdir = strdup("harvested_zones");
        if(!data.resultdir) error_exit("out of memory");
        data.maxdepth = 10;
@@ -451,6 +539,6 @@ int main(int argc, char* argv[])
        harvest_main(&data);
 
        /* no cleanup except the context (to close open sockets) */
-       ub_ctx_delete(ctx);
+       ub_ctx_delete(data.ctx);
        return 0;
 }