Beispiel #1
0
/** setup qinfo and edns */
static int
setup_qinfo_edns(struct libworker* w, struct ctx_query* q, 
	struct query_info* qinfo, struct edns_data* edns)
{
	ldns_rdf* rdf;
	qinfo->qtype = (uint16_t)q->res->qtype;
	qinfo->qclass = (uint16_t)q->res->qclass;
	rdf = ldns_dname_new_frm_str(q->res->qname);
	if(!rdf) {
		return 0;
	}
#ifdef UNBOUND_ALLOC_LITE
	qinfo->qname = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf));
	qinfo->qname_len = ldns_rdf_size(rdf);
	ldns_rdf_deep_free(rdf);
	rdf = 0;
#else
	qinfo->qname = ldns_rdf_data(rdf);
	qinfo->qname_len = ldns_rdf_size(rdf);
#endif
	edns->edns_present = 1;
	edns->ext_rcode = 0;
	edns->edns_version = 0;
	edns->bits = EDNS_DO;
	if(ldns_buffer_capacity(w->back->udp_buff) < 65535)
		edns->udp_size = (uint16_t)ldns_buffer_capacity(
			w->back->udp_buff);
	else	edns->udp_size = 65535;
	ldns_rdf_free(rdf);
	return 1;
}
Beispiel #2
0
void 
ldns_buffer_copy(ldns_buffer* result, ldns_buffer* from)
{
	size_t tocopy = ldns_buffer_limit(from);

	if(tocopy > ldns_buffer_capacity(result))
		tocopy = ldns_buffer_capacity(result);
	ldns_buffer_clear(result);
	ldns_buffer_write(result, ldns_buffer_begin(from), tocopy);
	ldns_buffer_flip(result);
}
Beispiel #3
0
static int
l_pkt2string(lua_State *L)
{
	ldns_buffer *b;
	luaL_Buffer lua_b;
	ldns_pkt *p = (ldns_pkt *)lua_touserdata(L, 1);

	if (!p) {
		return 0;
	}

	b = ldns_buffer_new(LDNS_MAX_PACKETLEN);
	luaL_buffinit(L,&lua_b);

	if (ldns_pkt2buffer_wire(b, p) != LDNS_STATUS_OK) {
		ldns_buffer_free(b);
		return 0;
	}
	/* this is a memcpy??? */
	luaL_addlstring(&lua_b,
			(char*)ldns_buffer_begin(b),
			ldns_buffer_capacity(b)
		       );
	/* I hope so */
	ldns_buffer_free(b); 

	luaL_pushresult(&lua_b);
	return 1;
}
Beispiel #4
0
size_t listen_get_mem(struct listen_dnsport* listen)
{
	size_t s = sizeof(*listen) + sizeof(*listen->base) + 
		sizeof(*listen->udp_buff) + 
		ldns_buffer_capacity(listen->udp_buff);
	struct listen_list* p;
	for(p = listen->cps; p; p = p->next) {
		s += sizeof(*p);
		s += comm_point_get_mem(p->com);
	}
	return s;
}
Beispiel #5
0
size_t 
mesh_get_mem(struct mesh_area* mesh)
{
	struct mesh_state* m;
	size_t s = sizeof(*mesh) + sizeof(struct timehist) +
		sizeof(struct th_buck)*mesh->histogram->num +
		sizeof(ldns_buffer) + ldns_buffer_capacity(mesh->qbuf_bak);
	RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
		/* all, including m itself allocated in qstate region */
		s += regional_get_mem(m->s.region);
	}
	return s;
}
Beispiel #6
0
static int
l_buf_info(lua_State *L)
{
	ldns_buffer *b = (ldns_buffer *)lua_touserdata(L, 1);
	if (!b) {
		return 0;
	}
	printf("capacity %d; position %d; limit %d\n",
			ldns_buffer_capacity(b),
			ldns_buffer_position(b),
			ldns_buffer_limit(b));
	return 0;
}
struct waiting_tcp* 
pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet,
	struct sockaddr_storage* addr, socklen_t addrlen, int timeout,
	comm_point_callback_t* callback, void* callback_arg)
{
	struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
	struct fake_pending* pend = (struct fake_pending*)calloc(1,
		sizeof(struct fake_pending));
	ldns_status status;
	log_assert(pend);
	pend->buffer = ldns_buffer_new(ldns_buffer_capacity(packet));
	log_assert(pend->buffer);
	ldns_buffer_write(pend->buffer, ldns_buffer_begin(packet),
		ldns_buffer_limit(packet));
	ldns_buffer_flip(pend->buffer);
	memcpy(&pend->addr, addr, addrlen);
	pend->addrlen = addrlen;
	pend->callback = callback;
	pend->cb_arg = callback_arg;
	pend->timeout = timeout;
	pend->transport = transport_tcp;
	pend->pkt = NULL;
	pend->runtime = runtime;
	pend->serviced = 0;
	status = ldns_buffer2pkt_wire(&pend->pkt, packet);
	if(status != LDNS_STATUS_OK) {
		log_err("ldns error parsing tcp output packet: %s",
			ldns_get_errorstr_by_id(status));
		fatal_exit("Sending unparseable DNS packets to servers!");
	}
	log_pkt("pending tcp pkt: ", pend->pkt);

	/* see if it matches the current moment */
	if(runtime->now && runtime->now->evt_type == repevt_back_query &&
		(runtime->now->addrlen == 0 || sockaddr_cmp(
			&runtime->now->addr, runtime->now->addrlen,
			&pend->addr, pend->addrlen) == 0) &&
		find_match(runtime->now->match, pend->pkt, pend->transport)) {
		log_info("testbound: matched pending to event. "
			"advance time between events.");
		log_info("testbound: do STEP %d %s", runtime->now->time_step,
			repevt_string(runtime->now->evt_type));
		advance_moment(runtime);
		/* still create the pending, because we need it to callback */
	} 
	log_info("testbound: created fake pending");
	/* add to list */
	pend->next = runtime->pending_list;
	runtime->pending_list = pend;
	return (struct waiting_tcp*)pend;
}
Beispiel #8
0
ldns_buffer *
read_hex_buffer(char *filename)
{
	uint8_t *wire;
	size_t wiresize;
	ldns_buffer *result_buffer = NULL;
	

	wire = xmalloc(LDNS_MAX_PACKETLEN);
	
	wiresize = packetbuffromfile(filename, wire);
	
	result_buffer = LDNS_MALLOC(ldns_buffer);
	ldns_buffer_new_frm_data(result_buffer, wire, wiresize);
	ldns_buffer_set_position(result_buffer, ldns_buffer_capacity(result_buffer));
	xfree(wire);

	return result_buffer;
}
Beispiel #9
0
/** Report on memory usage by this thread and global */
static void
worker_mem_report(struct worker* ATTR_UNUSED(worker), 
	struct serviced_query* ATTR_UNUSED(cur_serv))
{
#ifdef UNBOUND_ALLOC_STATS
	/* debug func in validator module */
	size_t total, front, back, mesh, msg, rrset, infra, ac, superac;
	size_t me, iter, val, anch;
	int i;
	if(verbosity < VERB_ALGO) 
		return;
	front = listen_get_mem(worker->front);
	back = outnet_get_mem(worker->back);
	msg = slabhash_get_mem(worker->env.msg_cache);
	rrset = slabhash_get_mem(&worker->env.rrset_cache->table);
	infra = infra_get_mem(worker->env.infra_cache);
	mesh = mesh_get_mem(worker->env.mesh);
	ac = alloc_get_mem(&worker->alloc);
	superac = alloc_get_mem(&worker->daemon->superalloc);
	anch = anchors_get_mem(worker->env.anchors);
	iter = 0;
	val = 0;
	for(i=0; i<worker->env.mesh->mods.num; i++) {
		fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
			mods.mod[i]->get_mem));
		if(strcmp(worker->env.mesh->mods.mod[i]->name, "validator")==0)
			val += (*worker->env.mesh->mods.mod[i]->get_mem)
				(&worker->env, i);
		else	iter += (*worker->env.mesh->mods.mod[i]->get_mem)
				(&worker->env, i);
	}
	me = sizeof(*worker) + sizeof(*worker->base) + sizeof(*worker->comsig)
		+ comm_point_get_mem(worker->cmd_com) 
		+ sizeof(worker->rndstate) 
		+ regional_get_mem(worker->scratchpad) 
		+ sizeof(*worker->env.scratch_buffer) 
		+ ldns_buffer_capacity(worker->env.scratch_buffer)
		+ forwards_get_mem(worker->env.fwds)
		+ hints_get_mem(worker->env.hints);
	if(worker->thread_num == 0)
		me += acl_list_get_mem(worker->daemon->acl);
	if(cur_serv) {
		me += serviced_get_mem(cur_serv);
	}
	total = front+back+mesh+msg+rrset+infra+iter+val+ac+superac+me;
	log_info("Memory conditions: %u front=%u back=%u mesh=%u msg=%u "
		"rrset=%u infra=%u iter=%u val=%u anchors=%u "
		"alloccache=%u globalalloccache=%u me=%u",
		(unsigned)total, (unsigned)front, (unsigned)back, 
		(unsigned)mesh, (unsigned)msg, (unsigned)rrset, 
		(unsigned)infra, (unsigned)iter, (unsigned)val, (unsigned)anch,
		(unsigned)ac, (unsigned)superac, (unsigned)me);
	debug_total_mem(total);
