mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
+ - 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:
parent
acb8698a3c
commit
2b95664a66
11 changed files with 151 additions and 23 deletions
|
|
@ -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
|
||||
|
|
|
|||
18
configure
vendored
18
configure
vendored
|
|
@ -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'`\\"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
BIN
ldns-src.tar.gz
BIN
ldns-src.tar.gz
Binary file not shown.
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue