Esempio n. 1
0
struct ctx_query* 
context_deserialize_new_query(struct ub_ctx* ctx, uint8_t* p, uint32_t len)
{
	struct ctx_query* q = (struct ctx_query*)calloc(1, sizeof(*q));
	if(!q) return NULL;
	if(len < 4*sizeof(uint32_t)+1) {
		free(q);
		return NULL;
	}
	log_assert( ldns_read_uint32(p) == UB_LIBCMD_NEWQUERY);
	q->querynum = (int)ldns_read_uint32(p+sizeof(uint32_t));
	q->node.key = &q->querynum;
	q->async = 1;
	q->res = (struct ub_result*)calloc(1, sizeof(*q->res));
	if(!q->res) {
		free(q);
		return NULL;
	}
	q->res->qtype = (int)ldns_read_uint32(p+2*sizeof(uint32_t));
	q->res->qclass = (int)ldns_read_uint32(p+3*sizeof(uint32_t));
	q->res->qname = strdup((char*)(p+4*sizeof(uint32_t)));
	if(!q->res->qname) {
		free(q->res);
		free(q);
		return NULL;
	}

	/** add to query list */
	ctx->num_async++;
	(void)rbtree_insert(&ctx->queries, &q->node);
	return q;
}
Esempio n. 2
0
struct ctx_query* context_deserialize_cancel(struct ub_ctx* ctx,
        uint8_t* p, uint32_t len)
{
	struct ctx_query* q;
	int id;
	if(len != 2*sizeof(uint32_t)) return NULL;
	log_assert( ldns_read_uint32(p) == UB_LIBCMD_CANCEL);
	id = (int)ldns_read_uint32(p+sizeof(uint32_t));
	q = (struct ctx_query*)rbtree_search(&ctx->queries, &id);
	return q;
}
Esempio n. 3
0
enum ub_ctx_cmd context_serial_getcmd(uint8_t* p, uint32_t len)
{
	uint32_t v;
	if((size_t)len < sizeof(v))
		return UB_LIBCMD_QUIT;
	v = ldns_read_uint32(p);
	return v;
}
Esempio n. 4
0
struct ctx_query* 
context_lookup_new_query(struct ub_ctx* ctx, uint8_t* p, uint32_t len)
{
	struct ctx_query* q;
	int querynum;
	if(len < 4*sizeof(uint32_t)+1) {
		return NULL;
	}
	log_assert( ldns_read_uint32(p) == UB_LIBCMD_NEWQUERY);
	querynum = (int)ldns_read_uint32(p+sizeof(uint32_t));
	q = (struct ctx_query*)rbtree_search(&ctx->queries, &querynum);
	if(!q) {
		return NULL;
	}
	log_assert(q->async);
	return q;
}
Esempio n. 5
0
struct ctx_query* 
context_deserialize_answer(struct ub_ctx* ctx,
        uint8_t* p, uint32_t len, int* err)
{
	struct ctx_query* q = NULL ;
	int id;
	size_t wlen;
	if(len < 5*sizeof(uint32_t)) return NULL;
	log_assert( ldns_read_uint32(p) == UB_LIBCMD_ANSWER);
	id = (int)ldns_read_uint32(p+sizeof(uint32_t));
	q = (struct ctx_query*)rbtree_search(&ctx->queries, &id);
	if(!q) return NULL; 
	*err = (int)ldns_read_uint32(p+2*sizeof(uint32_t));
	q->msg_security = ldns_read_uint32(p+3*sizeof(uint32_t));
	wlen = (size_t)ldns_read_uint32(p+4*sizeof(uint32_t));
	if(len > 5*sizeof(uint32_t) && wlen > 0) {
		if(len >= 5*sizeof(uint32_t)+wlen)
			q->res->why_bogus = (char*)memdup(
				p+5*sizeof(uint32_t), wlen);
		if(!q->res->why_bogus) {
			/* pass malloc failure to the user callback */
			q->msg_len = 0;
			*err = UB_NOMEM;
			return q;
		}
		q->res->why_bogus[wlen-1] = 0; /* zero terminated for sure */
	}
	if(len > 5*sizeof(uint32_t)+wlen) {
		q->msg_len = len - 5*sizeof(uint32_t) - wlen;
		q->msg = (uint8_t*)memdup(p+5*sizeof(uint32_t)+wlen, 
			q->msg_len);
		if(!q->msg) {
			/* pass malloc failure to the user callback */
			q->msg_len = 0;
			*err = UB_NOMEM;
			return q;
		}
	} 
	return q;
}
Esempio n. 6
0
void 
worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg,
	size_t len, int error, void* arg)
{
	struct worker* worker = (struct worker*)arg;
	enum worker_commands cmd;
	if(error != NETEVENT_NOERROR) {
		free(msg);
		if(error == NETEVENT_CLOSED)
			comm_base_exit(worker->base);
		else	log_info("control event: %d", error);
		return;
	}
	if(len != sizeof(uint32_t)) {
		fatal_exit("bad control msg length %d", (int)len);
	}
	cmd = ldns_read_uint32(msg);
	free(msg);
	switch(cmd) {
	case worker_cmd_quit:
		verbose(VERB_ALGO, "got control cmd quit");
		comm_base_exit(worker->base);
		break;
	case worker_cmd_stats:
		verbose(VERB_ALGO, "got control cmd stats");
		server_stats_reply(worker, 1);
		break;
	case worker_cmd_stats_noreset:
		verbose(VERB_ALGO, "got control cmd stats_noreset");
		server_stats_reply(worker, 0);
		break;
	case worker_cmd_remote:
		verbose(VERB_ALGO, "got control cmd remote");
		daemon_remote_exec(worker);
		break;
	default:
		log_err("bad command %d", (int)cmd);
		break;
	}
}
Esempio n. 7
0
ldns_status
ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
{
	ldns_rr_list *rr_list;
	uint16_t i;
	
	/* edns tmp vars */
	ldns_rr *edns_rr;
	uint8_t edata[4];
	
	(void) ldns_hdr2buffer_wire(buffer, packet);

	rr_list = ldns_pkt_question(packet);
	if (rr_list) {
		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
			(void) ldns_rr2buffer_wire(buffer, 
			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION);
		}
	}
	rr_list = ldns_pkt_answer(packet);
	if (rr_list) {
		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
			(void) ldns_rr2buffer_wire(buffer, 
			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER);
		}
	}
	rr_list = ldns_pkt_authority(packet);
	if (rr_list) {
		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
			(void) ldns_rr2buffer_wire(buffer, 
			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY);
		}
	}
	rr_list = ldns_pkt_additional(packet);
	if (rr_list) {
		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
			(void) ldns_rr2buffer_wire(buffer, 
			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL);
		}
	}
	
	/* add EDNS to additional if it is needed */
	if (ldns_pkt_edns(packet)) {
		edns_rr = ldns_rr_new();
		ldns_rr_set_owner(edns_rr,
				ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "."));
		ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT);
		ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet));
		edata[0] = ldns_pkt_edns_extended_rcode(packet);
		edata[1] = ldns_pkt_edns_version(packet);
		ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet));
		ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata));
		(void)ldns_rr2buffer_wire(buffer, edns_rr, LDNS_SECTION_ADDITIONAL);
		ldns_rr_free(edns_rr);
	}
	
	/* add TSIG to additional if it is there */
	if (ldns_pkt_tsig(packet)) {
		(void) ldns_rr2buffer_wire(buffer,
		                           ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL);
	}
	
	return LDNS_STATUS_OK;
}
Esempio n. 8
0
/** do the rdata copy */
static int
rdata_copy(ldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to, 
	struct rr_parse* rr, uint32_t* rr_ttl, uint16_t type)
{
	uint16_t pkt_len;
	const ldns_rr_descriptor* desc;

	*rr_ttl = ldns_read_uint32(rr->ttl_data);
	/* RFC 2181 Section 8. if msb of ttl is set treat as if zero. */
	if(*rr_ttl & 0x80000000U)
		*rr_ttl = 0;
	if(*rr_ttl < MIN_TTL)
		*rr_ttl = MIN_TTL;
	if(*rr_ttl < data->ttl)
		data->ttl = *rr_ttl;

	if(rr->outside_packet) {
		/* uncompressed already, only needs copy */
		memmove(to, rr->ttl_data+sizeof(uint32_t), rr->size);
		return 1;
	}

	ldns_buffer_set_position(pkt, (size_t)
		(rr->ttl_data - ldns_buffer_begin(pkt) + sizeof(uint32_t)));
	/* insert decompressed size into rdata len stored in memory */
	/* -2 because rdatalen bytes are not included. */
	pkt_len = htons(rr->size - 2);
	memmove(to, &pkt_len, sizeof(uint16_t));
	to += 2;
	/* read packet rdata len */
	pkt_len = ldns_buffer_read_u16(pkt);
	if(ldns_buffer_remaining(pkt) < pkt_len)
		return 0;
	desc = ldns_rr_descript(type);
	if(pkt_len > 0 && desc && desc->_dname_count > 0) {
		int count = (int)desc->_dname_count;
		int rdf = 0;
		size_t len;
		size_t oldpos;
		/* decompress dnames. */
		while(pkt_len > 0 && count) {
			switch(desc->_wireformat[rdf]) {
			case LDNS_RDF_TYPE_DNAME:
				oldpos = ldns_buffer_position(pkt);
				dname_pkt_copy(pkt, to, 
					ldns_buffer_current(pkt));
				to += pkt_dname_len(pkt);
				pkt_len -= ldns_buffer_position(pkt)-oldpos;
				count--;
				len = 0;
				break;
			case LDNS_RDF_TYPE_STR:
				len = ldns_buffer_current(pkt)[0] + 1;
				break;
			default:
				len = get_rdf_size(desc->_wireformat[rdf]);
				break;
			}
			if(len) {
				memmove(to, ldns_buffer_current(pkt), len);
				to += len;
				ldns_buffer_skip(pkt, (ssize_t)len);
				log_assert(len <= pkt_len);
				pkt_len -= len;
			}
			rdf++;
		}
	}
	/* copy remaining rdata */
	if(pkt_len >  0)
		memmove(to, ldns_buffer_current(pkt), pkt_len);
	
	return 1;
}