Exemple #1
0
/** performance test message encoding */
static void
perf_encode(struct query_info* qi, struct reply_info* rep, uint16_t id, 
	uint16_t flags, sldns_buffer* out, time_t timenow, 
	struct edns_data* edns)
{
	static int num = 0;
	int ret;
	size_t max = 10000;
	size_t i;
	struct timeval start, end;
	double dt;
	struct regional* r2 = regional_create();
	if(gettimeofday(&start, NULL) < 0)
		fatal_exit("gettimeofday: %s", strerror(errno));
	/* encode a couple times */
	for(i=0; i<max; i++) {
		ret = reply_info_encode(qi, rep, id, flags, out, timenow,
			r2, 65535, (int)(edns->bits & EDNS_DO) );
		unit_assert(ret != 0); /* udp packets should fit */
		attach_edns_record(out, edns);
		regional_free_all(r2);
	}
	if(gettimeofday(&end, NULL) < 0)
		fatal_exit("gettimeofday: %s", strerror(errno));
	/* time in millisec */
	dt = (double)(end.tv_sec - start.tv_sec)*1000. + 
		((double)end.tv_usec - (double)start.tv_usec)/1000.;
	printf("[%d] did %u in %g msec for %f encode/sec size %d\n", num++,
		(unsigned)max, dt, (double)max / (dt/1000.), 
		(int)sldns_buffer_limit(out));
	regional_destroy(r2);
}
Exemple #2
0
void 
log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep)
{
	/* not particularly fast but flexible, make wireformat and print */
	ldns_buffer* buf = ldns_buffer_new(65535);
	struct regional* region = regional_create();
	if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0, 
		region, 65535, 1)) {
		log_info("%s: log_dns_msg: out of memory", str);
	} else {
		ldns_status s;
		ldns_pkt* pkt = NULL;
		s = ldns_buffer2pkt_wire(&pkt, buf);
		if(s != LDNS_STATUS_OK) {
			log_info("%s: log_dns_msg: ldns parse gave: %s",
				str, ldns_get_errorstr_by_id(s));
		} else {
			ldns_buffer_clear(buf);
			s = ldns_pkt2buffer_str(buf, pkt);
			if(s != LDNS_STATUS_OK) {
				log_info("%s: log_dns_msg: ldns tostr gave: %s",
					str, ldns_get_errorstr_by_id(s));
			} else {
				log_info("%s %s", 
					str, (char*)ldns_buffer_begin(buf));
			}
		}
		ldns_pkt_free(pkt);
	}
	ldns_buffer_free(buf);
	regional_destroy(region);
}
Exemple #3
0
/** perf test a packet */
static void
perftestpkt(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out, 
	const char* hex)
{
	struct query_info qi;
	struct reply_info* rep = 0;
	int ret;
	uint16_t id;
	uint16_t flags;
	time_t timenow = 0;
	struct regional* region = regional_create();
	struct edns_data edns;

	hex_to_buf(pkt, hex);
	memmove(&id, sldns_buffer_begin(pkt), sizeof(id));
	if(sldns_buffer_limit(pkt) < 2)
		flags = 0;
	else	memmove(&flags, sldns_buffer_at(pkt, 2), sizeof(flags));
	flags = ntohs(flags);
	ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
	if(ret != 0) {
		char rbuf[16];
		sldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
		if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
		if(ret == LDNS_RCODE_FORMERR)
			checkformerr(pkt);
		unit_assert(ret != LDNS_RCODE_SERVFAIL);
	} else {
		perf_encode(&qi, rep, id, flags, out, timenow, &edns);
	} 

	query_info_clear(&qi);
	reply_info_parsedelete(rep, alloc);
	regional_destroy(region);
}
/** verify DS matches DNSKEY from a file */
static void
dstest_file(const char* fname)
{
	/* 
	 * The file contains a list of ldns-testpkts entries.
	 * The first entry must be a query for DNSKEY.
	 * The answer rrset is the keyset that will be used for verification
	 */
	struct regional* region = regional_create();
	struct alloc_cache alloc;
	ldns_buffer* buf = ldns_buffer_new(65535);
	struct entry* e;
	struct entry* list = read_datafile(fname);
	struct module_env env;

	if(!list)
		fatal_exit("could not read %s: %s", fname, strerror(errno));
	alloc_init(&alloc, NULL, 1);
	memset(&env, 0, sizeof(env));
	env.scratch = region;
	env.scratch_buffer = buf;
	unit_assert(region && buf);

	/* ready to go! */
	for(e = list; e; e = e->next) {
		dstest_entry(e, &alloc, region, buf, &env);
	}

	delete_entry(list);
	regional_destroy(region);
	alloc_clear(&alloc);
	ldns_buffer_free(buf);
}
Exemple #5
0
void 
acl_list_delete(struct acl_list* acl)
{
	if(!acl) 
		return;
	regional_destroy(acl->region);
	free(acl);
}
Exemple #6
0
void
respip_set_delete(struct respip_set* set)
{
	if(!set)
		return;
	regional_destroy(set->region);
	free(set);
}
Exemple #7
0
void 
local_zone_delete(struct local_zone* z)
{
	if(!z)
		return;
	lock_rw_destroy(&z->lock);
	regional_destroy(z->region);
	free(z->name);
	free(z->taglist);
	free(z);
}
Exemple #8
0
void 
alloc_reg_release(struct alloc_cache* alloc, struct regional* r)
{
	if(alloc->num_reg_blocks >= alloc->max_reg_blocks) {
		regional_destroy(r);
		return;
	}
	if(!r) return;
	regional_free_all(r);
	log_assert(r->next == NULL);
	r->next = (char*)alloc->reg_list;
	alloc->reg_list = r;
	alloc->num_reg_blocks++;
}
Exemple #9
0
void 
anchors_delete(struct val_anchors* anchors)
{
	if(!anchors)
		return;
	lock_unprotect(&anchors->lock, anchors->autr);
	lock_unprotect(&anchors->lock, anchors);
	lock_basic_destroy(&anchors->lock);
	traverse_postorder(anchors->tree, anchors_delfunc, NULL);
	free(anchors->tree);
	regional_destroy(anchors->region);
	autr_global_delete(anchors->autr);
	free(anchors);
}
Exemple #10
0
/** check if module works with config */
static void
check_mod(struct config_file* cfg, struct module_func_block* fb)
{
	struct module_env env;
	memset(&env, 0, sizeof(env));
	env.cfg = cfg;
	env.scratch = regional_create();
	env.scratch_buffer = ldns_buffer_new(BUFSIZ);
	if(!env.scratch || !env.scratch_buffer)
		fatal_exit("out of memory");
	if(!(*fb->init)(&env, 0)) {
		fatal_exit("bad config for %s module", fb->name);
	}
	(*fb->deinit)(&env, 0);
	ldns_buffer_free(env.scratch_buffer);
	regional_destroy(env.scratch);
}
/** verify from a file */
static void
verifytest_file(const char* fname, const char* at_date)
{
	/* 
	 * The file contains a list of ldns-testpkts entries.
	 * The first entry must be a query for DNSKEY.
	 * The answer rrset is the keyset that will be used for verification
	 */
	struct ub_packed_rrset_key* dnskey;
	struct regional* region = regional_create();
	struct alloc_cache alloc;
	ldns_buffer* buf = ldns_buffer_new(65535);
	struct entry* e;
	struct entry* list = read_datafile(fname);
	struct module_env env;
	struct val_env ve;
	uint32_t now = time(NULL);

	if(!list)
		fatal_exit("could not read %s: %s", fname, strerror(errno));
	alloc_init(&alloc, NULL, 1);
	memset(&env, 0, sizeof(env));
	memset(&ve, 0, sizeof(ve));
	env.scratch = region;
	env.scratch_buffer = buf;
	env.now = &now;
	ve.date_override = cfg_convert_timeval(at_date);
	unit_assert(region && buf);
	dnskey = extract_keys(list, &alloc, region, buf);
	if(vsig) log_nametypeclass(VERB_QUERY, "test dnskey",
			dnskey->rk.dname, ntohs(dnskey->rk.type), 
			ntohs(dnskey->rk.rrset_class));
	/* ready to go! */
	for(e = list->next; e; e = e->next) {
		verifytest_entry(e, &alloc, region, buf, dnskey, &env, &ve);
	}

	ub_packed_rrset_parsedelete(dnskey, &alloc);
	delete_entry(list);
	regional_destroy(region);
	alloc_clear(&alloc);
	ldns_buffer_free(buf);
}
Exemple #12
0
/** delete libworker env */
static void
libworker_delete_env(struct libworker* w)
{
	if(w->env) {
		outside_network_quit_prepare(w->back);
		mesh_delete(w->env->mesh);
		context_release_alloc(w->ctx, w->env->alloc, 
			!w->is_bg || w->is_bg_thread);
		sldns_buffer_free(w->env->scratch_buffer);
		regional_destroy(w->env->scratch);
		forwards_delete(w->env->fwds);
		hints_delete(w->env->hints);
		ub_randfree(w->env->rnd);
		free(w->env);
	}
#ifdef HAVE_SSL
	SSL_CTX_free(w->sslctx);
#endif
	outside_network_delete(w->back);
}
Exemple #13
0
/** delete libworker struct */
static void
libworker_delete(struct libworker* w)
{
	if(!w) return;
	if(w->env) {
		outside_network_quit_prepare(w->back);
		mesh_delete(w->env->mesh);
		context_release_alloc(w->ctx, w->env->alloc, 
			!w->is_bg || w->is_bg_thread);
		ldns_buffer_free(w->env->scratch_buffer);
		regional_destroy(w->env->scratch);
		forwards_delete(w->env->fwds);
		ub_randfree(w->env->rnd);
		free(w->env);
	}
	SSL_CTX_free(w->sslctx);
	outside_network_delete(w->back);
	comm_base_delete(w->base);
	free(w);
}
Exemple #14
0
void 
log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep)
{
	/* not particularly fast but flexible, make wireformat and print */
	sldns_buffer* buf = sldns_buffer_new(65535);
	struct regional* region = regional_create();
	if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0, 
		region, 65535, 1)) {
		log_info("%s: log_dns_msg: out of memory", str);
	} else {
		char* s = sldns_wire2str_pkt(sldns_buffer_begin(buf),
			sldns_buffer_limit(buf));
		if(!s) {
			log_info("%s: log_dns_msg: ldns tostr failed", str);
		} else {
			log_info("%s %s", str, s);
		}
		free(s);
	}
	sldns_buffer_free(buf);
	regional_destroy(region);
}
/** Read file to test NSEC3 hash algo */
static void
nsec3_hash_test(const char* fname)
{
	/* 
	 * The list contains a list of ldns-testpkts entries.
	 * Every entry is a test.
	 * 	The qname is hashed.
	 * 	The answer section AAAA RR name is the required result.
	 * 	The auth section NSEC3 is used to get hash parameters.
	 * The hash cache is maintained per file.
	 *
	 * The test does not perform canonicalization during the compare.
	 */
	rbtree_t ct;
	struct regional* region = regional_create();
	struct alloc_cache alloc;
	ldns_buffer* buf = ldns_buffer_new(65535);
	struct entry* e;
	struct entry* list = read_datafile(fname);

	if(!list)
		fatal_exit("could not read %s: %s", fname, strerror(errno));
	rbtree_init(&ct, &nsec3_hash_cmp);
	alloc_init(&alloc, NULL, 1);
	unit_assert(region && buf);

	/* ready to go! */
	for(e = list; e; e = e->next) {
		nsec3_hash_test_entry(e, &ct, &alloc, region, buf);
	}

	delete_entry(list);
	regional_destroy(region);
	alloc_clear(&alloc);
	ldns_buffer_free(buf);
}
Exemple #16
0
/** process answer from bg worker */
static int
process_answer_detail(struct ub_ctx* ctx, uint8_t* msg, uint32_t len,
                      ub_callback_t* cb, void** cbarg, int* err,
                      struct ub_result** res)
{
    struct ctx_query* q;
    if(context_serial_getcmd(msg, len) != UB_LIBCMD_ANSWER) {
        log_err("error: bad data from bg worker %d",
                (int)context_serial_getcmd(msg, len));
        return 0;
    }

