+ - 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.



git-svn-id: file:///svn/unbound/trunk@998 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2008-02-28 12:29:00 +00:00
parent acb8698a3c
commit 2b95664a66
11 changed files with 151 additions and 23 deletions

View file

@ -528,7 +528,7 @@ static long double abs_val (long double value)
return result; return result;
} }
static long double pow10 (int exp) static long double compat_pow10 (int exp)
{ {
long double result = 1; long double result = 1;
@ -541,7 +541,7 @@ static long double pow10 (int exp)
return result; return result;
} }
static long round (long double value) static long compat_round (long double value)
{ {
long intpart; 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 /* We "cheat" by converting the fractional part to integer by
* multiplying by a factor of 10 * 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++; intpart++;
fracpart -= pow10 (max); fracpart -= compat_pow10 (max);
} }
#ifdef DEBUG_SNPRINTF #ifdef DEBUG_SNPRINTF

18
configure vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # 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>. # Report bugs to <unbound-bugs@nlnetlabs.nl>.
# #
@ -724,8 +724,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='unbound' PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound' PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.0' PACKAGE_VERSION='0.10'
PACKAGE_STRING='unbound 1.0' PACKAGE_STRING='unbound 0.10'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
# Factoring default headers for most tests. # 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. # 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. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF 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]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1424,7 +1424,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.0:";; short | recursive ) echo "Configuration of unbound 0.10:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1549,7 +1549,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
unbound configure 1.0 unbound configure 0.10
generated by GNU Autoconf 2.61 generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 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 This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. 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 generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@ $ $0 $@
@ -25213,7 +25213,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" 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 generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -25262,7 +25262,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\ ac_cs_version="\\
unbound config.status 1.0 unbound config.status 0.10
configured by $0, generated by GNU Autoconf 2.61, configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View file

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57) 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= CFLAGS=
AC_AIX AC_AIX

View 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 27 February 2008: Wouter
- option to use caps for id randomness. - option to use caps for id randomness.
- config file option use-caps-for-id: yes - config file option use-caps-for-id: yes

View file

@ -303,6 +303,8 @@ The result of the DNS resolution and validation is returned as
int* len; /* array with lengths of rdata items */ int* len; /* array with lengths of rdata items */
char* canonname; /* canonical name of result */ char* canonname; /* canonical name of result */
int rcode; /* additional error code in case of no data */ 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 havedata; /* true if there is data */
int nxdomain; /* true if nodata because name does not exist */ int nxdomain; /* true if nodata because name does not exist */
int secure; /* true if result is secure */ int secure; /* true if result is secure */

Binary file not shown.

View file

@ -437,6 +437,9 @@ process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len,
libworker_enter_result(*res, buf, region, libworker_enter_result(*res, buf, region,
q->msg_security); q->msg_security);
} }
(*res)->answer_packet = q->msg;
(*res)->answer_len = q->msg_len;
q->msg = NULL;
ldns_buffer_free(buf); ldns_buffer_free(buf);
regional_destroy(region); 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); lock_basic_unlock(&ctx->cfglock);
if(*cb) return 2; if(*cb) return 2;
ub_resolve_free(*res);
return 1; return 1;
} }
@ -537,6 +541,7 @@ ub_wait(struct ub_ctx* ctx)
r = process_answer_detail(ctx, msg, len, r = process_answer_detail(ctx, msg, len,
&cb, &cbarg, &err, &res); &cb, &cbarg, &err, &res);
lock_basic_unlock(&ctx->rrpipe_lock); lock_basic_unlock(&ctx->rrpipe_lock);
free(msg);
if(r == 0) if(r == 0)
return UB_PIPE; return UB_PIPE;
if(r == 2) if(r == 2)
@ -579,6 +584,9 @@ ub_resolve(struct ub_ctx* ctx, char* name, int rrtype,
lock_basic_unlock(&ctx->cfglock); lock_basic_unlock(&ctx->cfglock);
return r; return r;
} }
q->res->answer_packet = q->msg;
q->res->answer_len = q->msg_len;
q->msg = NULL;
*result = q->res; *result = q->res;
q->res = NULL; q->res = NULL;
@ -672,8 +680,8 @@ ub_cancel(struct ub_ctx* ctx, int async_id)
if(!ctx->dothread) { /* if forked */ if(!ctx->dothread) { /* if forked */
(void)rbtree_delete(&ctx->queries, q->node.key); (void)rbtree_delete(&ctx->queries, q->node.key);
ctx->num_async--; ctx->num_async--;
context_query_delete(q);
msg = context_serialize_cancel(q, &len); msg = context_serialize_cancel(q, &len);
context_query_delete(q);
lock_basic_unlock(&ctx->cfglock); lock_basic_unlock(&ctx->cfglock);
if(!msg) { if(!msg) {
return UB_NOMEM; return UB_NOMEM;
@ -706,6 +714,7 @@ ub_resolve_free(struct ub_result* result)
free(*p); free(*p);
free(result->data); free(result->data);
free(result->len); free(result->len);
free(result->answer_packet);
free(result); free(result);
} }

View 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) { if((r=read(fd, *buf, *len)) == -1) {
log_err("msg read failed: %s", strerror(errno)); log_err("msg read failed: %s", strerror(errno));
(void)fd_set_nonblock(fd); (void)fd_set_nonblock(fd);
free(*buf);
return 0; return 0;
} }
if(r == 0) { /* EOF */ if(r == 0) { /* EOF */
(void)fd_set_nonblock(fd); (void)fd_set_nonblock(fd);
free(*buf);
return 0; return 0;
} }
if(!fd_set_nonblock(fd)) if(!fd_set_nonblock(fd)) {
free(*buf);
return 0; return 0;
}
return 1; return 1;
} }