#else /* no UNBOUND_ALLOC_STATS */
	size_t val = 0;
	int i;
	if(verbosity < VERB_QUERY)
		return;
	for(i=0; i<worker->env.mesh->mods.num; i++) {
		fptr_ok(fptr_whitelist_mod_get_mem(worker->env.mesh->
			mods.mod[i]->get_mem));
		if(strcmp(worker->env.mesh->mods.mod[i]->name, "validator")==0)
			val += (*worker->env.mesh->mods.mod[i]->get_mem)
				(&worker->env, i);
	}
	verbose(VERB_QUERY, "cache memory msg=%u rrset=%u infra=%u val=%u",
		(unsigned)slabhash_get_mem(worker->env.msg_cache),
		(unsigned)slabhash_get_mem(&worker->env.rrset_cache->table),
		(unsigned)infra_get_mem(worker->env.infra_cache),
		(unsigned)val);
#endif /* UNBOUND_ALLOC_STATS */
}
Beispiel #10
0
/** read a line from ssl into buffer */
static int
ssl_read_buf(SSL* ssl, ldns_buffer* buf)
{
	return ssl_read_line(ssl, (char*)ldns_buffer_begin(buf), 
		ldns_buffer_capacity(buf));
}
Beispiel #11
0
/*
 * Parses data buffer to a query, finds the correct answer 
 * and calls the given function for every packet to send.
 */