    lock_basic_lock(&ctx->cfglock);
    q = context_deserialize_answer(ctx, msg, len, err);
    if(!q) {
        lock_basic_unlock(&ctx->cfglock);
        /* probably simply the lookup that failed, i.e.
         * response returned before cancel was sent out, so noerror */
        return 1;
    }
    log_assert(q->async);

    /* grab cb while locked */
    if(q->cancelled) {
        *cb = NULL;
        *cbarg = NULL;
    } else {
        *cb = q->cb;
        *cbarg = q->cb_arg;
    }
    if(*err) {
        *res = NULL;
        ub_resolve_free(q->res);
    } else {
        /* parse the message, extract rcode, fill result */
        ldns_buffer* buf = ldns_buffer_new(q->msg_len);
        struct regional* region = regional_create();
        *res = q->res;
        (*res)->rcode = LDNS_RCODE_SERVFAIL;
        if(region && buf) {
            ldns_buffer_clear(buf);
            ldns_buffer_write(buf, q->msg, q->msg_len);
            ldns_buffer_flip(buf);
            libworker_enter_result(*res, buf, region,
                                   q->msg_security);
        }
        (*res)->answer_packet = q->msg;
        (*res)->answer_len = (int)q->msg_len;
        q->msg = NULL;
        ldns_buffer_free(buf);
        regional_destroy(region);
    }
    q->res = NULL;
    /* delete the q from list */
    (void)rbtree_delete(&ctx->queries, q->node.key);
    ctx->num_async--;
    context_query_delete(q);
    lock_basic_unlock(&ctx->cfglock);