View file

@ -139,6 +139,13 @@ struct ub_result {
*/ */
int rcode; 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 there is any data, this is true.
* If false, there was no data (nxdomain may be true, rcode can be set). * If false, there was no data (nxdomain may be true, rcode can be set).

View file

@ -216,6 +216,16 @@ ext_check_result(const char* desc, int err, struct ub_result* result)
"wrong.\n", desc); "wrong.\n", desc);
exit(1); 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], r = ub_resolve(inf->ctx, inf->argv[i%inf->argc],
LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &result); LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, &result);
ext_check_result("ub_resolve", r, result); ext_check_result("ub_resolve", r, result);
ub_resolve_free(result);
} }
} }
if(inf->thread_num > NUMTHR/2) { if(inf->thread_num > NUMTHR/2) {

View file

@ -232,6 +232,7 @@ lab_create(char* name)
if(!lab) error_exit("out of memory"); if(!lab) error_exit("out of memory");
lab->label = ldns_dname_new_frm_str(name); lab->label = ldns_dname_new_frm_str(name);
if(!lab->label) error_exit("out of memory"); 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); lab->name = ldns_dname_new_frm_str(name);
if(!lab->name) error_exit("out of memory"); if(!lab->name) error_exit("out of memory");
lab->node.key = lab->label; lab->node.key = lab->label;
@ -264,8 +265,12 @@ find_create_lab(struct harvest_data* data, ldns_rdf* name)
/* create it */ /* create it */
nextlab = (struct labdata*)calloc(1, sizeof(*lab)); nextlab = (struct labdata*)calloc(1, sizeof(*lab));
if(!nextlab) error_exit("out of memory"); 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); nextlab->label = ldns_rdf_clone(next);
if(!nextlab->label) error_exit("out of memory"); 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.key = nextlab->label;
nextlab->node.data = nextlab; nextlab->node.data = nextlab;
nextlab->sublabels = ldns_rbtree_create(lab_cmp); 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); LDNS_RR_CLASS_IN, it->depth);
new_todo_item(data, lab->name, LDNS_RR_TYPE_DS, new_todo_item(data, lab->name, LDNS_RR_TYPE_DS,
LDNS_RR_CLASS_IN, it->depth); 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; 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 static void
process(struct harvest_data* data, struct todo_item* it) 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) { if(hverb) {
printf("process: "); printf("process: ");
ldns_rdf_print(stdout, it->qname); ldns_rdf_print(stdout, it->qname);
@ -377,11 +439,36 @@ process(struct harvest_data* data, struct todo_item* it)
printf("\n"); printf("\n");
} }
/* do lookup */ /* 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 ldns pkt */
/* create recursive todo items */ s = ldns_wire2pkt(&pkt, result->answer_packet, result->answer_len);
/* store results */ 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 */ /** perform main harvesting */
@ -404,6 +491,7 @@ harvest_main(struct harvest_data* data)
} }
data->numtodo--; data->numtodo--;
process(data, it); process(data, it);
exit(1);
} }
} }
@ -417,11 +505,11 @@ int main(int argc, char* argv[])
{ {
struct harvest_data data; struct harvest_data data;
char* nm = argv[0]; char* nm = argv[0];
struct ub_ctx* ctx = ub_ctx_create();
int c; int c;
/* defaults */ /* defaults */
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.ctx = ub_ctx_create();
data.resultdir = strdup("harvested_zones"); data.resultdir = strdup("harvested_zones");
if(!data.resultdir) error_exit("out of memory"); if(!data.resultdir) error_exit("out of memory");
data.maxdepth = 10; data.maxdepth = 10;
@ -451,6 +539,6 @@ int main(int argc, char* argv[])
harvest_main(&data); harvest_main(&data);
/* no cleanup except the context (to close open sockets) */ /* no cleanup except the context (to close open sockets) */
ub_ctx_delete(ctx); ub_ctx_delete(data.ctx);
return 0; return 0;
} }