mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
harvest
git-svn-id: file:///svn/unbound/trunk@996 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
d90c162edf
commit
7a8fa9e3de
3 changed files with 463 additions and 2 deletions
11
Makefile.in
11
Makefile.in
|
|
@ -98,13 +98,16 @@ PERF_SRC=testcode/perf.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||||
PERF_OBJ=$(addprefix $(BUILD),$(PERF_SRC:.c=.o)) $(COMPAT_OBJ)
|
PERF_OBJ=$(addprefix $(BUILD),$(PERF_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
DELAYER_SRC=testcode/delayer.c smallapp/worker_cb.c $(COMMON_SRC)
|
DELAYER_SRC=testcode/delayer.c smallapp/worker_cb.c $(COMMON_SRC)
|
||||||
DELAYER_OBJ=$(addprefix $(BUILD),$(DELAYER_SRC:.c=.o)) $(COMPAT_OBJ)
|
DELAYER_OBJ=$(addprefix $(BUILD),$(DELAYER_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
|
HARVEST_SRC=testcode/harvest.c
|
||||||
|
HARVEST_OBJ=$(addprefix $(BUILD),$(HARVEST_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
LIBUNBOUND_SRC=$(patsubst $(srcdir)/%,%, \
|
LIBUNBOUND_SRC=$(patsubst $(srcdir)/%,%, \
|
||||||
$(wildcard $(srcdir)/libunbound/*.c) $(COMMON_SRC))
|
$(wildcard $(srcdir)/libunbound/*.c) $(COMMON_SRC))
|
||||||
LIBUNBOUND_OBJ=$(addprefix $(BUILD),$(LIBUNBOUND_SRC:.c=.o)) $(COMPAT_OBJ)
|
LIBUNBOUND_OBJ=$(addprefix $(BUILD),$(LIBUNBOUND_SRC:.c=.o)) $(COMPAT_OBJ)
|
||||||
ALL_SRC=$(sort $(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
ALL_SRC=$(sort $(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
||||||
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) $(SIGNIT_SRC) \
|
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) $(SIGNIT_SRC) \
|
||||||
$(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
|
$(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
|
||||||
$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC))
|
$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
|
||||||
|
$(HARVEST_SRC) )
|
||||||
ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.o) \
|
ALL_OBJ=$(addprefix $(BUILD),$(ALL_SRC:.c=.o) \
|
||||||
$(addprefix compat/,$(LIBOBJS))) $(COMPAT_OBJ)
|
$(addprefix compat/,$(LIBOBJS))) $(COMPAT_OBJ)
|
||||||
|
|
||||||
|
|
@ -124,7 +127,7 @@ $(BUILD)%.o: $(srcdir)/%.c
|
||||||
all: $(COMMON_OBJ) unbound unbound-checkconf lib unbound-host
|
all: $(COMMON_OBJ) unbound unbound-checkconf lib unbound-host
|
||||||
|
|
||||||
tests: all unittest testbound lock-verify pktview signit memstats \
|
tests: all unittest testbound lock-verify pktview signit memstats \
|
||||||
asynclook streamtcp perf delayer
|
asynclook streamtcp perf delayer harvest
|
||||||
|
|
||||||
test: tests
|
test: tests
|
||||||
bash testcode/do-tests.sh
|
bash testcode/do-tests.sh
|
||||||
|
|
@ -196,6 +199,10 @@ delayer: $(DELAYER_OBJ) $(ldnslib)
|
||||||
$(INFO) Link $@
|
$(INFO) Link $@
|
||||||
$Q$(LINK) -o $@ $(sort $(DELAYER_OBJ)) $(LIBS)
|
$Q$(LINK) -o $@ $(sort $(DELAYER_OBJ)) $(LIBS)
|
||||||
|
|
||||||
|
harvest: $(HARVEST_OBJ) $(ldnslib) libunbound.la
|
||||||
|
$(INFO) Link $@
|
||||||
|
$Q$(LINK) -o $@ $(sort $(HARVEST_OBJ)) $(LIBS) -L. -L.libs -lunbound
|
||||||
|
|
||||||
#testcode/ldns-testpkts.c: $(ldnsdir)/examples/ldns-testpkts.c \
|
#testcode/ldns-testpkts.c: $(ldnsdir)/examples/ldns-testpkts.c \
|
||||||
# $(ldnsdir)/examples/ldns-testpkts.h
|
# $(ldnsdir)/examples/ldns-testpkts.h
|
||||||
# cp $(ldnsdir)/examples/ldns-testpkts.c testcode/ldns-testpkts.c
|
# cp $(ldnsdir)/examples/ldns-testpkts.c testcode/ldns-testpkts.c
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
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
|
||||||
|
- harvest debug tool
|
||||||
|
|
||||||
26 February 2008: Wouter
|
26 February 2008: Wouter
|
||||||
- delay utility delays TCP as well. If the server that is forwarded
|
- delay utility delays TCP as well. If the server that is forwarded
|
||||||
|
|
|
||||||
453
testcode/harvest.c
Normal file
453
testcode/harvest.c
Normal file
|
|
@ -0,0 +1,453 @@
|
||||||
|
/*
|
||||||
|
* testcode/harvest.c - debug program to get relevant data to a set of queries.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, NLnet Labs. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is open source.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* This program downloads relevant DNS data to a set of queries.
|
||||||
|
* This means that the queries are asked to root, TLD, SLD servers and
|
||||||
|
* the results stored per zone.
|
||||||
|
* The following data is pertinent:
|
||||||
|
*
|
||||||
|
* At each label:
|
||||||
|
* SOA
|
||||||
|
* NS
|
||||||
|
* DNSKEY
|
||||||
|
* DS
|
||||||
|
* For the whole query:
|
||||||
|
* the result.
|
||||||
|
* For NS-records:
|
||||||
|
* their label data
|
||||||
|
* and the A and AAAA records for it.
|
||||||
|
* (as if the name, with A and AAAA query type is in the list,
|
||||||
|
* referred to as recursion depth+1)
|
||||||
|
* Any NSEC, NSEC3, SOA records or additional data found in answers.
|
||||||
|
*
|
||||||
|
* All of this is data that would be encountered during an iterative lookup
|
||||||
|
* for the queries in the list. It is saved to enable a replay of iterative
|
||||||
|
* lookups for performance testing.
|
||||||
|
*
|
||||||
|
* A number of assumptions are made.
|
||||||
|
* 1) configuration is correct.
|
||||||
|
* The parent has the same NS records as the child.
|
||||||
|
* All nameservers carry the same data.
|
||||||
|
* 2) EDNS/nonEDNS responses and other behaviour is ignored.
|
||||||
|
* Only the data is saved.
|
||||||
|
* This creates a snapshot that represents the data as this resolver saw it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "libunbound/unbound.h"
|
||||||
|
struct todo_item;
|
||||||
|
struct labdata;
|
||||||
|
|
||||||
|
/** this represents the data that has been collected
|
||||||
|
* as well as a todo list and some settings */
|
||||||
|
struct harvest_data {
|
||||||
|
/** the unbound context */
|
||||||
|
struct ub_ctx* ctx;
|
||||||
|
|
||||||
|
/** a tree per label; thus this first one is one root entry,
|
||||||
|
* that has a tree of TLD labels. Those have trees of SLD labels. */
|
||||||
|
struct labdata* root;
|
||||||
|
/** the original query list */
|
||||||
|
struct todo_item* orig_list;
|
||||||
|
/** the query list todo */
|
||||||
|
struct todo_item* todo_list;
|
||||||
|
/** last item in todo list */
|
||||||
|
struct todo_item* todo_last;
|
||||||
|
/** number of todo items */
|
||||||
|
int numtodo;
|
||||||
|
|
||||||
|
/** where to store the results */
|
||||||
|
char* resultdir;
|
||||||
|
/** maximum recursion depth */
|
||||||
|
int maxdepth;
|
||||||
|
/** current recursion depth */
|
||||||
|
int curdepth;
|
||||||
|
|
||||||
|
/** max depth of labels */
|
||||||
|
int maxlabels;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Todo item
|
||||||
|
*/
|
||||||
|
struct todo_item {
|
||||||
|
/** the next item */
|
||||||
|
struct todo_item* next;
|
||||||
|
|
||||||
|
/** query as rdf */
|
||||||
|
ldns_rdf* qname;
|
||||||
|
/** the query type */
|
||||||
|
int qtype;
|
||||||
|
/** query class */
|
||||||
|
int qclass;
|
||||||
|
|
||||||
|
/** recursion depth of todo item (orig list is 0) */
|
||||||
|
int depth;
|
||||||
|
/** the label associated with the query */
|
||||||
|
struct labdata* lab;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Every label has a sest of sublabels, that have sets of sublabels ...
|
||||||
|
* Per label is stored also a set of data items, and todo information
|
||||||
|
*/
|
||||||
|
struct labdata {
|
||||||
|
/** node in ldns rbtree */
|
||||||
|
ldns_rbnode_t node;
|
||||||
|
/** the name of this label */
|
||||||
|
ldns_rdf* label;
|
||||||
|
/** full name of point in domain tree */
|
||||||
|
ldns_rdf* name;
|
||||||
|
|
||||||
|
/** parent in label tree (NULL for root) */
|
||||||
|
struct labdata* parent;
|
||||||
|
/** tree of sublabels (if any) */
|
||||||
|
ldns_rbtree_t* sublabels;
|
||||||
|
|
||||||
|
/** list of RRs for this label */
|
||||||
|
ldns_rr_list* rrlist;
|
||||||
|
/** have queries for this label been queued */
|
||||||
|
int done;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** usage information for harvest */
|
||||||
|
static void usage(char* nm)
|
||||||
|
{
|
||||||
|
printf("usage: %s [options]\n", nm);
|
||||||
|
printf("-f fnm query list to read from file\n");
|
||||||
|
printf(" every line has format: qname qclass qtype\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** verbosity for harvest */
|
||||||
|
static int hverb = 1;
|
||||||
|
|
||||||
|
/** exit with error */
|
||||||
|
static void error_exit(char* str)
|
||||||
|
{
|
||||||
|
printf("error: %s\n", str);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** read a query file */
|
||||||
|
static void
|
||||||
|
qlist_read_file(struct harvest_data* data, char* fname)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
char nm[1024], cl[1024], tp[1024];
|
||||||
|
int r;
|
||||||
|
int num = 0;
|
||||||
|
FILE* in = fopen(fname, "r");
|
||||||
|
struct todo_item* t;
|
||||||
|
if(!in) {
|
||||||
|
perror(fname);
|
||||||
|
error_exit("could not open file");
|
||||||
|
}
|
||||||
|
while(fgets(buf, (int)sizeof(buf), in)) {
|
||||||
|
if(buf[0] == 0) continue;
|
||||||
|
if(buf[0] == '\n') continue;
|
||||||
|
/* allow some comments */
|
||||||
|
if(buf[0] == ';') continue;
|
||||||
|
if(buf[0] == '#') continue;
|
||||||
|
nm[0] = 0; cl[0] = 0; tp[0] = 0;
|
||||||
|
r = sscanf(buf, " %1023s %1023s %1023s", nm, cl, tp);
|
||||||
|
if(r == 0) continue;
|
||||||
|
t = (struct todo_item*)calloc(1, sizeof(*t));
|
||||||
|
if(!t) error_exit("out of memory");
|
||||||
|
t->qname = ldns_dname_new_frm_str(nm);
|
||||||
|
if(!t->qname) {
|
||||||
|
printf("parse error: %s\n", nm);
|
||||||
|
error_exit("bad qname");
|
||||||
|
}
|
||||||
|
t->depth = 0;
|
||||||
|
t->qtype = LDNS_RR_TYPE_A;
|
||||||
|
t->qclass = LDNS_RR_CLASS_IN;
|
||||||
|
if(r >= 2) {
|
||||||
|
if(strcmp(cl, "IN") == 0 || strcmp(cl, "CH") == 0)
|
||||||
|
t->qclass = ldns_get_rr_class_by_name(cl);
|
||||||
|
else t->qtype = ldns_get_rr_type_by_name(cl);
|
||||||
|
}
|
||||||
|
if(r >= 3) {
|
||||||
|
if(strcmp(tp, "IN") == 0 || strcmp(tp, "CH") == 0)
|
||||||
|
t->qclass = ldns_get_rr_class_by_name(tp);
|
||||||
|
else t->qtype = ldns_get_rr_type_by_name(tp);
|
||||||
|
}
|
||||||
|
num++;
|
||||||
|
|
||||||
|
t->next = data->orig_list;
|
||||||
|
data->orig_list = t;
|
||||||
|
}
|
||||||
|
printf("read %s: %d queries\n", fname, num);
|
||||||
|
fclose(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** compare two labels */
|
||||||
|
static int
|
||||||
|
lab_cmp(const void *x, const void *y)
|
||||||
|
{
|
||||||
|
return ldns_dname_compare((const ldns_rdf*)x, (const ldns_rdf*)y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** create label entry */
|
||||||
|
static struct labdata*
|
||||||
|
lab_create(char* name)
|
||||||
|
{
|
||||||
|
struct labdata* lab = (struct labdata*)calloc(1, sizeof(*lab));
|
||||||
|
if(!lab) error_exit("out of memory");
|
||||||
|
lab->label = ldns_dname_new_frm_str(name);
|
||||||
|
if(!lab->label) error_exit("out of memory");
|
||||||
|
lab->name = ldns_dname_new_frm_str(name);
|
||||||
|
if(!lab->name) error_exit("out of memory");
|
||||||
|
lab->node.key = lab->label;
|
||||||
|
lab->node.data = lab;
|
||||||
|
lab->sublabels = ldns_rbtree_create(lab_cmp);
|
||||||
|
if(!lab->sublabels) error_exit("out of memory");
|
||||||
|
lab->rrlist = ldns_rr_list_new();
|
||||||
|
if(!lab->rrlist) error_exit("out of memory");
|
||||||
|
|
||||||
|
return lab;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** for this name, lookup the label, create if does not exist */
|
||||||
|
static struct labdata*
|
||||||
|
find_create_lab(struct harvest_data* data, ldns_rdf* name)
|
||||||
|
{
|
||||||
|
struct labdata* lab = data->root;
|
||||||
|
struct labdata* nextlab;
|
||||||
|
ldns_rdf* next;
|
||||||
|
uint8_t numlab = ldns_dname_label_count(name);
|
||||||
|
if(numlab > data->maxlabels)
|
||||||
|
data->maxlabels = numlab;
|
||||||
|
while(numlab--) {
|
||||||
|
next = ldns_dname_label(name, numlab);
|
||||||
|
if(!next) error_exit("ldns_dname_label");
|
||||||
|
|
||||||
|
nextlab = (struct labdata*)
|
||||||
|
ldns_rbtree_search(lab->sublabels, next);
|
||||||
|
if(!nextlab) {
|
||||||
|
/* create it */
|
||||||
|
nextlab = (struct labdata*)calloc(1, sizeof(*lab));
|
||||||
|
if(!nextlab) error_exit("out of memory");
|
||||||
|
nextlab->label = ldns_rdf_clone(next);
|
||||||
|
if(!nextlab->label) error_exit("out of memory");
|
||||||
|
nextlab->node.key = nextlab->label;
|
||||||
|
nextlab->node.data = nextlab;
|
||||||
|
nextlab->sublabels = ldns_rbtree_create(lab_cmp);
|
||||||
|
if(!nextlab->sublabels) error_exit("out of memory");
|
||||||
|
nextlab->parent = lab;
|
||||||
|
nextlab->name = ldns_rdf_clone(next);
|
||||||
|
if(!nextlab->name) error_exit("out of memory");
|
||||||
|
if(ldns_dname_cat(nextlab->name, lab->name)
|
||||||
|
!= LDNS_STATUS_OK) error_exit("outofmem");
|
||||||
|
nextlab->rrlist = ldns_rr_list_new();
|
||||||
|
if(!nextlab->rrlist) error_exit("out of memory");
|
||||||
|
ldns_rbtree_insert(lab->sublabels, &nextlab->node);
|
||||||
|
if(hverb) {
|
||||||
|
printf("new label: ");
|
||||||
|
ldns_rdf_print(stdout, nextlab->name);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lab = nextlab;
|
||||||
|
ldns_rdf_deep_free(next);
|
||||||
|
}
|
||||||
|
return lab;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** for given query, create todo items, and labels if needed */
|
||||||
|
static void
|
||||||
|
new_todo_item(struct harvest_data* data, ldns_rdf* qname, int qtype,
|
||||||
|
int qclass, int depth)
|
||||||
|
{
|
||||||
|
struct labdata* lab = find_create_lab(data, qname);
|
||||||
|
struct todo_item* it;
|
||||||
|
if(!lab) error_exit("out of memory creating new label");
|
||||||
|
it = (struct todo_item*)calloc(1, sizeof(*it));
|
||||||
|
it->qname = ldns_rdf_clone(qname);
|
||||||
|
it->qtype = qtype;
|
||||||
|
it->qclass = qclass;
|
||||||
|
it->depth = depth;
|
||||||
|
it->lab = lab;
|
||||||
|
it->next = NULL;
|
||||||
|
if(data->todo_last)
|
||||||
|
data->todo_last->next = it;
|
||||||
|
else data->todo_list = it;
|
||||||
|
data->todo_last = it;
|
||||||
|
data->numtodo ++;
|
||||||
|
if(hverb) {
|
||||||
|
printf("new todo: ");
|
||||||
|
ldns_rdf_print(stdout, it->qname);
|
||||||
|
if(ldns_rr_descript(it->qtype) &&
|
||||||
|
ldns_rr_descript(it->qtype)->_name)
|
||||||
|
printf(" %s", ldns_rr_descript(it->qtype)->_name);
|
||||||
|
if(ldns_lookup_by_id(ldns_rr_classes, it->qclass) &&
|
||||||
|
ldns_lookup_by_id(ldns_rr_classes, it->qclass)->name)
|
||||||
|
printf(" %s", ldns_lookup_by_id(ldns_rr_classes,
|
||||||
|
it->qclass)->name);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** add infra todo items for this query */
|
||||||
|
static void
|
||||||
|
new_todo_infra(struct harvest_data* data, struct todo_item* it)
|
||||||
|
{
|
||||||
|
struct labdata* lab;
|
||||||
|
for(lab = it->lab; lab; lab = lab->parent) {
|
||||||
|
if(lab->done)
|
||||||
|
return;
|
||||||
|
new_todo_item(data, lab->name, LDNS_RR_TYPE_NS,
|
||||||
|
LDNS_RR_CLASS_IN, it->depth);
|
||||||
|
new_todo_item(data, lab->name, LDNS_RR_TYPE_SOA,
|
||||||
|
LDNS_RR_CLASS_IN, it->depth);
|
||||||
|
new_todo_item(data, lab->name, LDNS_RR_TYPE_DNSKEY,
|
||||||
|
LDNS_RR_CLASS_IN, it->depth);
|
||||||
|
new_todo_item(data, lab->name, LDNS_RR_TYPE_DS,
|
||||||
|
LDNS_RR_CLASS_IN, it->depth);
|
||||||
|
lab->done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** make todo items for initial data */
|
||||||
|
static void
|
||||||
|
make_todo(struct harvest_data* data)
|
||||||
|
{
|
||||||
|
struct todo_item* it;
|
||||||
|
for(it=data->orig_list; it; it = it->next) {
|
||||||
|
/* create todo item for this query itself */
|
||||||
|
new_todo_item(data, it->qname, it->qtype, it->qclass, 0);
|
||||||
|
/* create todo items for infra queries to support it */
|
||||||
|
new_todo_infra(data, data->todo_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** get result and store it */
|
||||||
|
static void
|
||||||
|
process(struct harvest_data* data, struct todo_item* it)
|
||||||
|
{
|
||||||
|
if(hverb) {
|
||||||
|
printf("process: ");
|
||||||
|
ldns_rdf_print(stdout, it->qname);
|
||||||
|
if(ldns_rr_descript(it->qtype) &&
|
||||||
|
ldns_rr_descript(it->qtype)->_name)
|
||||||
|
printf(" %s", ldns_rr_descript(it->qtype)->_name);
|
||||||
|
if(ldns_lookup_by_id(ldns_rr_classes, it->qclass) &&
|
||||||
|
ldns_lookup_by_id(ldns_rr_classes, it->qclass)->name)
|
||||||
|
printf(" %s", ldns_lookup_by_id(ldns_rr_classes,
|
||||||
|
it->qclass)->name);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
/* do lookup */
|
||||||
|
|
||||||
|
|
||||||
|
/* create ldns pkt */
|
||||||
|
/* create recursive todo items */
|
||||||
|
/* store results */
|
||||||
|
}
|
||||||
|
|
||||||
|
/** perform main harvesting */
|
||||||
|
static void
|
||||||
|
harvest_main(struct harvest_data* data)
|
||||||
|
{
|
||||||
|
struct todo_item* it;
|
||||||
|
/* register todo queries for all original queries */
|
||||||
|
make_todo(data);
|
||||||
|
printf("depth 0: todo list %d\n", data->numtodo);
|
||||||
|
/* pick up a todo item and process it */
|
||||||
|
while(data->todo_list) {
|
||||||
|
it = data->todo_list;
|
||||||
|
data->todo_list = it->next;
|
||||||
|
if(!data->todo_list) data->todo_last = NULL;
|
||||||
|
if(it->depth > data->curdepth) {
|
||||||
|
data->curdepth = it->depth;
|
||||||
|
printf("depth %d: todo list %d\n", it->depth,
|
||||||
|
data->numtodo);
|
||||||
|
}
|
||||||
|
data->numtodo--;
|
||||||
|
process(data, it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** getopt global, in case header files fail to declare it. */
|
||||||
|
extern int optind;
|
||||||
|
/** getopt global, in case header files fail to declare it. */
|
||||||
|
extern char* optarg;
|
||||||
|
|
||||||
|
/** main program for harvest */
|
||||||
|
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.resultdir = strdup("harvested_zones");
|
||||||
|
if(!data.resultdir) error_exit("out of memory");
|
||||||
|
data.maxdepth = 10;
|
||||||
|
|
||||||
|
/* parse the options */
|
||||||
|
while( (c=getopt(argc, argv, "hf:")) != -1) {
|
||||||
|
switch(c) {
|
||||||
|
case 'f':
|
||||||
|
qlist_read_file(&data, optarg);
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
case 'h':
|
||||||
|
default:
|
||||||
|
usage(nm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
if(argc != 0)
|
||||||
|
usage(nm);
|
||||||
|
if(data.orig_list == NULL)
|
||||||
|
error_exit("No queries to make, use -f (help with -h).");
|
||||||
|
data.root = lab_create(".");
|
||||||
|
if(!data.root) error_exit("out of memory");
|
||||||
|
|
||||||
|
/* harvest the data */
|
||||||
|
harvest_main(&data);
|
||||||
|
|
||||||
|
/* no cleanup except the context (to close open sockets) */
|
||||||
|
ub_ctx_delete(ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue