mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
lookup delegation from cache and printout.
git-svn-id: file:///svn/unbound/trunk@1266 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
de0f903d37
commit
cfceb6487d
12 changed files with 136 additions and 19 deletions
|
|
@ -48,6 +48,9 @@
|
||||||
#include "util/data/msgreply.h"
|
#include "util/data/msgreply.h"
|
||||||
#include "util/regional.h"
|
#include "util/regional.h"
|
||||||
#include "util/net_help.h"
|
#include "util/net_help.h"
|
||||||
|
#include "util/data/dname.h"
|
||||||
|
#include "iterator/iter_delegpt.h"
|
||||||
|
#include "iterator/iter_utils.h"
|
||||||
|
|
||||||
/** convert to ldns rr */
|
/** convert to ldns rr */
|
||||||
static ldns_rr*
|
static ldns_rr*
|
||||||
|
|
@ -776,3 +779,74 @@ load_cache(SSL* ssl, struct worker* worker)
|
||||||
return 0;
|
return 0;
|
||||||
return read_fixed(ssl, worker->env.scratch_buffer, "EOF");
|
return read_fixed(ssl, worker->env.scratch_buffer, "EOF");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||||
|
size_t nmlen, int ATTR_UNUSED(nmlabs))
|
||||||
|
{
|
||||||
|
/* deep links into the iterator module */
|
||||||
|
struct delegpt* dp;
|
||||||
|
struct dns_msg* msg;
|
||||||
|
struct regional* region = worker->scratchpad;
|
||||||
|
char b[260];
|
||||||
|
struct query_info qinfo;
|
||||||
|
size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
|
||||||
|
regional_free_all(region);
|
||||||
|
qinfo.qname = nm;
|
||||||
|
qinfo.qname_len = nmlen;
|
||||||
|
qinfo.qtype = LDNS_RR_TYPE_A;
|
||||||
|
qinfo.qclass = LDNS_RR_CLASS_IN;
|
||||||
|
|
||||||
|
dname_str(nm, b);
|
||||||
|
if(!ssl_printf(ssl, "The following name servers are used for lookup "
|
||||||
|
"of %s\n", b))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
dp = dns_cache_find_delegation(&worker->env, nm, nmlen,
|
||||||
|
qinfo.qtype, qinfo.qclass, region, &msg,
|
||||||
|
*worker->env.now);
|
||||||
|
if(!dp) {
|
||||||
|
return ssl_printf(ssl, "no delegation from "
|
||||||
|
"cache; goes to configured roots\n");
|
||||||
|
}
|
||||||
|
/* print the dp */
|
||||||
|
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||||
|
struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
|
||||||
|
struct packed_rrset_data* d =
|
||||||
|
(struct packed_rrset_data*)k->entry.data;
|
||||||
|
if(!dump_rrset(ssl, k, d, 0))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
delegpt_count_ns(dp, &n_ns, &n_miss);
|
||||||
|
delegpt_count_addr(dp, &n_addr, &n_res, &n_avail);
|
||||||
|
/* since dp has not been used by iterator, all are available*/
|
||||||
|
if(!ssl_printf(ssl, "Delegation with %d names, of which %d "
|
||||||
|
"have no addresses in cache.\n"
|
||||||
|
"It provides %d IP addresses.\n",
|
||||||
|
(int)n_ns, (int)n_miss, (int)n_addr))
|
||||||
|
return 0;
|
||||||
|
/* go up? */
|
||||||
|
if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) {
|
||||||
|
if(!ssl_printf(ssl, "cache delegation was "
|
||||||
|
"useless (no IP addresses)\n"))
|
||||||
|
return 0;
|
||||||
|
if(dname_is_root(nm)) {
|
||||||
|
/* goes to root config */
|
||||||
|
return ssl_printf(ssl, "no delegation from "
|
||||||
|
"cache; goes to configured roots\n");
|
||||||
|
} else {
|
||||||
|
/* useless, goes up */
|
||||||
|
nm = dp->name;
|
||||||
|
nmlen = dp->namelen;
|
||||||
|
dname_remove_label(&nm, &nmlen);
|
||||||
|
dname_str(nm, b);
|
||||||
|
if(!ssl_printf(ssl, "going up, lookup %s\n", b))
|
||||||
|
return 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -91,4 +91,17 @@ int dump_cache(SSL* ssl, struct worker* worker);
|
||||||
*/
|
*/
|
||||||
int load_cache(SSL* ssl, struct worker* worker);
|
int load_cache(SSL* ssl, struct worker* worker);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the delegation used to lookup for this name.
|
||||||
|
* @param ssl: to read from
|
||||||
|
* @param worker: worker that is available (buffers, etc) and has
|
||||||
|
* ptrs to the caches.
|
||||||
|
* @param nm: name to lookup
|
||||||
|
* @param nmlen: length of name.
|
||||||
|
* @param nmlabs: labels in name.
|
||||||
|
* @return false on ssl error.
|
||||||
|
*/
|
||||||
|
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||||
|
size_t nmlen, int nmlabs);
|
||||||
|
|
||||||
#endif /* DAEMON_DUMPCACHE_H */
|
#endif /* DAEMON_DUMPCACHE_H */
|
||||||
|
|
|
||||||
|
|
@ -896,6 +896,7 @@ do_zone_add(SSL* ssl, struct worker* worker, char* arg)
|
||||||
return;
|
return;
|
||||||
if(!local_zone_str2type(arg2, &t)) {
|
if(!local_zone_str2type(arg2, &t)) {
|
||||||
ssl_printf(ssl, "error not a zone type. %s\n", arg2);
|
ssl_printf(ssl, "error not a zone type. %s\n", arg2);
|
||||||
|
free(nm);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lock_quick_lock(&worker->daemon->local_zones->lock);
|
lock_quick_lock(&worker->daemon->local_zones->lock);
|
||||||
|
|
@ -905,6 +906,7 @@ do_zone_add(SSL* ssl, struct worker* worker, char* arg)
|
||||||
lock_rw_wrlock(&z->lock);
|
lock_rw_wrlock(&z->lock);
|
||||||
z->type = t; /* update type anyway */
|
z->type = t; /* update type anyway */
|
||||||
lock_rw_unlock(&z->lock);
|
lock_rw_unlock(&z->lock);
|
||||||
|
free(nm);
|
||||||
lock_quick_unlock(&worker->daemon->local_zones->lock);
|
lock_quick_unlock(&worker->daemon->local_zones->lock);
|
||||||
send_ok(ssl);
|
send_ok(ssl);
|
||||||
return;
|
return;
|
||||||
|
|
@ -934,6 +936,7 @@ do_zone_remove(SSL* ssl, struct worker* worker, char* arg)
|
||||||
nmlabs, LDNS_RR_CLASS_IN))) {
|
nmlabs, LDNS_RR_CLASS_IN))) {
|
||||||
/* present in tree */
|
/* present in tree */
|
||||||
local_zones_del_zone(worker->daemon->local_zones, z);
|
local_zones_del_zone(worker->daemon->local_zones, z);
|
||||||
|
free(nm);
|
||||||
}
|
}
|
||||||
lock_quick_unlock(&worker->daemon->local_zones->lock);
|
lock_quick_unlock(&worker->daemon->local_zones->lock);
|
||||||
send_ok(ssl);
|
send_ok(ssl);
|
||||||
|
|
@ -962,9 +965,23 @@ do_data_remove(SSL* ssl, struct worker* worker, char* arg)
|
||||||
return;
|
return;
|
||||||
local_zones_del_data(worker->daemon->local_zones, nm,
|
local_zones_del_data(worker->daemon->local_zones, nm,
|
||||||
nmlen, nmlabs, LDNS_RR_CLASS_IN);
|
nmlen, nmlabs, LDNS_RR_CLASS_IN);
|
||||||
|
free(nm);
|
||||||
send_ok(ssl);
|
send_ok(ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** cache lookup of nameservers */
|
||||||
|
static void
|
||||||
|
do_lookup(SSL* ssl, struct worker* worker, char* arg)
|
||||||
|
{
|
||||||
|
uint8_t* nm;
|
||||||
|
int nmlabs;
|
||||||
|
size_t nmlen;
|
||||||
|
if(!parse_arg_name(ssl, arg, &nm, &nmlen, &nmlabs))
|
||||||
|
return;
|
||||||
|
(void)print_deleg_lookup(ssl, worker, nm, nmlen, nmlabs);
|
||||||
|
free(nm);
|
||||||
|
}
|
||||||
|
|
||||||
/** execute a remote control command */
|
/** execute a remote control command */
|
||||||
static void
|
static void
|
||||||
execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
||||||
|
|
@ -991,6 +1008,8 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
||||||
(void)dump_cache(ssl, rc->worker);
|
(void)dump_cache(ssl, rc->worker);
|
||||||
} else if(strncmp(p, "load_cache", 10) == 0) {
|
} else if(strncmp(p, "load_cache", 10) == 0) {
|
||||||
if(load_cache(ssl, rc->worker)) send_ok(ssl);
|
if(load_cache(ssl, rc->worker)) send_ok(ssl);
|
||||||
|
} else if(strncmp(p, "lookup", 6) == 0) {
|
||||||
|
do_lookup(ssl, rc->worker, skipwhite(p+6));
|
||||||
} else {
|
} else {
|
||||||
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
|
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,8 @@ flush_type <name> <RR type>
|
||||||
flush_zone <name>
|
flush_zone <name>
|
||||||
removes name and everything below that name from the cache.
|
removes name and everything below that name from the cache.
|
||||||
has to search through the cache item by item, so this is slow.
|
has to search through the cache item by item, so this is slow.
|
||||||
delegation <name>
|
lookup <name>
|
||||||
see what servers would be queried for the given name.
|
see what servers would be queried for a lookup of the given name.
|
||||||
info <name>
|
|
||||||
see data about the name. Slow, searches the cache item by item.
|
|
||||||
local_zone_remove <name of local-zone entry>
|
local_zone_remove <name of local-zone entry>
|
||||||
the local-zone entry is removed.
|
the local-zone entry is removed.
|
||||||
All data from the local zone is also deleted.
|
All data from the local zone is also deleted.
|
||||||
|
|
|
||||||
2
doc/plan
2
doc/plan
|
|
@ -54,7 +54,7 @@ like dnswall does. Allow certain subdomains to do it, config options.
|
||||||
addup stats over threads.
|
addup stats over threads.
|
||||||
not stats on SIGUSR1. perhaps also see which slow auth servers cause >1sec values.
|
not stats on SIGUSR1. perhaps also see which slow auth servers cause >1sec values.
|
||||||
+ remote control to add/remove localinfo, redirects.
|
+ remote control to add/remove localinfo, redirects.
|
||||||
* remote control to load/store cache contents
|
+ remote control to load/store cache contents
|
||||||
+ remote control to start, stop, reload.
|
+ remote control to start, stop, reload.
|
||||||
* remote control to flush names or domains (all under a name) from the
|
* remote control to flush names or domains (all under a name) from the
|
||||||
cache. Include NSes. And the A, AAAA for its NSes.
|
cache. Include NSes. And the A, AAAA for its NSes.
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,10 @@ redirect it to a file to store the cache in a file.
|
||||||
The contents of the cache is loaded from stdin. Uses the same format as
|
The contents of the cache is loaded from stdin. Uses the same format as
|
||||||
dump_cache uses. Loading the cache with old, or wrong data can result
|
dump_cache uses. Loading the cache with old, or wrong data can result
|
||||||
in old or wrong data returned to clients.
|
in old or wrong data returned to clients.
|
||||||
|
.TP
|
||||||
|
.B lookup \fIname
|
||||||
|
Print to stdout the name servers that would be used to look up the
|
||||||
|
name specified.
|
||||||
.SH "EXIT CODE"
|
.SH "EXIT CODE"
|
||||||
The unbound-control program exits with status code 1 on error, 0 on success.
|
The unbound-control program exits with status code 1 on error, 0 on success.
|
||||||
.SH "SET UP"
|
.SH "SET UP"
|
||||||
|
|
|
||||||
|
|
@ -157,8 +157,7 @@ delegpt_add_addr(struct delegpt* dp, struct regional* region,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** count NS and number missing */
|
void
|
||||||
static void
|
|
||||||
delegpt_count_ns(struct delegpt* dp, size_t* numns, size_t* missing)
|
delegpt_count_ns(struct delegpt* dp, size_t* numns, size_t* missing)
|
||||||
{
|
{
|
||||||
struct delegpt_ns* ns;
|
struct delegpt_ns* ns;
|
||||||
|
|
@ -171,8 +170,7 @@ delegpt_count_ns(struct delegpt* dp, size_t* numns, size_t* missing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** count addresses, and number in result and available lists */
|
void
|
||||||
static void
|
|
||||||
delegpt_count_addr(struct delegpt* dp, size_t* numaddr, size_t* numres,
|
delegpt_count_addr(struct delegpt* dp, size_t* numaddr, size_t* numres,
|
||||||
size_t* numavail)
|
size_t* numavail)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,13 @@ struct delegpt_ns* delegpt_find_ns(struct delegpt* dp, uint8_t* name,
|
||||||
*/
|
*/
|
||||||
void delegpt_log(enum verbosity_value v, struct delegpt* dp);
|
void delegpt_log(enum verbosity_value v, struct delegpt* dp);
|
||||||
|
|
||||||
|
/** count NS and number missing for logging */
|
||||||
|
void delegpt_count_ns(struct delegpt* dp, size_t* numns, size_t* missing);
|
||||||
|
|
||||||
|
/** count addresses, and number in result and available lists, for logging */
|
||||||
|
void delegpt_count_addr(struct delegpt* dp, size_t* numaddr, size_t* numres,
|
||||||
|
size_t* numavail);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add all usable targets to the result list.
|
* Add all usable targets to the result list.
|
||||||
* @param dp: delegation point.
|
* @param dp: delegation point.
|
||||||
|
|
|
||||||
|
|
@ -372,7 +372,8 @@ iter_mark_cycle_targets(struct module_qstate* qstate, struct delegpt* dp)
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
iter_dp_is_useless(struct module_qstate* qstate, struct delegpt* dp)
|
iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||||
|
struct delegpt* dp)
|
||||||
{
|
{
|
||||||
struct delegpt_ns* ns;
|
struct delegpt_ns* ns;
|
||||||
/* check:
|
/* check:
|
||||||
|
|
@ -385,18 +386,17 @@ iter_dp_is_useless(struct module_qstate* qstate, struct delegpt* dp)
|
||||||
* o the query is for one of the nameservers in dp,
|
* o the query is for one of the nameservers in dp,
|
||||||
* and that nameserver is a glue-name for this dp.
|
* and that nameserver is a glue-name for this dp.
|
||||||
*/
|
*/
|
||||||
if(!(qstate->query_flags&BIT_RD))
|
if(!(qflags&BIT_RD))
|
||||||
return 0;
|
return 0;
|
||||||
/* either available or unused targets */
|
/* either available or unused targets */
|
||||||
if(dp->usable_list || dp->result_list)
|
if(dp->usable_list || dp->result_list)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* see if query is for one of the nameservers, which is glue */
|
/* see if query is for one of the nameservers, which is glue */
|
||||||
if( (qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
|
if( (qinfo->qtype == LDNS_RR_TYPE_A ||
|
||||||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) &&
|
qinfo->qtype == LDNS_RR_TYPE_AAAA) &&
|
||||||
dname_subdomain_c(qstate->qinfo.qname, dp->name) &&
|
dname_subdomain_c(qinfo->qname, dp->name) &&
|
||||||
delegpt_find_ns(dp, qstate->qinfo.qname,
|
delegpt_find_ns(dp, qinfo->qname, qinfo->qname_len))
|
||||||
qstate->qinfo.qname_len))
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
for(ns = dp->nslist; ns; ns = ns->next) {
|
for(ns = dp->nslist; ns; ns = ns->next) {
|
||||||
|
|
|
||||||
|
|
@ -135,10 +135,12 @@ void iter_mark_cycle_targets(struct module_qstate* qstate, struct delegpt* dp);
|
||||||
/**
|
/**
|
||||||
* See if delegation is useful or offers immediately no targets for
|
* See if delegation is useful or offers immediately no targets for
|
||||||
* further recursion.
|
* further recursion.
|
||||||
* @param qstate: query state with RD flag and query name.
|
* @param qinfo: query name and type
|
||||||
|
* @param qflags: query flags with RD flag
|
||||||
* @param dp: delegpt to check.
|
* @param dp: delegpt to check.
|
||||||
*/
|
*/
|
||||||
int iter_dp_is_useless(struct module_qstate* qstate, struct delegpt* dp);
|
int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
|
||||||
|
struct delegpt* dp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* See if delegation is expected to have DNSSEC information (RRSIGs) in
|
* See if delegation is expected to have DNSSEC information (RRSIGs) in
|
||||||
|
|
|
||||||
|
|
@ -842,7 +842,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||||
* could be useless but lead to loops (bumping into the
|
* could be useless but lead to loops (bumping into the
|
||||||
* same server reply) if useless-checked.
|
* same server reply) if useless-checked.
|
||||||
*/
|
*/
|
||||||
if(iter_dp_is_useless(qstate, iq->dp)) {
|
if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags,
|
||||||
|
iq->dp)) {
|
||||||
if(dname_is_root(iq->dp->name)) {
|
if(dname_is_root(iq->dp->name)) {
|
||||||
/* use safety belt */
|
/* use safety belt */
|
||||||
verbose(VERB_QUERY, "Cache has root NS but "
|
verbose(VERB_QUERY, "Cache has root NS but "
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ usage()
|
||||||
printf(" local_data_remove [name] remove local RR data from name\n");
|
printf(" local_data_remove [name] remove local RR data from name\n");
|
||||||
printf(" dump_cache print cache to stdout\n");
|
printf(" dump_cache print cache to stdout\n");
|
||||||
printf(" load_cache load cache from stdin\n");
|
printf(" load_cache load cache from stdin\n");
|
||||||
|
printf(" lookup [name] print nameservers for name\n");
|
||||||
printf("Version %s\n", PACKAGE_VERSION);
|
printf("Version %s\n", PACKAGE_VERSION);
|
||||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue