mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-06-10 09:00:57 -04:00
Merge branch 'master' into xfr-tsig
This commit is contained in:
commit
54175a4180
20 changed files with 1688 additions and 144 deletions
|
|
@ -1200,7 +1200,7 @@ unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/u
|
|||
$(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h
|
||||
unitdname.lo unitdname.o: $(srcdir)/testcode/unitdname.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \
|
||||
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
|
||||
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
|
||||
unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h $(srcdir)/testcode/unitmain.h \
|
||||
$(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h
|
||||
unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
|
||||
|
|
|
|||
|
|
@ -62,84 +62,232 @@
|
|||
#include "sldns/wire2str.h"
|
||||
#include "sldns/str2wire.h"
|
||||
|
||||
static void spool_txt_printf(struct config_strlist_head* txt,
|
||||
const char* format, ...) ATTR_FORMAT(printf, 2, 3);
|
||||
|
||||
/** Append to strlist at end, and log error if out of memory. */
|
||||
static void
|
||||
spool_txt_string(struct config_strlist_head* txt, char* str)
|
||||
{
|
||||
if(!cfg_strlist_append(txt, strdup(str))) {
|
||||
log_err("out of memory in spool text");
|
||||
}
|
||||
}
|
||||
|
||||
/** Spool txt to spool list. */
|
||||
static void
|
||||
spool_txt_vmsg(struct config_strlist_head* txt, const char* format,
|
||||
va_list args)
|
||||
{
|
||||
char msg[65535];
|
||||
vsnprintf(msg, sizeof(msg), format, args);
|
||||
spool_txt_string(txt, msg);
|
||||
}
|
||||
|
||||
/** Print item to spool list. On alloc failure the list is as before. */
|
||||
static void
|
||||
spool_txt_printf(struct config_strlist_head* txt, const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
spool_txt_vmsg(txt, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/** dump one rrset zonefile line */
|
||||
static int
|
||||
dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
static void
|
||||
dump_rrset_line(struct config_strlist_head* txt, struct ub_packed_rrset_key* k,
|
||||
time_t now, size_t i)
|
||||
{
|
||||
char s[65535];
|
||||
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
|
||||
return ssl_printf(ssl, "BADRR\n");
|
||||
spool_txt_string(txt, "BADRR\n");
|
||||
return;
|
||||
}
|
||||
return ssl_printf(ssl, "%s", s);
|
||||
spool_txt_string(txt, s);
|
||||
}
|
||||
|
||||
/** dump rrset key and data info */
|
||||
static int
|
||||
dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
|
||||
static void
|
||||
dump_rrset(struct config_strlist_head* txt, struct ub_packed_rrset_key* k,
|
||||
struct packed_rrset_data* d, time_t now)
|
||||
{
|
||||
size_t i;
|
||||
/* rd lock held by caller */
|
||||
if(!k || !d) return 1;
|
||||
if(k->id == 0) return 1; /* deleted */
|
||||
if(d->ttl < now) return 1; /* expired */
|
||||
if(!k || !d) return;
|
||||
if(k->id == 0) return; /* deleted */
|
||||
if(d->ttl < now) return; /* expired */
|
||||
|
||||
/* meta line */
|
||||
if(!ssl_printf(ssl, ";rrset%s " ARG_LL "d %u %u %d %d\n",
|
||||
spool_txt_printf(txt, ";rrset%s " ARG_LL "d %u %u %d %d\n",
|
||||
(k->rk.flags & PACKED_RRSET_NSEC_AT_APEX)?" nsec_apex":"",
|
||||
(long long)(d->ttl - now),
|
||||
(unsigned)d->count, (unsigned)d->rrsig_count,
|
||||
(int)d->trust, (int)d->security
|
||||
))
|
||||
return 0;
|
||||
);
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
if(!dump_rrset_line(ssl, k, now, i))
|
||||
dump_rrset_line(txt, k, now, i);
|
||||
}
|
||||
}
|
||||
|
||||
/** Spool strlist to the output. */
|
||||
static int
|
||||
spool_strlist(RES* ssl, struct config_strlist* list)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
for(s=list; s; s=s->next) {
|
||||
if(!ssl_printf(ssl, "%s", s->str))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** dump lruhash rrset cache */
|
||||
/** dump lruhash cache and call callback for every item. */
|
||||
static int
|
||||
dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
|
||||
dump_lruhash(struct lruhash* table,
|
||||
void (*func)(struct lruhash_entry*, struct config_strlist_head*, void*),
|
||||
RES* ssl, void* arg)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
/* lruhash already locked by caller */
|
||||
/* walk in order of lru; best first */
|
||||
for(e=h->lru_start; e; e = e->lru_next) {
|
||||
lock_rw_rdlock(&e->lock);
|
||||
if(!dump_rrset(ssl, (struct ub_packed_rrset_key*)e->key,
|
||||
(struct packed_rrset_data*)e->data, now)) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
int just_started = 1;
|
||||
int not_done = 1;
|
||||
hashvalue_type hash;
|
||||
size_t num = 0; /* number of entries processed. */
|
||||
size_t max = 2; /* number of entries after which it unlocks. */
|
||||
struct config_strlist_head txt; /* Text strings spooled. */
|
||||
memset(&txt, 0, sizeof(txt));
|
||||
|
||||
while(not_done) {
|
||||
size_t i; /* hash bin. */
|
||||
/* Process a number of items. */
|
||||
num = 0;
|
||||
lock_quick_lock(&table->lock);
|
||||
if(just_started) {
|
||||
i = 0;
|
||||
} else {
|
||||
i = hash&table->size_mask;
|
||||
}
|
||||
while(num < max) {
|
||||
/* Process bin. */
|
||||
int found = 0;
|
||||
size_t num_bin = 0;
|
||||
struct lruhash_bin* bin = &table->array[i];
|
||||
struct lruhash_entry* e;
|
||||
lock_quick_lock(&bin->lock);
|
||||
for(e = bin->overflow_list; e; e = e->overflow_next) {
|
||||
/* Entry e is locked by the func. */
|
||||
func(e, &txt, arg);
|
||||
num_bin++;
|
||||
}
|
||||
lock_quick_unlock(&bin->lock);
|
||||
/* This addition of bin number of entries may take
|
||||
* it over the max. */
|
||||
num += num_bin;
|
||||
|
||||
/* Move to next bin. */
|
||||
/* Find one with an entry, with a hash value, so we
|
||||
* can continue from the hash value. The hash value
|
||||
* can be indexed also if the array changes size. */
|
||||
i++;
|
||||
while(i < table->size) {
|
||||
bin = &table->array[i];
|
||||
lock_quick_lock(&bin->lock);
|
||||
if(bin->overflow_list) {
|
||||
hash = bin->overflow_list->hash;
|
||||
lock_quick_unlock(&bin->lock);
|
||||
found = 1;
|
||||
just_started = 0;
|
||||
break;
|
||||
}
|
||||
lock_quick_unlock(&bin->lock);
|
||||
i++;
|
||||
}
|
||||
if(!found) {
|
||||
not_done = 0;
|
||||
lock_quick_unlock(&table->lock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lock_quick_unlock(&table->lock);
|
||||
/* Print the spooled items, that are collected while the
|
||||
* locks are locked. The print happens while they are not
|
||||
* locked. */
|
||||
if(txt.first) {
|
||||
if(!spool_strlist(ssl, txt.first)) {
|
||||
config_delstrlist(txt.first);
|
||||
return 0;
|
||||
}
|
||||
config_delstrlist(txt.first);
|
||||
memset(&txt, 0, sizeof(txt));
|
||||
}
|
||||
}
|
||||
/* Print the final spooled items. */
|
||||
if(txt.first) {
|
||||
if(!spool_strlist(ssl, txt.first)) {
|
||||
config_delstrlist(txt.first);
|
||||
return 0;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
config_delstrlist(txt.first);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** dump slabhash cache and call callback for every item. */
|
||||
static int
|
||||
dump_slabhash(struct slabhash* sh,
|
||||
void (*func)(struct lruhash_entry*, struct config_strlist_head*, void*),
|
||||
RES* ssl, void* arg)
|
||||
{
|
||||
/* Process a number of items at a time, then unlock the cache,
|
||||
* so that ordinary processing can continue. Keep an iteration marker
|
||||
* to continue the loop. That means the cache can change, items
|
||||
* could be inserted and deleted. And, for example, the hash table
|
||||
* can grow. */
|
||||
size_t slab;
|
||||
for(slab=0; slab<sh->size; slab++) {
|
||||
if(!dump_lruhash(sh->array[slab], func, ssl, arg))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Struct for dump information. */
|
||||
struct dump_info {
|
||||
/** The worker. */
|
||||
struct worker* worker;
|
||||
/** The printout connection. */
|
||||
RES* ssl;
|
||||
};
|
||||
|
||||
/** Dump the rrset cache entry */
|
||||
static void
|
||||
dump_rrset_entry(struct lruhash_entry* e, struct config_strlist_head* txt,
|
||||
void* arg)
|
||||
{
|
||||
struct dump_info* dump_info = (struct dump_info*)arg;
|
||||
lock_rw_rdlock(&e->lock);
|
||||
dump_rrset(txt, (struct ub_packed_rrset_key*)e->key,
|
||||
(struct packed_rrset_data*)e->data,
|
||||
*dump_info->worker->env.now);
|
||||
lock_rw_unlock(&e->lock);
|
||||
}
|
||||
|
||||
/** dump rrset cache */
|
||||
static int
|
||||
dump_rrset_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
struct rrset_cache* r = worker->env.rrset_cache;
|
||||
size_t slab;
|
||||
struct dump_info dump_info;
|
||||
dump_info.worker = worker;
|
||||
dump_info.ssl = ssl;
|
||||
if(!ssl_printf(ssl, "START_RRSET_CACHE\n")) return 0;
|
||||
for(slab=0; slab<r->table.size; slab++) {
|
||||
lock_quick_lock(&r->table.array[slab]->lock);
|
||||
if(!dump_rrset_lruhash(ssl, r->table.array[slab],
|
||||
*worker->env.now)) {
|
||||
lock_quick_unlock(&r->table.array[slab]->lock);
|
||||
return 0;
|
||||
}
|
||||
lock_quick_unlock(&r->table.array[slab]->lock);
|
||||
}
|
||||
if(!dump_slabhash(&r->table, &dump_rrset_entry, ssl, &dump_info))
|
||||
return 0;
|
||||
return ssl_printf(ssl, "END_RRSET_CACHE\n");
|
||||
}
|
||||
|
||||
/** dump message to rrset reference */
|
||||
static int
|
||||
dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
|
||||
static void
|
||||
dump_msg_ref(struct config_strlist_head* txt, struct ub_packed_rrset_key* k)
|
||||
{
|
||||
char* nm, *tp, *cl;
|
||||
nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
|
||||
|
|
@ -149,30 +297,25 @@ dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
|
|||
free(nm);
|
||||
free(tp);
|
||||
free(cl);
|
||||
return ssl_printf(ssl, "BADREF\n");
|
||||
}
|
||||
if(!ssl_printf(ssl, "%s %s %s %d\n", nm, cl, tp, (int)k->rk.flags)) {
|
||||
free(nm);
|
||||
free(tp);
|
||||
free(cl);
|
||||
return 0;
|
||||
spool_txt_string(txt, "BADREF\n");
|
||||
return;
|
||||
}
|
||||
spool_txt_printf(txt, "%s %s %s %d\n", nm, cl, tp, (int)k->rk.flags);
|
||||
free(nm);
|
||||
free(tp);
|
||||
free(cl);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** dump message entry */
|
||||
static int
|
||||
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now)
|
||||
static void
|
||||
dump_msg(struct config_strlist_head* txt, struct query_info* k,
|
||||
struct reply_info* d, time_t now)
|
||||
{
|
||||
size_t i;
|
||||
char* nm, *tp, *cl;
|
||||
if(!k || !d) return 1;
|
||||
if(d->ttl < now) return 1; /* expired */
|
||||
|
||||
if(!k || !d) return;
|
||||
if(d->ttl < now) return; /* expired */
|
||||
|
||||
nm = sldns_wire2str_dname(k->qname, k->qname_len);
|
||||
tp = sldns_wire2str_type(k->qtype);
|
||||
cl = sldns_wire2str_class(k->qclass);
|
||||
|
|
@ -180,45 +323,35 @@ dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now)
|
|||
free(nm);
|
||||
free(tp);
|
||||
free(cl);
|
||||
return 1; /* skip this entry */
|
||||
return; /* skip this entry */
|
||||
}
|
||||
if(!rrset_array_lock(d->ref, d->rrset_count, now)) {
|
||||
/* rrsets have timed out or do not exist */
|
||||
free(nm);
|
||||
free(tp);
|
||||
free(cl);
|
||||
return 1; /* skip this entry */
|
||||
return; /* skip this entry */
|
||||
}
|
||||
|
||||
|
||||
/* meta line */
|
||||
if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
|
||||
nm, cl, tp,
|
||||
(int)d->flags, (int)d->qdcount,
|
||||
(long long)(d->ttl-now), (int)d->security,
|
||||
(unsigned)d->an_numrrsets,
|
||||
(unsigned)d->ns_numrrsets,
|
||||
(unsigned)d->ar_numrrsets,
|
||||
(int)d->reason_bogus,
|
||||
d->reason_bogus_str?d->reason_bogus_str:"")) {
|
||||
free(nm);
|
||||
free(tp);
|
||||
free(cl);
|
||||
rrset_array_unlock(d->ref, d->rrset_count);
|
||||
return 0;
|
||||
}
|
||||
spool_txt_printf(txt,
|
||||
"msg %s %s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
|
||||
nm, cl, tp,
|
||||
(int)d->flags, (int)d->qdcount,
|
||||
(long long)(d->ttl-now), (int)d->security,
|
||||
(unsigned)d->an_numrrsets,
|
||||
(unsigned)d->ns_numrrsets,
|
||||
(unsigned)d->ar_numrrsets,
|
||||
(int)d->reason_bogus,
|
||||
d->reason_bogus_str?d->reason_bogus_str:"");
|
||||
free(nm);
|
||||
free(tp);
|
||||
free(cl);
|
||||
|
||||
for(i=0; i<d->rrset_count; i++) {
|
||||
if(!dump_msg_ref(ssl, d->rrsets[i])) {
|
||||
rrset_array_unlock(d->ref, d->rrset_count);
|
||||
return 0;
|
||||
}
|
||||
dump_msg_ref(txt, d->rrsets[i]);
|
||||
}
|
||||
rrset_array_unlock(d->ref, d->rrset_count);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** copy msg to worker pad */
|
||||
|
|
@ -247,49 +380,40 @@ copy_msg(struct regional* region, struct lruhash_entry* e,
|
|||
return (*k)->qname != NULL;
|
||||
}
|
||||
|
||||
/** dump lruhash msg cache */
|
||||
static int
|
||||
dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
|
||||
/** Dump the msg entry. */
|
||||
static void
|
||||
dump_msg_entry(struct lruhash_entry* e, struct config_strlist_head* txt,
|
||||
void* arg)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct dump_info* dump_info = (struct dump_info*)arg;
|
||||
struct query_info* k;
|
||||
struct reply_info* d;
|
||||
|
||||
/* lruhash already locked by caller */
|
||||
/* walk in order of lru; best first */
|
||||
for(e=h->lru_start; e; e = e->lru_next) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
lock_rw_rdlock(&e->lock);
|
||||
/* make copy of rrset in worker buffer */
|
||||
if(!copy_msg(worker->scratchpad, e, &k, &d)) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 0;
|
||||
}
|
||||
regional_free_all(dump_info->worker->scratchpad);
|
||||
/* Make copy of rrset in worker buffer. */
|
||||
lock_rw_rdlock(&e->lock);
|
||||
if(!copy_msg(dump_info->worker->scratchpad, e, &k, &d)) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
/* release lock so we can lookup the rrset references
|
||||
* in the rrset cache */
|
||||
if(!dump_msg(ssl, k, d, *worker->env.now)) {
|
||||
return 0;
|
||||
}
|
||||
log_err("out of memory in dump_msg_entry");
|
||||
return;
|
||||
}
|
||||
return 1;
|
||||
lock_rw_unlock(&e->lock);
|
||||
/* Release lock so we can lookup the rrset references
|
||||
* in the rrset cache. */
|
||||
dump_msg(txt, k, d, *dump_info->worker->env.now);
|
||||
}
|
||||
|
||||
/** dump msg cache */
|
||||
static int
|
||||
dump_msg_cache(RES* ssl, struct worker* worker)
|
||||
{
|
||||
struct slabhash* sh = worker->env.msg_cache;
|
||||
size_t slab;
|
||||
struct dump_info dump_info;
|
||||
dump_info.worker = worker;
|
||||
dump_info.ssl = ssl;
|
||||
if(!ssl_printf(ssl, "START_MSG_CACHE\n")) return 0;
|
||||
for(slab=0; slab<sh->size; slab++) {
|
||||
lock_quick_lock(&sh->array[slab]->lock);
|
||||
if(!dump_msg_lruhash(ssl, worker, sh->array[slab])) {
|
||||
lock_quick_unlock(&sh->array[slab]->lock);
|
||||
return 0;
|
||||
}
|
||||
lock_quick_unlock(&sh->array[slab]->lock);
|
||||
}
|
||||
if(!dump_slabhash(worker->env.msg_cache, &dump_msg_entry, ssl,
|
||||
&dump_info))
|
||||
return 0;
|
||||
return ssl_printf(ssl, "END_MSG_CACHE\n");
|
||||
}
|
||||
|
||||
|
|
@ -811,12 +935,18 @@ print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
|
|||
struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
|
||||
struct packed_rrset_data* d =
|
||||
(struct packed_rrset_data*)k->entry.data;
|
||||
struct config_strlist_head txt;
|
||||
memset(&txt, 0, sizeof(txt));
|
||||
if(d->security == sec_status_bogus) {
|
||||
if(!ssl_printf(ssl, "Address is BOGUS:\n"))
|
||||
return;
|
||||
}
|
||||
if(!dump_rrset(ssl, k, d, 0))
|
||||
dump_rrset(&txt, k, d, 0);
|
||||
if(!spool_strlist(ssl, txt.first)) {
|
||||
config_delstrlist(txt.first);
|
||||
return;
|
||||
}
|
||||
config_delstrlist(txt.first);
|
||||
}
|
||||
delegpt_count_ns(dp, &n_ns, &n_miss);
|
||||
delegpt_count_addr(dp, &n_addr, &n_res, &n_avail);
|
||||
|
|
|
|||
335
daemon/remote.c
335
daemon/remote.c
|
|
@ -101,6 +101,10 @@
|
|||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#endif
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/subnetmod.h"
|
||||
#include "edns-subnet/addrtree.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
|
|
@ -1742,6 +1746,334 @@ do_view_datas_remove(struct daemon_remote* rc, RES* ssl, struct worker* worker,
|
|||
(void)ssl_printf(ssl, "removed %d datas\n", num);
|
||||
}
|
||||
|
||||
/** information for the domain search */
|
||||
struct cache_lookup_info {
|
||||
/** The connection to print on. */
|
||||
RES* ssl;
|
||||
/** The worker. */
|
||||
struct worker* worker;
|
||||
/** The domain, in wireformat. */
|
||||
uint8_t* nm;
|
||||
/** The length of nm. */
|
||||
size_t nmlen;
|
||||
};
|
||||
|
||||
#ifdef CLIENT_SUBNET
|
||||
static void addrtree_traverse_visit_node(struct addrnode* n, addrkey_t* addr,
|
||||
size_t addr_size, int is_ipv6, time_t now, struct query_info* q,
|
||||
void (*func)(struct query_info*, struct reply_info*, addrkey_t*,
|
||||
size_t, int, addrlen_t, int, time_t, void*), void* arg);
|
||||
|
||||
/** Lookup in subnet addrtree */
|
||||
static void
|
||||
cache_lookup_subnet_addrnode(struct query_info* q, struct reply_info* d,
|
||||
addrkey_t* addr, size_t addr_size, int is_ipv6, addrlen_t scope,
|
||||
int only_match_scope_zero, time_t ttl, void* arg)
|
||||
{
|
||||
size_t i;
|
||||
char s[65535], tp[32], cl[32], rc[32], fg[32], astr[64];
|
||||
struct cache_lookup_info* inf = (struct cache_lookup_info*)arg;
|
||||
if(is_ipv6) {
|
||||
if(addr_size < 16 || inet_ntop(AF_INET6, addr, astr,
|
||||
sizeof(astr)) == NULL)
|
||||
snprintf(astr, sizeof(astr), "(inet6ntoperror)");
|
||||
} else {
|
||||
if(addr_size < 4 || inet_ntop(AF_INET, addr, astr,
|
||||
sizeof(astr)) == NULL)
|
||||
snprintf(astr, sizeof(astr), "(inetntoperror)");
|
||||
}
|
||||
sldns_wire2str_dname_buf(q->qname, q->qname_len, s, sizeof(s));
|
||||
sldns_wire2str_type_buf(q->qtype, tp, sizeof(tp));
|
||||
sldns_wire2str_class_buf(q->qclass, cl, sizeof(cl));
|
||||
sldns_wire2str_rcode_buf(FLAGS_GET_RCODE(d->flags),
|
||||
rc, sizeof(rc));
|
||||
snprintf(fg, sizeof(fg), "%s%s%s%s%s%s%s%s",
|
||||
((d->flags&BIT_QR)?" QR":""),
|
||||
((d->flags&BIT_AA)?" AA":""),
|
||||
((d->flags&BIT_TC)?" TC":""),
|
||||
((d->flags&BIT_RD)?" RD":""),
|
||||
((d->flags&BIT_RA)?" RA":""),
|
||||
((d->flags&BIT_Z)?" Z":""),
|
||||
((d->flags&BIT_AD)?" AD":""),
|
||||
((d->flags&BIT_CD)?" CD":""));
|
||||
if(!rrset_array_lock(d->ref, d->rrset_count,
|
||||
*inf->worker->env.now)) {
|
||||
/* rrsets have timed out or do not exist */
|
||||
return;
|
||||
}
|
||||
if(!ssl_printf(inf->ssl, "subnet %s/%d%s %s %s %s " ARG_LL "d\n", astr,
|
||||
(int)scope, (only_match_scope_zero?" scope_zero":""),
|
||||
s, cl, tp, (long long)(ttl-*inf->worker->env.now))) {
|
||||
rrset_array_unlock(d->ref, d->rrset_count);
|
||||
return;
|
||||
}
|
||||
ssl_printf(inf->ssl,
|
||||
"subnet msg %s %s %s%s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
|
||||
s, cl, tp, fg, rc,
|
||||
(int)d->flags, (int)d->qdcount,
|
||||
(long long)(d->ttl-*inf->worker->env.now),
|
||||
(int)d->security,
|
||||
(unsigned)d->an_numrrsets,
|
||||
(unsigned)d->ns_numrrsets,
|
||||
(unsigned)d->ar_numrrsets,
|
||||
(int)d->reason_bogus,
|
||||
d->reason_bogus_str?d->reason_bogus_str:"");
|
||||
for(i=0; i<d->rrset_count; i++) {
|
||||
struct ub_packed_rrset_key* rk = d->rrsets[i];
|
||||
struct packed_rrset_data* rd = (struct packed_rrset_data*)rk->entry.data;
|
||||
size_t j;
|
||||
for(j=0; j<rd->count + rd->rrsig_count; j++) {
|
||||
if(!packed_rr_to_string(rk, j,
|
||||
*inf->worker->env.now, s, sizeof(s))) {
|
||||
ssl_printf(inf->ssl, "BADRR\n");
|
||||
} else {
|
||||
ssl_printf(inf->ssl, "%s", s);
|
||||
}
|
||||
}
|
||||
}
|
||||
rrset_array_unlock(d->ref, d->rrset_count);
|
||||
ssl_printf(inf->ssl, "\n");
|
||||
}
|
||||
|
||||
/** Visit an edge in subnet addrtree traverse */
|
||||
static void
|
||||
addrtree_traverse_visit_edge(struct addredge* edge, addrkey_t* addr,
|
||||
size_t addr_size, int is_ipv6, time_t now, struct query_info* q,
|
||||
void (*func)(struct query_info*, struct reply_info*, addrkey_t*,
|
||||
size_t, int, addrlen_t, int, time_t, void*), void* arg)
|
||||
{
|
||||
size_t n;
|
||||
addrlen_t addrlen;
|
||||
if(!edge || !edge->node)
|
||||
return;
|
||||
addrlen = edge->len;
|
||||
/* ceil() */
|
||||
n = (size_t)((addrlen / KEYWIDTH) + ((addrlen % KEYWIDTH != 0)?1:0));
|
||||
if(n > addr_size)
|
||||
n = addr_size;
|
||||
memset(addr, 0, addr_size);
|
||||
memcpy(addr, edge->str, n);
|
||||
addrtree_traverse_visit_node(edge->node, addr, addr_size, is_ipv6,
|
||||
now, q, func, arg);
|
||||
}
|
||||
|
||||
/** Visit a node in subnet addrtree traverse */
|
||||
static void
|
||||
addrtree_traverse_visit_node(struct addrnode* n, addrkey_t* addr,
|
||||
size_t addr_size, int is_ipv6, time_t now, struct query_info* q,
|
||||
void (*func)(struct query_info*, struct reply_info*, addrkey_t*,
|
||||
size_t, int, addrlen_t, int, time_t, void*), void* arg)
|
||||
{
|
||||
/* If this node has data, and not expired. */
|
||||
if(n->elem && n->ttl >= now) {
|
||||
func(q, (struct reply_info*)n->elem, addr, addr_size, is_ipv6,
|
||||
n->scope, n->only_match_scope_zero, n->ttl, arg);
|
||||
}
|
||||
/* Traverse edges. */
|
||||
addrtree_traverse_visit_edge(n->edge[0], addr, addr_size, is_ipv6,
|
||||
now, q, func, arg);
|
||||
addrtree_traverse_visit_edge(n->edge[1], addr, addr_size, is_ipv6,
|
||||
now, q, func, arg);
|
||||
}
|
||||
|
||||
/** Traverse subnet addrtree */
|
||||
static void
|
||||
addrtree_traverse(struct addrtree* tree, int is_ipv6, time_t now,
|
||||
struct query_info* q,
|
||||
void (*func)(struct query_info*, struct reply_info*, addrkey_t*,
|
||||
size_t, int, addrlen_t, int, time_t, void*), void* arg)
|
||||
{
|
||||
uint8_t addr[16]; /* Large enough for IPv4 and IPv6. */
|
||||
memset(addr, 0, sizeof(addr));
|
||||
addrtree_traverse_visit_node(tree->root, (addrkey_t*)addr,
|
||||
sizeof(addr), is_ipv6, now, q, func, arg);
|
||||
}
|
||||
|
||||
/** Lookup cache_lookup for subnet content. */
|
||||
static void
|
||||
cache_lookup_subnet_msg(struct lruhash_entry* e, void* arg)
|
||||
{
|
||||
struct cache_lookup_info* inf = (struct cache_lookup_info*)arg;
|
||||
struct msgreply_entry *k = (struct msgreply_entry*)e->key;
|
||||
struct subnet_msg_cache_data* d =
|
||||
(struct subnet_msg_cache_data*)e->data;
|
||||
if(!dname_subdomain_c(k->key.qname, inf->nm))
|
||||
return;
|
||||
|
||||
if(d->tree4) {
|
||||
addrtree_traverse(d->tree4, 0, *inf->worker->env.now, &k->key,
|
||||
&cache_lookup_subnet_addrnode, inf);
|
||||
}
|
||||
if(d->tree6) {
|
||||
addrtree_traverse(d->tree6, 1, *inf->worker->env.now, &k->key,
|
||||
&cache_lookup_subnet_addrnode, inf);
|
||||
}
|
||||
}
|
||||
#endif /* CLIENT_SUBNET */
|
||||
|
||||
static void
|
||||
cache_lookup_rrset(struct lruhash_entry* e, void* arg)
|
||||
{
|
||||
struct cache_lookup_info* inf = (struct cache_lookup_info*)arg;
|
||||
struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)e->key;
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)e->data;
|
||||
if(*inf->worker->env.now < d->ttl &&
|
||||
k->id != 0 && /* not deleted */
|
||||
dname_subdomain_c(k->rk.dname, inf->nm)) {
|
||||
size_t i;
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
char s[65535];
|
||||
if(!packed_rr_to_string(k, i, *inf->worker->env.now,
|
||||
s, sizeof(s))) {
|
||||
ssl_printf(inf->ssl, "BADRR\n");
|
||||
return;
|
||||
}
|
||||
ssl_printf(inf->ssl, "%s", s);
|
||||
}
|
||||
ssl_printf(inf->ssl, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cache_lookup_msg(struct lruhash_entry* e, void* arg)
|
||||
{
|
||||
struct cache_lookup_info* inf = (struct cache_lookup_info*)arg;
|
||||
struct msgreply_entry* k = (struct msgreply_entry*)e->key;
|
||||
struct reply_info* d = (struct reply_info*)e->data;
|
||||
if(*inf->worker->env.now < d->ttl &&
|
||||
dname_subdomain_c(k->key.qname, inf->nm)) {
|
||||
size_t i;
|
||||
char s[65535], tp[32], cl[32], rc[32], fg[32];
|
||||
sldns_wire2str_dname_buf(k->key.qname, k->key.qname_len,
|
||||
s, sizeof(s));
|
||||
sldns_wire2str_type_buf(k->key.qtype, tp, sizeof(tp));
|
||||
sldns_wire2str_class_buf(k->key.qclass, cl, sizeof(cl));
|
||||
sldns_wire2str_rcode_buf(FLAGS_GET_RCODE(d->flags),
|
||||
rc, sizeof(rc));
|
||||
snprintf(fg, sizeof(fg), "%s%s%s%s%s%s%s%s",
|
||||
((d->flags&BIT_QR)?" QR":""),
|
||||
((d->flags&BIT_AA)?" AA":""),
|
||||
((d->flags&BIT_TC)?" TC":""),
|
||||
((d->flags&BIT_RD)?" RD":""),
|
||||
((d->flags&BIT_RA)?" RA":""),
|
||||
((d->flags&BIT_Z)?" Z":""),
|
||||
((d->flags&BIT_AD)?" AD":""),
|
||||
((d->flags&BIT_CD)?" CD":""));
|
||||
if(!rrset_array_lock(d->ref, d->rrset_count,
|
||||
*inf->worker->env.now)) {
|
||||
/* rrsets have timed out or do not exist */
|
||||
return;
|
||||
}
|
||||
ssl_printf(inf->ssl,
|
||||
"msg %s %s %s%s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
|
||||
s, cl, tp, fg, rc,
|
||||
(int)d->flags, (int)d->qdcount,
|
||||
(long long)(d->ttl-*inf->worker->env.now),
|
||||
(int)d->security,
|
||||
(unsigned)d->an_numrrsets,
|
||||
(unsigned)d->ns_numrrsets,
|
||||
(unsigned)d->ar_numrrsets,
|
||||
(int)d->reason_bogus,
|
||||
d->reason_bogus_str?d->reason_bogus_str:"");
|
||||
for(i=0; i<d->rrset_count; i++) {
|
||||
struct ub_packed_rrset_key* rk = d->rrsets[i];
|
||||
struct packed_rrset_data* rd = (struct packed_rrset_data*)rk->entry.data;
|
||||
size_t j;
|
||||
for(j=0; j<rd->count + rd->rrsig_count; j++) {
|
||||
if(!packed_rr_to_string(rk, j,
|
||||
*inf->worker->env.now, s, sizeof(s))) {
|
||||
rrset_array_unlock(d->ref, d->rrset_count);
|
||||
ssl_printf(inf->ssl, "BADRR\n");
|
||||
return;
|
||||
}
|
||||
ssl_printf(inf->ssl, "%s", s);
|
||||
}
|
||||
}
|
||||
rrset_array_unlock(d->ref, d->rrset_count);
|
||||
ssl_printf(inf->ssl, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/** perform cache search for domain */
|
||||
static void
|
||||
do_cache_lookup_domain(RES* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen)
|
||||
{
|
||||
#ifdef CLIENT_SUBNET
|
||||
int m;
|
||||
struct subnet_env* sn_env = NULL;
|
||||
#endif /* CLIENT_SUBNET */
|
||||
struct cache_lookup_info inf;
|
||||
inf.ssl = ssl;
|
||||
inf.worker = worker;
|
||||
inf.nm = nm;
|
||||
inf.nmlen = nmlen;
|
||||
|
||||
#ifdef CLIENT_SUBNET
|
||||
m = modstack_find(worker->env.modstack, "subnetcache");
|
||||
if(m != -1) sn_env = (struct subnet_env*)worker->env.modinfo[m];
|
||||
if(sn_env) {
|
||||
lock_rw_rdlock(&sn_env->biglock);
|
||||
slabhash_traverse(sn_env->subnet_msg_cache, 0,
|
||||
&cache_lookup_subnet_msg, &inf);
|
||||
lock_rw_unlock(&sn_env->biglock);
|
||||
}
|
||||
#endif /* CLIENT_SUBNET */
|
||||
|
||||
slabhash_traverse(&worker->env.rrset_cache->table, 0,
|
||||
&cache_lookup_rrset, &inf);
|
||||
slabhash_traverse(worker->env.msg_cache, 0, &cache_lookup_msg, &inf);
|
||||
}
|
||||
|
||||
/** cache lookup of domain */
|
||||
static void
|
||||
do_cache_lookup(RES* ssl, struct worker* worker, char* arg)
|
||||
{
|
||||
uint8_t nm[LDNS_MAX_DOMAINLEN+1];
|
||||
size_t nmlen;
|
||||
int status;
|
||||
char* s = arg, *next = NULL;
|
||||
int allow_long = 0;
|
||||
|
||||
if(arg[0] == '+' && arg[1] == 't' && (arg[2]==' ' || arg[2]=='\t')) {
|
||||
allow_long = 1;
|
||||
s = arg+2;
|
||||
}
|
||||
|
||||
/* Find the commandline arguments of domains. */
|
||||
while(s && *s != 0) {
|
||||
s = skipwhite(s);
|
||||
if(*s == 0)
|
||||
break;
|
||||
if(strchr(s, ' ') || strchr(s, '\t')) {
|
||||
char* sp = strchr(s, ' ');
|
||||
if(strchr(s, '\t') != 0 && strchr(s, '\t') < sp)
|
||||
sp = strchr(s, '\t');
|
||||
*sp = 0;
|
||||
next = sp+1;
|
||||
} else {
|
||||
next = NULL;
|
||||
}
|
||||
|
||||
nmlen = sizeof(nm);
|
||||
status = sldns_str2wire_dname_buf(s, nm, &nmlen);
|
||||
if(status != 0) {
|
||||
ssl_printf(ssl, "error cannot parse name %s at %d: %s\n", s,
|
||||
LDNS_WIREPARSE_OFFSET(status),
|
||||
sldns_get_errorstr_parse(status));
|
||||
return;
|
||||
}
|
||||
if(!allow_long && dname_count_labels(nm) < 3) {
|
||||
ssl_printf(ssl, "error name too short: '%s'. Need example.com. or longer, short names take very long, use +t to allow them.\n", s);
|
||||
return;
|
||||
}
|
||||
|
||||
do_cache_lookup_domain(ssl, worker, nm, nmlen);
|
||||
|
||||
s = next;
|
||||
}
|
||||
}
|
||||
|
||||
/** cache lookup of nameservers */
|
||||
static void
|
||||
do_lookup(RES* ssl, struct worker* worker, char* arg)
|
||||
|
|
@ -3615,6 +3947,9 @@ execute_cmd(struct daemon_remote* rc, struct rc_state* s, RES* ssl, char* cmd,
|
|||
if(rc) distribute_cmd(rc, ssl, cmd);
|
||||
do_flush_requestlist(ssl, worker);
|
||||
return;
|
||||
} else if(cmdcmp(p, "cache_lookup", 12)) {
|
||||
do_cache_lookup(ssl, worker, skipwhite(p+12));
|
||||
return;
|
||||
} else if(cmdcmp(p, "lookup", 6)) {
|
||||
do_lookup(ssl, worker, skipwhite(p+6));
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,47 @@
|
|||
15 August 2025: Wouter
|
||||
- unbound-control cache_lookup +t allows tld and root names. And
|
||||
subnet cache contents are printed.
|
||||
- Fix cache_lookup subnet printout to wipe zero part of the prefix.
|
||||
- Fix cache_lookup subnet print to not print messages without rrsets
|
||||
and perform in-depth check on node in the addrtree.
|
||||
|
||||
14 August 2025: Wouter
|
||||
- Fix to increase responsiveness of dump_cache.
|
||||
- Fix to decouple file descriptor activity and cache lookups in
|
||||
dump_cache.
|
||||
|
||||
13 August 2025: Wouter
|
||||
- unbound-control cache_lookup <domains> prints the cached rrsets
|
||||
and messages for those.
|
||||
- Fix to remove debug from cache_lookup.
|
||||
- Fix to unlock cache_lookup message for malformed records.
|
||||
|
||||
12 August 2025: Wouter
|
||||
- Fix that unbound-control dump_cache releases the cache locks
|
||||
every so often, so that the server stays responsive.
|
||||
|
||||
7 August 2025: Wouter
|
||||
- Fix dname_str for printout of long names. Thanks to Jan Komissar
|
||||
for the fix.
|
||||
- Fix that edns-subnet failure to create a subquery errors as
|
||||
servfail, and not formerror.
|
||||
- Fix to whitespace in dname_str.
|
||||
|
||||
6 August 2025: Wouter
|
||||
- Fix edns subnet, so that the subquery without subnet is stored in
|
||||
global cache if the querier used 0.0.0.0/0 and the name and address
|
||||
do not receive subnet treatment. If the name and address are
|
||||
configured for subnet, it is stored in the subnet cache.
|
||||
|
||||
5 August 2025: Wouter
|
||||
- Fix #1309: incorrectly reclaimed tcp handler can cause data
|
||||
corruption and segfault.
|
||||
- Fix to use assertions for consistency checks in #1309 reclaimed
|
||||
tcp handlers.
|
||||
|
||||
1 August 2025: Wouter
|
||||
- Fix testbound test program to accurately output packets from hex.
|
||||
|
||||
28 July 2025: Wouter
|
||||
- Fix redis cachedb module gettimeofday init failure.
|
||||
|
||||
|
|
|
|||
|
|
@ -386,6 +386,18 @@ There are several commands that the server understands.
|
|||
Not supported in remote Unbounds in multi-process operation.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.commands@cache_lookup@@ [``+t``] *names*
|
||||
Print to stdout the RRsets and messages that are in the cache.
|
||||
For every name listed the content at or under the name is printed.
|
||||
Several names separated by spaces can be given, each is printed.
|
||||
When subnetcache is enabled, also matching entries from the subnet
|
||||
cache are printed.
|
||||
|
||||
The ``+t`` option allows tld and root names.
|
||||
With it names like 'com' and '.' can be used, but it takes a lot of
|
||||
effort to look up in the cache.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.commands@lookup@@ *name*
|
||||
Print to stdout the name servers that would be used to look up the name
|
||||
specified.
|
||||
|
|
|
|||
|
|
@ -154,6 +154,21 @@ int ecs_whitelist_check(struct query_info* qinfo,
|
|||
return 1;
|
||||
sn_env = (struct subnet_env*)qstate->env->modinfo[id];
|
||||
|
||||
if(sq->is_subquery_nonsubnet) {
|
||||
if(sq->is_subquery_scopezero) {
|
||||
/* Check if the result can be stored in the global cache,
|
||||
* this is okay if the address and name are not configured
|
||||
* as subnet address and subnet zone. */
|
||||
if(!ecs_is_whitelisted(sn_env->whitelist,
|
||||
addr, addrlen, qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qclass)) {
|
||||
verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.");
|
||||
qstate->no_cache_store = 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Cache by default, might be disabled after parsing EDNS option
|
||||
* received from nameserver. */
|
||||
if(!iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)
|
||||
|
|
@ -527,11 +542,12 @@ common_prefix(uint8_t *a, uint8_t *b, uint8_t net)
|
|||
/**
|
||||
* Create sub request that looks up the query.
|
||||
* @param qstate: query state
|
||||
* @param id: module id.
|
||||
* @param sq: subnet qstate
|
||||
* @return false on failure.
|
||||
*/
|
||||
static int
|
||||
generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq)
|
||||
generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate* sq)
|
||||
{
|
||||
struct module_qstate* subq = NULL;
|
||||
uint16_t qflags = 0; /* OPCODE QUERY, no flags */
|
||||
|
|
@ -557,10 +573,22 @@ generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq)
|
|||
}
|
||||
if(subq) {
|
||||
/* It is possible to access the subquery module state. */
|
||||
struct subnet_qstate* subsq;
|
||||
if(!subnet_new_qstate(subq, id)) {
|
||||
verbose(VERB_ALGO, "Could not allocate new subnet qstate");
|
||||
return 0;
|
||||
}
|
||||
subsq = (struct subnet_qstate*)subq->minfo[id];
|
||||
subsq->is_subquery_nonsubnet = 1;
|
||||
|
||||
/* When the client asks 0.0.0.0/0 and the name is not treated
|
||||
* as subnet, it is to be stored in the global cache.
|
||||
* Store that the client asked for that, if so. */
|
||||
if(sq->ecs_client_in.subnet_source_mask == 0 &&
|
||||
edns_opt_list_find(qstate->edns_opts_front_in,
|
||||
qstate->env->cfg->client_subnet_opcode)) {
|
||||
subq->no_cache_store = 1;
|
||||
subsq->is_subquery_scopezero = 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
|
@ -569,17 +597,18 @@ generate_sub_request(struct module_qstate *qstate, struct subnet_qstate* sq)
|
|||
/**
|
||||
* Perform the query without subnet
|
||||
* @param qstate: query state
|
||||
* @param id: module id.
|
||||
* @param sq: subnet qstate
|
||||
* @return module state
|
||||
*/
|
||||
static enum module_ext_state
|
||||
generate_lookup_without_subnet(struct module_qstate *qstate,
|
||||
generate_lookup_without_subnet(struct module_qstate *qstate, int id,
|
||||
struct subnet_qstate* sq)
|
||||
{
|
||||
verbose(VERB_ALGO, "subnetcache: make subquery to look up without subnet");
|
||||
if(!generate_sub_request(qstate, sq)) {
|
||||
if(!generate_sub_request(qstate, id, sq)) {
|
||||
verbose(VERB_ALGO, "Could not generate sub query");
|
||||
qstate->return_rcode = LDNS_RCODE_FORMERR;
|
||||
qstate->return_rcode = LDNS_RCODE_SERVFAIL;
|
||||
qstate->return_msg = NULL;
|
||||
return module_finished;
|
||||
}
|
||||
|
|
@ -622,7 +651,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
|||
* is still useful to put it in the edns subnet cache for
|
||||
* when a client explicitly asks for subnet specific answer. */
|
||||
verbose(VERB_QUERY, "subnetcache: Authority indicates no support");
|
||||
return generate_lookup_without_subnet(qstate, sq);
|
||||
return generate_lookup_without_subnet(qstate, id, sq);
|
||||
}
|
||||
|
||||
/* Purposefully there was no sent subnet, and there is consequently
|
||||
|
|
@ -654,7 +683,7 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
|||
qstate->env->cfg->client_subnet_opcode);
|
||||
sq->subnet_sent = 0;
|
||||
sq->subnet_sent_no_subnet = 0;
|
||||
return generate_lookup_without_subnet(qstate, sq);
|
||||
return generate_lookup_without_subnet(qstate, id, sq);
|
||||
}
|
||||
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
|
|
@ -945,7 +974,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
|||
/* aggregated this deaggregated state */
|
||||
qstate->ext_state[id] =
|
||||
generate_lookup_without_subnet(
|
||||
qstate, sq);
|
||||
qstate, id, sq);
|
||||
return;
|
||||
}
|
||||
verbose(VERB_ALGO, "subnetcache: pass to next module");
|
||||
|
|
@ -993,7 +1022,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
|||
qstate->env->cfg->client_subnet_opcode)) {
|
||||
/* client asked for resolution without edns subnet */
|
||||
qstate->ext_state[id] = generate_lookup_without_subnet(
|
||||
qstate, sq);
|
||||
qstate, id, sq);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,10 @@ struct subnet_qstate {
|
|||
int wait_subquery;
|
||||
/** The subquery waited for is done. */
|
||||
int wait_subquery_done;
|
||||
/** The subnet state is a subquery state for nonsubnet lookup. */
|
||||
int is_subquery_nonsubnet;
|
||||
/** This is a subquery, and it is made due to a scope zero request. */
|
||||
int is_subquery_scopezero;
|
||||
};
|
||||
|
||||
void subnet_data_delete(void* d, void* ATTR_UNUSED(arg));
|
||||
|
|
|
|||
|
|
@ -143,6 +143,8 @@ usage(void)
|
|||
printf(" load_cache load cache from stdin\n");
|
||||
printf(" (not supported in remote unbounds in\n");
|
||||
printf(" multi-process operation)\n");
|
||||
printf(" cache_lookup [+t] <names> print rrsets and msgs at or under the names\n");
|
||||
printf(" +t allow tld and root names.\n");
|
||||
printf(" lookup <name> print nameservers for name\n");
|
||||
printf(" flush [+c] <name> flushes common types for name from cache\n");
|
||||
printf(" types: A, AAAA, MX, PTR, NS,\n");
|
||||
|
|
|
|||
|
|
@ -188,6 +188,22 @@ delete_replay_answer(struct replay_answer* a)
|
|||
free(a);
|
||||
}
|
||||
|
||||
/** Log the packet for a reply_packet from testpkts. */
|
||||
static void
|
||||
log_testpkt_reply_pkt(const char* txt, struct reply_packet* reppkt)
|
||||
{
|
||||
if(!reppkt) {
|
||||
log_info("%s <null>", txt);
|
||||
return;
|
||||
}
|
||||
if(reppkt->reply_from_hex) {
|
||||
log_pkt(txt, sldns_buffer_begin(reppkt->reply_from_hex),
|
||||
sldns_buffer_limit(reppkt->reply_from_hex));
|
||||
return;
|
||||
}
|
||||
log_pkt(txt, reppkt->reply_pkt, reppkt->reply_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* return: true if pending query matches the now event.
|
||||
*/
|
||||
|
|
@ -240,9 +256,8 @@ pending_find_match(struct replay_runtime* runtime, struct entry** entry,
|
|||
p->start_step, p->end_step, (*entry)->lineno);
|
||||
if(p->addrlen != 0)
|
||||
log_addr(0, "matched ip", &p->addr, p->addrlen);
|
||||
log_pkt("matched pkt: ",
|
||||
(*entry)->reply_list->reply_pkt,
|
||||
(*entry)->reply_list->reply_len);
|
||||
log_testpkt_reply_pkt("matched pkt: ",
|
||||
(*entry)->reply_list);
|
||||
return 1;
|
||||
}
|
||||
p = p->next_range;
|
||||
|
|
@ -330,7 +345,7 @@ fill_buffer_with_reply(sldns_buffer* buffer, struct entry* entry, uint8_t* q,
|
|||
while(reppkt && i--)
|
||||
reppkt = reppkt->next;
|
||||
if(!reppkt) fatal_exit("extra packet read from TCP stream but none is available");
|
||||
log_pkt("extra_packet ", reppkt->reply_pkt, reppkt->reply_len);
|
||||
log_testpkt_reply_pkt("extra packet ", reppkt);
|
||||
}
|
||||
if(reppkt->reply_from_hex) {
|
||||
c = sldns_buffer_begin(reppkt->reply_from_hex);
|
||||
|
|
@ -462,8 +477,7 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
|
|||
repinfo.c->type = comm_udp;
|
||||
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0, 0);
|
||||
log_info("testbound: incoming QUERY");
|
||||
log_pkt("query pkt", todo->match->reply_list->reply_pkt,
|
||||
todo->match->reply_list->reply_len);
|
||||
log_testpkt_reply_pkt("query pkt ", todo->match->reply_list);
|
||||
/* call the callback for incoming queries */
|
||||
if((*runtime->callback_query)(repinfo.c, runtime->cb_arg,
|
||||
NETEVENT_NOERROR, &repinfo)) {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "util/data/dname.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/str2wire.h"
|
||||
#include "sldns/wire2str.h"
|
||||
|
||||
/** put dname into buffer */
|
||||
static sldns_buffer*
|
||||
|
|
@ -876,6 +877,262 @@ dname_setup_bufs(sldns_buffer* loopbuf, sldns_buffer* boundbuf)
|
|||
sldns_buffer_flip(boundbuf);
|
||||
}
|
||||
|
||||
/* Test strings for the test_long_names test. */
|
||||
/* Each label begins with the length of the label including the length octet. */
|
||||
|
||||
char desc_1[] = "Domain is 1 octet too long.";
|
||||
|
||||
uint8_t wire_dom_1[] = { /* Bad: Domain: (8x)0031abcdefghijklmnopqrstuvwxyz.0007ab. */
|
||||
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
|
||||
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
|
||||
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
|
||||
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
|
||||
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
|
||||
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
|
||||
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
|
||||
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
|
||||
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
|
||||
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
|
||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
|
||||
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Bad: */ 0x06, 0x30, 0x30, 0x30, 0x37, 0x61, 0x62, 0x00
|
||||
};
|
||||
|
||||
char desc_2[] = "Domain has the maximum allowed length (255).";
|
||||
|
||||
uint8_t wire_dom_2[] = { /* Good: Domain: (8x)0031abcdefghijklmnopqrstuvwxyz.00076a. */
|
||||
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
|
||||
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
|
||||
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
|
||||
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
|
||||
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
|
||||
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
|
||||
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
|
||||
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
|
||||
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
|
||||
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
|
||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
|
||||
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Good: */ 0x05, 0x30, 0x30, 0x30, 0x36, 0x61, 0x00
|
||||
};
|
||||
|
||||
char desc_3[] = "Domain has a length one label in the 255th position for a total of 257.";
|
||||
|
||||
uint8_t wire_dom_3[] = { /* Bad: Domain: (8x(0031abcdefghijklmnopqrstuvwxyz.0006ab.1. */
|
||||
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
|
||||
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
|
||||
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
|
||||
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
|
||||
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
|
||||
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
|
||||
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
|
||||
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
|
||||
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
|
||||
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
|
||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
|
||||
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Bad: */ 0x05, 0x30, 0x30, 0x30, 0x36, 0x61, 0x01, 0x32, 0x00
|
||||
};
|
||||
|
||||
char desc_4[] = "Domain has the maximum allowed length (255).";
|
||||
|
||||
uint8_t wire_dom_4[] = { /* Good: Domain: (8x)0031abcdefghijklmnopqrstuvwxyz.03.03. */
|
||||
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
|
||||
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
|
||||
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
|
||||
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
|
||||
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
|
||||
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
|
||||
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
|
||||
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
|
||||
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
|
||||
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
|
||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
|
||||
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Good: */ 0x02, 0x30, 0x33, 0x02, 0x30, 0x33, 0x00
|
||||
};
|
||||
|
||||
char desc_5[] = "Domain has a maximum length label (63) in the 255th position.";
|
||||
|
||||
uint8_t wire_dom_5[] = { /* Bad: Domain: (8x)0031abcdefghijklmnopqrstuvwxyz.03.03.65abc...zab...zab...ghi. */
|
||||
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
|
||||
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
|
||||
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
|
||||
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
|
||||
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
|
||||
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
|
||||
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
|
||||
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
|
||||
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
|
||||
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
|
||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
|
||||
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Bad: */ 0x02, 0x30, 0x33, 0x02, 0x30, 0x33, 0x3f, 0x36,
|
||||
0x33, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65,
|
||||
0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
|
||||
0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x00
|
||||
};
|
||||
|
||||
char desc_6[] = "Domain has a too long label (65) in the 255th position.";
|
||||
|
||||
uint8_t wire_dom_6[] = { /* Bad: Domain: (8x)0031abcdefghijklmnopqrstuvwxyz.03.03.66abc...zab...zab...ijk. */
|
||||
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
|
||||
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
|
||||
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
|
||||
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
|
||||
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
|
||||
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
|
||||
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
|
||||
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61,
|
||||
0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71,
|
||||
0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62,
|
||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72,
|
||||
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, /* Bad: */ 0x02, 0x30, 0x33, 0x02, 0x30, 0x33, 0x41, 0x36,
|
||||
0x36, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65,
|
||||
0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
|
||||
0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x00
|
||||
};
|
||||
|
||||
char desc_7[] = "Domain has a too long label (65) in the 187th position.";
|
||||
|
||||
uint8_t wire_dom_7[] = { /* Bad: Domain: (6x)0031abcdefghijklmnopqrstuvwxyz.65abc..zab...zab...ijk. */
|
||||
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
|
||||
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
|
||||
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
|
||||
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
|
||||
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
|
||||
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
|
||||
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
|
||||
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
|
||||
/* Bad: */ 0x41, 0x36,
|
||||
0x36, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65,
|
||||
0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
|
||||
0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x00
|
||||
};
|
||||
|
||||
char desc_8[] = "Domains has the maximum allowed length and ends with a maximum length label.";
|
||||
|
||||
uint8_t wire_dom_8[] = { /* Good: Domain: (6x)0031abcdefghijklmnopqrstuvwxyz.0004.0064abc..zab...zabcdefg. */
|
||||
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
|
||||
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
|
||||
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
|
||||
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
|
||||
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
|
||||
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
|
||||
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
|
||||
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x03, 0x30, 0x30, 0x34 ,/* Good: */ 0x3f, 0x30,
|
||||
0x30, 0x36, 0x34, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63,
|
||||
0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
|
||||
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x00
|
||||
};
|
||||
|
||||
char desc_9[] = "Domains has 254 octets, one less than the maximum allowed length.";
|
||||
|
||||
uint8_t wire_dom_9[] = { /* Good: Domain: (6x)0031abcdefghijklmnopqrstuvwxyz.0004.0064abc..zab...zabcdef. */
|
||||
0x1e, 0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
|
||||
0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e,
|
||||
0x30, 0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c,
|
||||
0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30,
|
||||
0x30, 0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30,
|
||||
0x33, 0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
|
||||
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33,
|
||||
0x31, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1e, 0x30, 0x30, 0x33, 0x31,
|
||||
0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
|
||||
0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x03, 0x30, 0x30, 0x34 ,/* Good: */ 0x3e, 0x30,
|
||||
0x30, 0x35, 0x34, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
|
||||
0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63,
|
||||
0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
|
||||
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x00
|
||||
};
|
||||
|
||||
/** Test dname to string with long domain names. */
|
||||
static void
|
||||
test_long_names(void)
|
||||
{
|
||||
/* Set to 1 for verbose output, 0 turns it off. */
|
||||
int verbtest = 0;
|
||||
|
||||
uint8_t* wire_doms[] = {wire_dom_1, wire_dom_2, wire_dom_3,
|
||||
wire_dom_4, wire_dom_5, wire_dom_6, wire_dom_7, wire_dom_8,
|
||||
wire_dom_9, 0};
|
||||
char* descs[] = {desc_1, desc_2, desc_3, desc_4, desc_5, desc_6,
|
||||
desc_7, desc_8, desc_9, 0};
|
||||
|
||||
int n;
|
||||
char string_domain[260];
|
||||
uint8_t** wd = wire_doms;
|
||||
int di = 0;
|
||||
int skip = 5; /* 0..6 */
|
||||
|
||||
while (*wd) {
|
||||
|
||||
if(verbtest)
|
||||
printf("Test: %s\n", descs[di++]);
|
||||
|
||||
memset(string_domain, 0xff, sizeof(string_domain));
|
||||
dname_str(*wd, string_domain);
|
||||
for (n = 0 ; n < (int)sizeof(string_domain); ++n) {
|
||||
if ((uint8_t)string_domain[n] == 0xff)
|
||||
break;
|
||||
}
|
||||
if(verbtest)
|
||||
printf("dname_str: L=%d, S=Skipping %d labels...%s\n",
|
||||
n, skip, string_domain + skip*31);
|
||||
unit_assert(n <= 255);
|
||||
|
||||
memset(string_domain, 0xff, sizeof(string_domain));
|
||||
sldns_wire2str_dname_buf(*wd,
|
||||
strlen((char*)*wd)+1 /* strlen works with these test strings */,
|
||||
string_domain,
|
||||
255 /* for comparable result to dname_str */ );
|
||||
for (n = 0 ; n < (int)sizeof(string_domain); ++n) {
|
||||
if ((uint8_t)string_domain[n] == 0xff)
|
||||
break;
|
||||
}
|
||||
if(verbtest)
|
||||
printf("sldns_wire2str_dname_buf: L=%d, S=Skipping %d labels...%s\n",
|
||||
n, skip, string_domain + skip*31);
|
||||
unit_assert(n <= 255);
|
||||
|
||||
++wd;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dname_test_str(sldns_buffer* buff)
|
||||
{
|
||||
|
|
@ -1019,6 +1276,8 @@ dname_test_str(sldns_buffer* buff)
|
|||
unit_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
test_long_names();
|
||||
}
|
||||
|
||||
void dname_test(void)
|
||||
|
|
|
|||
36
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.conf
vendored
Normal file
36
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.conf
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
server:
|
||||
verbosity: 7
|
||||
# num-threads: 1
|
||||
interface: 127.0.0.1
|
||||
interface: 127.0.0.1@@PROXYPORT@
|
||||
port: @PORT@
|
||||
proxy-protocol-port: @PROXYPORT@
|
||||
access-control: 1.0.0.0/8 allow
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
send-client-subnet: 127.0.0.1
|
||||
max-client-subnet-ipv4: 17
|
||||
module-config: "subnetcache iterator"
|
||||
qname-minimisation: no
|
||||
minimal-responses: no
|
||||
remote-control:
|
||||
control-enable: yes
|
||||
control-interface: @CONTROL_PATH@/controlpipe.@CONTROL_PID@
|
||||
control-use-cert: no
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-prime: no
|
||||
stub-addr: "127.0.0.1@@TOPORT@"
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-prime: no
|
||||
stub-addr: "127.0.0.1@@TOPORT@"
|
||||
stub-zone:
|
||||
name: "example.net"
|
||||
stub-prime: no
|
||||
stub-addr: "127.0.0.1@@TOPORT@"
|
||||
16
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.dsc
vendored
Normal file
16
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.dsc
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
BaseName: subnet_cache_lookup
|
||||
Version: 1.0
|
||||
Description: Subnet cache contents with unbound-control cache_lookup
|
||||
CreationDate: Fri Aug 15 11:00:00 CEST 2025
|
||||
Maintainer: dr. W.C.A. Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: subnet_cache_lookup.pre
|
||||
Post: subnet_cache_lookup.post
|
||||
Test: subnet_cache_lookup.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
15
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.post
vendored
Normal file
15
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.post
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# #-- subnet_cache_lookup.post --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# source the test var file when it's there
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
#
|
||||
# do your teardown here
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
echo "> cat logfiles"
|
||||
kill_pid $FWD_PID
|
||||
kill_pid $UNBOUND_PID
|
||||
rm -f $CONTROL_PATH/controlpipe.$CONTROL_PID
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
42
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.pre
vendored
Normal file
42
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.pre
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# #-- subnet_cache_lookup.pre--#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
if grep "define CLIENT_SUBNET 1" $PRE/config.h; then echo test enabled; else skip_test "test skipped"; fi
|
||||
|
||||
get_make
|
||||
(cd $PRE; $MAKE streamtcp)
|
||||
|
||||
get_random_port 3
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
PROXY_PORT=$(($RND_PORT + 1))
|
||||
FWD_PORT=$(($RND_PORT + 2))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "PROXY_PORT=$PROXY_PORT" >> .tpkg.var.test
|
||||
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
|
||||
|
||||
# start forwarder
|
||||
get_ldns_testns
|
||||
$LDNS_TESTNS -p $FWD_PORT subnet_cache_lookup.testns >fwd.log 2>&1 &
|
||||
FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
CONTROL_PATH=/tmp
|
||||
CONTROL_PID=$$
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@PROXYPORT\@/'$PROXY_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's?@CONTROL_PATH\@?'$CONTROL_PATH'?' -e 's/@CONTROL_PID@/'$CONTROL_PID'/' < subnet_cache_lookup.conf > ub.conf
|
||||
# start unbound in the background
|
||||
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
echo "CONTROL_PATH=$CONTROL_PATH" >> .tpkg.var.test
|
||||
echo "CONTROL_PID=$CONTROL_PID" >> .tpkg.var.test
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_ldns_testns_up fwd.log
|
||||
wait_unbound_up unbound.log
|
||||
|
||||
121
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.test
vendored
Normal file
121
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.test
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# #-- subnet_cache_lookup.test --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
PRE="../.."
|
||||
# do the test
|
||||
echo "> dig www.example.com."
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 10
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 10
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
#echo "> cat logfiles"
|
||||
#cat fwd.log
|
||||
#cat unbound.log
|
||||
echo "> check answer"
|
||||
if grep www.example.com outfile | grep "10.20.30.40"; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "> unbound-control status"
|
||||
$PRE/unbound-control -c ub.conf status
|
||||
if test $? -ne 0; then
|
||||
echo "wrong exit value."
|
||||
exit 1
|
||||
else
|
||||
echo "exit value: OK"
|
||||
fi
|
||||
|
||||
echo "> unbound-control cache_lookup example.com"
|
||||
$PRE/unbound-control -c ub.conf cache_lookup example.com 2>&1 | tee outfile
|
||||
if test $? -ne 0; then
|
||||
echo "wrong exit value."
|
||||
exit 1
|
||||
fi
|
||||
echo "> check unbound-control output"
|
||||
if grep "subnet" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "> use proxy-protocol to put more addresses in the edns subnet cache"
|
||||
$PRE/streamtcp -f 127.0.0.1@$PROXY_PORT -p 1.1.3.4 www.example.net. A IN | tee outfile
|
||||
if grep www.example.net outfile | grep "10.20.30.41"; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$PRE/streamtcp -f 127.0.0.1@$PROXY_PORT -p 1.2.3.4 www.example.net. A IN | tee outfile
|
||||
if grep www.example.net outfile | grep "10.20.30.42"; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$PRE/streamtcp -f 127.0.0.1@$PROXY_PORT -p 1.3.3.4 www.example.net. A IN | tee outfile
|
||||
if grep www.example.net outfile | grep "10.20.30.43"; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$PRE/streamtcp -f 127.0.0.1@$PROXY_PORT -p 1.4.3.4 www.example.net. A IN | tee outfile
|
||||
if grep www.example.net outfile | grep "10.20.30.44"; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "> unbound-control cache_lookup example.net"
|
||||
$PRE/unbound-control -c ub.conf cache_lookup example.net 2>&1 | tee outfile
|
||||
if test $? -ne 0; then
|
||||
echo "wrong exit value."
|
||||
exit 1
|
||||
fi
|
||||
echo "> check unbound-control output"
|
||||
if grep "subnet" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
181
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.testns
vendored
Normal file
181
testdata/subnet_cache_lookup.tdir/subnet_cache_lookup.testns
vendored
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS test.ns.
|
||||
SECTION ADDITIONAL
|
||||
test.ns. IN A 127.0.0.1
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
;MATCH opcode qtype qname ednsdata
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 127.0.0.1
|
||||
00 08 ; OPC
|
||||
00 07 ; option length
|
||||
00 01 ; Family
|
||||
11 11 ; source mask, scopemask
|
||||
7f 00 00 ; address
|
||||
HEX_EDNSDATA_END
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN SOA
|
||||
SECTION ANSWER
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.net. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 1.1.3.4
|
||||
00 08 ; OPC
|
||||
00 07 ; option length
|
||||
00 01 ; Family
|
||||
11 00 ; source mask, scopemask
|
||||
01 01 00 ; address
|
||||
HEX_EDNSDATA_END
|
||||
HEX_ANSWER_BEGIN
|
||||
00 00 84 00 00 01 00 01 ;ID 0, QR AA
|
||||
00 00 00 01 03 77 77 77 ; www.example.net. A? (DO)
|
||||
07 65 78 61 6d 70 6c 65
|
||||
03 6e 65 74 00 00 01 00
|
||||
01
|
||||
; www.example.net. A 10.20.30.41
|
||||
03 77 77 77 07 65 78 61 6d 70 6c 65 03 6e 65 74 00
|
||||
00 01 00 01 00 00 0e 10 00 04
|
||||
0a 14 1e 29
|
||||
|
||||
00 00 29 10 00 00 00
|
||||
80 00 00 0b
|
||||
00 08 00 07 ; OPC, optlen
|
||||
00 01 11 11 ; ip4, scope 17, source 17
|
||||
01 01 00 ;1.1.0.0/17
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.net. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 1.2.3.4
|
||||
00 08 ; OPC
|
||||
00 07 ; option length
|
||||
00 01 ; Family
|
||||
11 00 ; source mask, scopemask
|
||||
01 02 00 ; address
|
||||
HEX_EDNSDATA_END
|
||||
HEX_ANSWER_BEGIN
|
||||
00 00 84 00 00 01 00 01 ;ID 0, QR AA
|
||||
00 00 00 01 03 77 77 77 ; www.example.net. A? (DO)
|
||||
07 65 78 61 6d 70 6c 65
|
||||
03 6e 65 74 00 00 01 00
|
||||
01
|
||||
; www.example.net. A 10.20.30.42
|
||||
03 77 77 77 07 65 78 61 6d 70 6c 65 03 6e 65 74 00
|
||||
00 01 00 01 00 00 0e 10 00 04
|
||||
0a 14 1e 2a
|
||||
|
||||
00 00 29 10 00 00 00
|
||||
80 00 00 0b
|
||||
00 08 00 07 ; OPC, optlen
|
||||
00 01 11 11 ; ip4, scope 17, source 17
|
||||
01 02 00 ;1.2.0.0/17
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.net. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 1.3.3.4
|
||||
00 08 ; OPC
|
||||
00 07 ; option length
|
||||
00 01 ; Family
|
||||
11 00 ; source mask, scopemask
|
||||
01 03 00 ; address
|
||||
HEX_EDNSDATA_END
|
||||
HEX_ANSWER_BEGIN
|
||||
00 00 84 00 00 01 00 01 ;ID 0, QR AA
|
||||
00 00 00 01 03 77 77 77 ; www.example.net. A? (DO)
|
||||
07 65 78 61 6d 70 6c 65
|
||||
03 6e 65 74 00 00 01 00
|
||||
01
|
||||
; www.example.net. A 10.20.30.43
|
||||
03 77 77 77 07 65 78 61 6d 70 6c 65 03 6e 65 74 00
|
||||
00 01 00 01 00 00 0e 10 00 04
|
||||
0a 14 1e 2b
|
||||
|
||||
00 00 29 10 00 00 00
|
||||
80 00 00 0b
|
||||
00 08 00 07 ; OPC, optlen
|
||||
00 01 11 11 ; ip4, scope 17, source 17
|
||||
01 03 00 ;1.3.0.0/17
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.net. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 1.4.3.4
|
||||
00 08 ; OPC
|
||||
00 07 ; option length
|
||||
00 01 ; Family
|
||||
11 00 ; source mask, scopemask
|
||||
01 04 00 ; address
|
||||
HEX_EDNSDATA_END
|
||||
HEX_ANSWER_BEGIN
|
||||
00 00 84 00 00 01 00 01 ;ID 0, QR AA
|
||||
00 00 00 01 03 77 77 77 ; www.example.net. A? (DO)
|
||||
07 65 78 61 6d 70 6c 65
|
||||
03 6e 65 74 00 00 01 00
|
||||
01
|
||||
; www.example.net. A 10.20.30.44
|
||||
03 77 77 77 07 65 78 61 6d 70 6c 65 03 6e 65 74 00
|
||||
00 01 00 01 00 00 0e 10 00 04
|
||||
0a 14 1e 2c
|
||||
|
||||
00 00 29 10 00 00 00
|
||||
80 00 00 0b
|
||||
00 08 00 07 ; OPC, optlen
|
||||
00 01 11 11 ; ip4, scope 17, source 17
|
||||
01 04 00 ;1.4.0.0/17
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
280
testdata/subnet_scopezero_global.crpl
vendored
Normal file
280
testdata/subnet_scopezero_global.crpl
vendored
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
; config options
|
||||
server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
module-config: "subnetcache validator iterator"
|
||||
verbosity: 4
|
||||
qname-minimisation: no
|
||||
; the domain is not configured for edns-subnet
|
||||
;send-client-subnet: 1.2.3.4
|
||||
client-subnet-zone: "ex2.com"
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129
|
||||
|
||||
stub-zone:
|
||||
name: "example.com"
|
||||
stub-addr: 1.2.3.4
|
||||
stub-zone:
|
||||
name: "ex2.com"
|
||||
stub-addr: 1.2.3.5
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test subnet cache with scope zero for global cache store.
|
||||
|
||||
; the upstream server.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
;; we expect to receive empty
|
||||
HEX_EDNSDATA_END
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
RANGE_BEGIN 0 21
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
RANGE_BEGIN 20 61
|
||||
ADDRESS 1.2.3.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.ex2.com. IN A
|
||||
SECTION ANSWER
|
||||
www.ex2.com. IN A 10.20.30.41
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
RANGE_BEGIN 90 101
|
||||
ADDRESS 1.2.3.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id copy_ednsdata_assume_clientsubnet
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.ex2.com. IN A
|
||||
SECTION ANSWER
|
||||
www.ex2.com. 10 IN A 10.20.30.42
|
||||
SECTION AUTHORITY
|
||||
ex2.com. IN NS ns.ex2.com.
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 127.0.0.1
|
||||
00 08 ; OPC
|
||||
00 07 ; option length
|
||||
00 01 ; Family
|
||||
18 00 ; source mask, scopemask
|
||||
7f 00 00 ; address
|
||||
HEX_EDNSDATA_END
|
||||
ns.ex2.com. IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; query for 0.0.0.0/0
|
||||
STEP 10 QUERY
|
||||
ENTRY_BEGIN
|
||||
HEX_ANSWER_BEGIN
|
||||
00 00 01 00 00 01 00 00 ;ID 0
|
||||
00 00 00 01 03 77 77 77 ; www.example.com A? (DO)
|
||||
07 65 78 61 6d 70 6c 65
|
||||
03 63 6f 6d 00 00 01 00
|
||||
01 00 00 29 10 00 00 00
|
||||
80 00 00 08
|
||||
|
||||
00 08 00 04 ; OPC, optlen
|
||||
00 01 00 00 ; ip4, scope 0, source 0
|
||||
;0.0.0.0/0
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ednsdata
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 ; OPC
|
||||
00 04 ; option length
|
||||
00 01 ; Family
|
||||
00 00 ; source mask, scopemask
|
||||
; address
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
; That that it is in global cache.
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ednsdata
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
ENTRY_END
|
||||
|
||||
; With a query where the name is whitelisted, it should not be stored
|
||||
; in global cache.
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
HEX_ANSWER_BEGIN
|
||||
00 00 01 00 00 01 00 00 ;ID 0
|
||||
00 00 00 01 03 77 77 77 ; www.ex2.com A? (DO)
|
||||
03 65 78 32 03 63 6f 6d
|
||||
00 00 01 00 01 00 00 29
|
||||
10 00 00 00 80 00 00 08
|
||||
|
||||
00 08 00 04 ; OPC, optlen
|
||||
00 01 00 00 ; ip4, scope 0, source 0
|
||||
;0.0.0.0/0
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ednsdata
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.ex2.com. IN A
|
||||
SECTION ANSWER
|
||||
www.ex2.com. IN A 10.20.30.41
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 ; OPC
|
||||
00 04 ; option length
|
||||
00 01 ; Family
|
||||
00 00 ; source mask, scopemask
|
||||
; address
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 70 QUERY
|
||||
ENTRY_BEGIN
|
||||
HEX_ANSWER_BEGIN
|
||||
00 00 01 00 00 01 00 00 ;ID 0
|
||||
00 00 00 01 03 77 77 77 ; www.ex2.com A? (DO)
|
||||
03 65 78 32 03 63 6f 6d
|
||||
00 00 01 00 01 00 00 29
|
||||
10 00 00 00 80 00 00 08
|
||||
|
||||
00 08 00 04 ; OPC, optlen
|
||||
00 01 00 00 ; ip4, scope 0, source 0
|
||||
;0.0.0.0/0
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 80 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ednsdata
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.ex2.com. IN A
|
||||
SECTION ANSWER
|
||||
www.ex2.com. IN A 10.20.30.41
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 ; OPC
|
||||
00 04 ; option length
|
||||
00 01 ; Family
|
||||
00 00 ; source mask, scopemask
|
||||
; address
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
; www.ex2.com is not in the global cache. and gets subnet treatment
|
||||
STEP 90 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD NOERROR
|
||||
SECTION QUESTION
|
||||
www.ex2.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 100 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ednsdata
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.ex2.com. IN A
|
||||
SECTION ANSWER
|
||||
www.ex2.com. IN A 10.20.30.42
|
||||
ENTRY_END
|
||||
|
||||
; that result is in the subnet cache
|
||||
STEP 110 QUERY
|
||||
ENTRY_BEGIN
|
||||
HEX_ANSWER_BEGIN
|
||||
00 00 01 00 00 01 00 00 ;ID 0
|
||||
00 00 00 01 03 77 77 77 ; www.ex2.com A? (DO)
|
||||
03 65 78 32 03 63 6f 6d
|
||||
00 00 01 00 01 00 00 29
|
||||
10 00 00 00 80 00 00 0b
|
||||
|
||||
00 08 00 07 ; OPC, optlen
|
||||
; ip4 127.0.0.0/24 scope /0
|
||||
00 01 ; Family
|
||||
18 00 ; source mask, scopemask
|
||||
7f 00 00 ; address
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 120 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ednsdata
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.ex2.com. IN A
|
||||
SECTION ANSWER
|
||||
www.ex2.com. IN A 10.20.30.42
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 ; OPC
|
||||
00 07 ; option length
|
||||
; ip4 127.0.0.0/24 scope /24
|
||||
00 01 ; Family
|
||||
18 18 ; source mask, scopemask
|
||||
7f 00 00 ; address
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
|
@ -644,20 +644,22 @@ void dname_str(uint8_t* dname, char* str)
|
|||
if(!dname || !*dname) {
|
||||
*s++ = '.';
|
||||
*s = 0;
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
lablen = *dname++;
|
||||
while(lablen) {
|
||||
len += lablen+1;
|
||||
if(len >= LDNS_MAX_DOMAINLEN) {
|
||||
if ((s-str) >= (LDNS_MAX_DOMAINLEN-1))
|
||||
s = str + LDNS_MAX_DOMAINLEN - 2;
|
||||
*s++ = '&';
|
||||
*s = 0;
|
||||
return;
|
||||
}
|
||||
if(lablen > LDNS_MAX_LABELLEN) {
|
||||
*s++ = '#';
|
||||
*s = 0;
|
||||
goto out;
|
||||
}
|
||||
len += lablen+1;
|
||||
if(len >= LDNS_MAX_DOMAINLEN) {
|
||||
*s++ = '&';
|
||||
*s = 0;
|
||||
goto out;
|
||||
return;
|
||||
}
|
||||
while(lablen--) {
|
||||
if(isalnum((unsigned char)*dname)
|
||||
|
|
@ -673,10 +675,6 @@ void dname_str(uint8_t* dname, char* str)
|
|||
lablen = *dname++;
|
||||
}
|
||||
*s = 0;
|
||||
|
||||
out:
|
||||
log_assert(s - str < LDNS_MAX_DOMAINLEN);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -3218,6 +3218,9 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
|
|||
}
|
||||
/* accept incoming connection. */
|
||||
c_hdl = c->tcp_free;
|
||||
/* Should not happen: inconsistent tcp_free state in
|
||||
* accept_callback. */
|
||||
log_assert(c_hdl->is_in_tcp_free);
|
||||
/* clear leftover flags from previous use, and then set the
|
||||
* correct event base for the event structure for libevent */
|
||||
ub_event_free(c_hdl->ev->ev);
|
||||
|
|
@ -3292,10 +3295,15 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Paranoia: Check that the state has not changed from above: */
|
||||
/* Should not happen: tcp_free state changed within accept_callback. */
|
||||
log_assert(c_hdl == c->tcp_free);
|
||||
log_assert(c_hdl->is_in_tcp_free);
|
||||
/* grab the tcp handler buffers */
|
||||
c->cur_tcp_count++;
|
||||
c->tcp_free = c_hdl->tcp_free;
|
||||
c_hdl->tcp_free = NULL;
|
||||
c_hdl->is_in_tcp_free = 0;
|
||||
if(!c->tcp_free) {
|
||||
/* stop accepting incoming queries for now. */
|
||||
comm_point_stop_listening(c);
|
||||
|
|
@ -3316,12 +3324,14 @@ reclaim_tcp_handler(struct comm_point* c)
|
|||
#endif
|
||||
}
|
||||
comm_point_close(c);
|
||||
if(c->tcp_parent) {
|
||||
if(c != c->tcp_parent->tcp_free) {
|
||||
c->tcp_parent->cur_tcp_count--;
|
||||
c->tcp_free = c->tcp_parent->tcp_free;
|
||||
c->tcp_parent->tcp_free = c;
|
||||
}
|
||||
if(c->tcp_parent && !c->is_in_tcp_free) {
|
||||
/* Should not happen: bad tcp_free state in reclaim_tcp. */
|
||||
log_assert(c->tcp_free == NULL);
|
||||
log_assert(c->tcp_parent->cur_tcp_count > 0);
|
||||
c->tcp_parent->cur_tcp_count--;
|
||||
c->tcp_free = c->tcp_parent->tcp_free;
|
||||
c->tcp_parent->tcp_free = c;
|
||||
c->is_in_tcp_free = 1;
|
||||
if(!c->tcp_free) {
|
||||
/* re-enable listening on accept socket */
|
||||
comm_point_start_listening(c->tcp_parent, -1, -1);
|
||||
|
|
@ -4707,12 +4717,14 @@ reclaim_http_handler(struct comm_point* c)
|
|||
#endif
|
||||
}
|
||||
comm_point_close(c);
|
||||
if(c->tcp_parent) {
|
||||
if(c != c->tcp_parent->tcp_free) {
|
||||
c->tcp_parent->cur_tcp_count--;
|
||||
c->tcp_free = c->tcp_parent->tcp_free;
|
||||
c->tcp_parent->tcp_free = c;
|
||||
}
|
||||
if(c->tcp_parent && !c->is_in_tcp_free) {
|
||||
/* Should not happen: bad tcp_free state in reclaim_http. */
|
||||
log_assert(c->tcp_free == NULL);
|
||||
log_assert(c->tcp_parent->cur_tcp_count > 0);
|
||||
c->tcp_parent->cur_tcp_count--;
|
||||
c->tcp_free = c->tcp_parent->tcp_free;
|
||||
c->tcp_parent->tcp_free = c;
|
||||
c->is_in_tcp_free = 1;
|
||||
if(!c->tcp_free) {
|
||||
/* re-enable listening on accept socket */
|
||||
comm_point_start_listening(c->tcp_parent, -1, -1);
|
||||
|
|
@ -5748,6 +5760,7 @@ comm_point_create_udp(struct comm_base *base, int fd, sldns_buffer* buffer,
|
|||
c->cur_tcp_count = 0;
|
||||
c->tcp_handlers = NULL;
|
||||
c->tcp_free = NULL;
|
||||
c->is_in_tcp_free = 0;
|
||||
c->type = comm_udp;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
|
|
@ -5812,6 +5825,7 @@ comm_point_create_udp_ancil(struct comm_base *base, int fd,
|
|||
c->cur_tcp_count = 0;
|
||||
c->tcp_handlers = NULL;
|
||||
c->tcp_free = NULL;
|
||||
c->is_in_tcp_free = 0;
|
||||
c->type = comm_udp;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
|
|
@ -5879,6 +5893,7 @@ comm_point_create_doq(struct comm_base *base, int fd, sldns_buffer* buffer,
|
|||
c->cur_tcp_count = 0;
|
||||
c->tcp_handlers = NULL;
|
||||
c->tcp_free = NULL;
|
||||
c->is_in_tcp_free = 0;
|
||||
c->type = comm_doq;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
|
|
@ -5979,6 +5994,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
|
|||
c->cur_tcp_count = 0;
|
||||
c->tcp_handlers = NULL;
|
||||
c->tcp_free = NULL;
|
||||
c->is_in_tcp_free = 0;
|
||||
c->type = comm_tcp;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
|
|
@ -6016,6 +6032,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
|
|||
/* add to parent free list */
|
||||
c->tcp_free = parent->tcp_free;
|
||||
parent->tcp_free = c;
|
||||
c->is_in_tcp_free = 1;
|
||||
/* ub_event stuff */
|
||||
evbits = UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT;
|
||||
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
|
||||
|
|
@ -6078,6 +6095,7 @@ comm_point_create_http_handler(struct comm_base *base,
|
|||
c->cur_tcp_count = 0;
|
||||
c->tcp_handlers = NULL;
|
||||
c->tcp_free = NULL;
|
||||
c->is_in_tcp_free = 0;
|
||||
c->type = comm_http;
|
||||
c->tcp_do_close = 1;
|
||||
c->do_not_close = 0;
|
||||
|
|
@ -6136,6 +6154,7 @@ comm_point_create_http_handler(struct comm_base *base,
|
|||
/* add to parent free list */
|
||||
c->tcp_free = parent->tcp_free;
|
||||
parent->tcp_free = c;
|
||||
c->is_in_tcp_free = 1;
|
||||
/* ub_event stuff */
|
||||
evbits = UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT;
|
||||
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
|
||||
|
|
@ -6197,6 +6216,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num,
|
|||
return NULL;
|
||||
}
|
||||
c->tcp_free = NULL;
|
||||
c->is_in_tcp_free = 0;
|
||||
c->type = comm_tcp_accept;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
|
|
@ -6291,6 +6311,7 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
|
|||
c->cur_tcp_count = 0;
|
||||
c->tcp_handlers = NULL;
|
||||
c->tcp_free = NULL;
|
||||
c->is_in_tcp_free = 0;
|
||||
c->type = comm_tcp;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
|
|
@ -6355,6 +6376,7 @@ comm_point_create_http_out(struct comm_base *base, size_t bufsize,
|
|||
c->cur_tcp_count = 0;
|
||||
c->tcp_handlers = NULL;
|
||||
c->tcp_free = NULL;
|
||||
c->is_in_tcp_free = 0;
|
||||
c->type = comm_http;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 0;
|
||||
|
|
@ -6425,6 +6447,7 @@ comm_point_create_local(struct comm_base *base, int fd, size_t bufsize,
|
|||
c->cur_tcp_count = 0;
|
||||
c->tcp_handlers = NULL;
|
||||
c->tcp_free = NULL;
|
||||
c->is_in_tcp_free = 0;
|
||||
c->type = comm_local;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 1;
|
||||
|
|
@ -6488,6 +6511,7 @@ comm_point_create_raw(struct comm_base* base, int fd, int writing,
|
|||
c->cur_tcp_count = 0;
|
||||
c->tcp_handlers = NULL;
|
||||
c->tcp_free = NULL;
|
||||
c->is_in_tcp_free = 0;
|
||||
c->type = comm_raw;
|
||||
c->tcp_do_close = 0;
|
||||
c->do_not_close = 1;
|
||||
|
|
|
|||
|
|
@ -238,6 +238,8 @@ struct comm_point {
|
|||
/** linked list of free tcp_handlers to use for new queries.
|
||||
For tcp_accept the first entry, for tcp_handlers the next one. */
|
||||
struct comm_point* tcp_free;
|
||||
/** Whether this struct is in its parent's tcp_free list */
|
||||
int is_in_tcp_free;
|
||||
|
||||
/* -------- SSL TCP DNS ------- */
|
||||
/** the SSL object with rw bio (owned) or for commaccept ctx ref */
|
||||
|
|
|
|||
Loading…
Reference in a new issue