#include "config.h"
#include "testcode/unitmain.h"
#include "iterator/iterator.h"
#include "services/cache/infra.h"
#include "util/config_file.h"
#include "util/net_help.h"
static struct infra_data* infra_lookup_host(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int wr, time_t now, struct infra_key** k)
{
struct infra_data* d;
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
zone, zonelen, wr);
if(!e) return NULL;
d = (struct infra_data*)e->data;
if(d->ttl < now) {
lock_rw_unlock(&e->lock);
return NULL;
}
*k = (struct infra_key*)e->key;
return d;
}
static void test_keep_probing(struct infra_cache* slab,
struct config_file* cfg, struct sockaddr_storage one, socklen_t onelen,
uint8_t* zone, size_t zonelen, time_t *now, int keep_probing,
int rtt_max_timeout)
{
uint8_t edns_lame;
int vs, to, lame, dnsseclame, reclame, probedelay;
struct infra_key* k;
struct infra_data* d;
cfg->infra_cache_max_rtt = rtt_max_timeout;
config_apply_max_rtt(rtt_max_timeout);
slab->infra_keep_probing = keep_probing;
*now += cfg->host_ttl + 10;
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
*now, &vs, &edns_lame, &to) );
while(to < USEFUL_SERVER_TOP_TIMEOUT) {
unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen,
LDNS_RR_TYPE_A, -1, to, *now) );
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
*now, &vs, &edns_lame, &to) );
unit_assert( vs == 0 && to <= USEFUL_SERVER_TOP_TIMEOUT && edns_lame == 0 );
}
unit_assert( vs == 0 && to == USEFUL_SERVER_TOP_TIMEOUT && edns_lame == 0 );
unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, *now, &k)) );
unit_assert( d->timeout_A >= TIMEOUT_COUNT_MAX );
unit_assert( d->probedelay > 0 );
probedelay = d->probedelay;
lock_rw_unlock(&k->entry.lock);
cfg->host_ttl = cfg->host_ttl + *now < probedelay
?cfg->host_ttl :probedelay + 10;
*now = probedelay;
unit_assert( infra_get_lame_rtt(slab, &one, onelen, zone, zonelen,
LDNS_RR_TYPE_A, &lame, &dnsseclame, &reclame, &to, *now) );
unit_assert( lame == 0 && dnsseclame == 0 && reclame == 0
&& to == keep_probing ?still_useful_timeout() :USEFUL_SERVER_TOP_TIMEOUT);
}
void infra_test(void)
{
struct sockaddr_storage one;
socklen_t onelen;
uint8_t* zone = (uint8_t*)"\007example\003com\000";
size_t zonelen = 13;
struct infra_cache* slab;
struct config_file* cfg = config_create();
time_t now = 0;
uint8_t edns_lame;
int vs, to;
struct infra_key* k;
struct infra_data* d;
int init = UNKNOWN_SERVER_NICENESS;
int default_max_rtt = USEFUL_SERVER_TOP_TIMEOUT;
unit_show_feature("infra cache");
unit_assert(ipstrtoaddr("127.0.0.1", 53, &one, &onelen));
config_auto_slab_values(cfg);
slab = infra_create(cfg);
unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now,
&vs, &edns_lame, &to) );
unit_assert( vs == 0 && to == init && edns_lame == 0 );
unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, LDNS_RR_TYPE_A, -1, init, now) );
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
now, &vs, &edns_lame, &to) );
unit_assert( vs == 0 && to == init*2 && edns_lame == 0 );
unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) );
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
now, &vs, &edns_lame, &to) );
unit_assert( vs == -1 && to == init*2 && edns_lame == 1);
now += cfg->host_ttl + 10;
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
now, &vs, &edns_lame, &to) );
unit_assert( vs == 0 && to == init && edns_lame == 0 );
unit_assert( infra_set_lame(slab, &one, onelen,
zone, zonelen, now, 0, 0, LDNS_RR_TYPE_A) );
unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) );
unit_assert( d->ttl == now+cfg->host_ttl );
unit_assert( d->edns_version == 0 );
unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A &&
!d->lame_other);
lock_rw_unlock(&k->entry.lock);
unit_assert( infra_set_lame(slab, &one, onelen,
zone, zonelen, now, 0, 0, LDNS_RR_TYPE_AAAA) );
unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) );
unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A &&
d->lame_other);
lock_rw_unlock(&k->entry.lock);
now += cfg->host_ttl + 10;
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
now, &vs, &edns_lame, &to) );
unit_assert( vs == 0 && to == init && edns_lame == 0 );
unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, 0, now) );
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
now, &vs, &edns_lame, &to) );
unit_assert( vs == 0 && to == init && edns_lame == 1 );
unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) );
unit_assert( infra_host(slab, &one, onelen, zone, zonelen,
now, &vs, &edns_lame, &to) );
unit_assert( vs == 0 && to == init && edns_lame == 1 );
unit_show_feature("infra cache probing (keep-probing off, default infra-cache-max-rtt)");
test_keep_probing(slab, cfg, one, onelen, zone, zonelen, &now, 0, default_max_rtt);
unit_show_feature("infra cache probing (keep-probing on, default infra-cache-max-rtt)");
test_keep_probing(slab, cfg, one, onelen, zone, zonelen, &now, 1, default_max_rtt);
unit_show_feature("infra cache probing (keep-probing off, low infra-cache-max-rtt)");
test_keep_probing(slab, cfg, one, onelen, zone, zonelen, &now, 0, 3000);
unit_show_feature("infra cache probing (keep-probing on, low infra-cache-max-rtt)");
test_keep_probing(slab, cfg, one, onelen, zone, zonelen, &now, 1, 3000);
config_apply_max_rtt(default_max_rtt);
infra_delete(slab);
config_delete(cfg);
}