    if(*cb) return 2;
    ub_resolve_free(*res);
    return 1;
}
Exemple #17
0
/** test a packet */
static void
testpkt(sldns_buffer* pkt, struct alloc_cache* alloc, sldns_buffer* out, 
	const char* hex)
{
	struct query_info qi;
	struct reply_info* rep = 0;
	int ret;
	uint16_t id;
	uint16_t flags;
	uint32_t timenow = 0;
	struct regional* region = regional_create();
	struct edns_data edns;

	hex_to_buf(pkt, hex);
	memmove(&id, sldns_buffer_begin(pkt), sizeof(id));
	if(sldns_buffer_limit(pkt) < 2)
		flags = 0;
	else	memmove(&flags, sldns_buffer_at(pkt, 2), sizeof(flags));
	flags = ntohs(flags);
	ret = reply_info_parse(pkt, alloc, &qi, &rep, region, &edns);
	if(ret != 0) {
		char rbuf[16];
		sldns_wire2str_rcode_buf(ret, rbuf, sizeof(rbuf));
		if(vbmp) printf("parse code %d: %s\n", ret, rbuf);
		if(ret == LDNS_RCODE_FORMERR) {
			unit_assert(!check_formerr_gone);
			checkformerr(pkt);
		}
		unit_assert(ret != LDNS_RCODE_SERVFAIL);
	} else if(!check_formerr_gone) {
		const size_t lim = 512;
		ret = reply_info_encode(&qi, rep, id, flags, out, timenow,
			region, 65535, (int)(edns.bits & EDNS_DO) );
		unit_assert(ret != 0); /* udp packets should fit */
		attach_edns_record(out, &edns);
		if(vbmp) printf("inlen %u outlen %u\n", 
			(unsigned)sldns_buffer_limit(pkt),
			(unsigned)sldns_buffer_limit(out));
		if(!check_nosameness)
			test_buffers(pkt, out);
		if(check_rrsigs)
			check_the_rrsigs(&qi, rep);

		if(sldns_buffer_limit(out) > lim) {
			ret = reply_info_encode(&qi, rep, id, flags, out, 
				timenow, region, 
				lim - calc_edns_field_size(&edns),
				(int)(edns.bits & EDNS_DO));
			unit_assert(ret != 0); /* should fit, but with TC */
			attach_edns_record(out, &edns);
			if( LDNS_QDCOUNT(sldns_buffer_begin(out)) !=
				LDNS_QDCOUNT(sldns_buffer_begin(pkt)) ||
				LDNS_ANCOUNT(sldns_buffer_begin(out)) !=
				LDNS_ANCOUNT(sldns_buffer_begin(pkt)) ||
				LDNS_NSCOUNT(sldns_buffer_begin(out)) !=
				LDNS_NSCOUNT(sldns_buffer_begin(pkt)))
				unit_assert(
				LDNS_TC_WIRE(sldns_buffer_begin(out)));
				/* must set TC bit if shortened */
			unit_assert(sldns_buffer_limit(out) <= lim);
		}
	} 

	query_info_clear(&qi);
	reply_info_parsedelete(rep, alloc);
	regional_destroy(region);
}