void
handle_query(uint8_t* inbuf, ssize_t inlen, struct entry* entries, int* count,
	enum transport_type transport, void (*sendfunc)(uint8_t*, size_t, void*),
	void* userdata, FILE* verbose_out)
{
	ldns_status status;
	ldns_pkt *query_pkt = NULL;
	ldns_pkt *answer_pkt = NULL;
	struct reply_packet *p;
	ldns_rr *query_rr = NULL;
	uint8_t *outbuf = NULL;
	size_t answer_size = 0;
	struct entry* entry = NULL;
	ldns_rdf *stop_command = ldns_dname_new_frm_str("server.stop.");

	status = ldns_wire2pkt(&query_pkt, inbuf, (size_t)inlen);
	if (status != LDNS_STATUS_OK) {
		verbose(1, "Got bad packet: %s\n", ldns_get_errorstr_by_id(status));
		ldns_rdf_free(stop_command);
		return;
	}
	
	query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0);
	verbose(1, "query %d: id %d: %s %d bytes: ", ++(*count), (int)ldns_pkt_id(query_pkt), 
		(transport==transport_tcp)?"TCP":"UDP", (int)inlen);
	if(verbose_out) ldns_rr_print(verbose_out, query_rr);
	if(verbose_out) ldns_pkt_print(verbose_out, query_pkt);

	if (ldns_rr_get_type(query_rr) == LDNS_RR_TYPE_TXT &&
	    ldns_rr_get_class(query_rr) == LDNS_RR_CLASS_CH &&
	    ldns_dname_compare(ldns_rr_owner(query_rr), stop_command) == 0) {
		exit(0);
        }
	
	/* fill up answer packet */
	entry = find_match(entries, query_pkt, transport);
	if(!entry || !entry->reply_list) {
		verbose(1, "no answer packet for this query, no reply.\n");
		ldns_pkt_free(query_pkt);
		ldns_rdf_free(stop_command);
		return;
	}
	for(p = entry->reply_list; p; p = p->next)
	{
		verbose(3, "Answer pkt:\n");
		if (p->reply_from_hex) {
			/* try to parse the hex packet, if it can be
			 * parsed, we can use adjust rules. if not,
			 * send packet literally */
			status = ldns_buffer2pkt_wire(&answer_pkt, p->reply_from_hex);
			if (status == LDNS_STATUS_OK) {
				adjust_packet(entry, answer_pkt, query_pkt);
				if(verbose_out) ldns_pkt_print(verbose_out, answer_pkt);
				status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size);
				verbose(2, "Answer packet size: %u bytes.\n", (unsigned int)answer_size);
				if (status != LDNS_STATUS_OK) {
					verbose(1, "Error creating answer: %s\n", ldns_get_errorstr_by_id(status));
					ldns_pkt_free(query_pkt);
					ldns_rdf_free(stop_command);
					return;
				}
				ldns_pkt_free(answer_pkt);
				answer_pkt = NULL;
			} else {
				verbose(3, "Could not parse hex data (%s), sending hex data directly.\n", ldns_get_errorstr_by_id(status));
				/* still try to adjust ID */
				answer_size = ldns_buffer_capacity(p->reply_from_hex);
				outbuf = LDNS_XMALLOC(uint8_t, answer_size);
				memcpy(outbuf, ldns_buffer_export(p->reply_from_hex), answer_size);
				if(entry->copy_id) {
					ldns_write_uint16(outbuf, 
						ldns_pkt_id(query_pkt));
				}
			}
		} else {
			answer_pkt = ldns_pkt_clone(p->reply);
			adjust_packet(entry, answer_pkt, query_pkt);
			if(verbose_out) ldns_pkt_print(verbose_out, answer_pkt);
			status = ldns_pkt2wire(&outbuf, answer_pkt, &answer_size);
			verbose(1, "Answer packet size: %u bytes.\n", (unsigned int)answer_size);
			if (status != LDNS_STATUS_OK) {
				verbose(1, "Error creating answer: %s\n", ldns_get_errorstr_by_id(status));
				ldns_pkt_free(query_pkt);
				ldns_rdf_free(stop_command);
				return;
			}
			ldns_pkt_free(answer_pkt);
			answer_pkt = NULL;
		}
		if(p->packet_sleep) {
			verbose(3, "sleeping for next packet %d secs\n", 
				p->packet_sleep);
#ifdef HAVE_SLEEP
			sleep(p->packet_sleep);
#else
			Sleep(p->packet_sleep * 1000);
#endif
			verbose(3, "wakeup for next packet "
				"(slept %d secs)\n", p->packet_sleep);
		}
		sendfunc(outbuf, answer_size, userdata);
		LDNS_FREE(outbuf);
		outbuf = NULL;
		answer_size = 0;
	}
	ldns_pkt_free(query_pkt);
	ldns_rdf_free(stop_command);
}