Пример #1
0
/** compress owner name of RR, return RETVAL_OUTMEM RETVAL_TRUNC */
static int
compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt, 
	struct regional* region, struct compress_tree_node** tree, 
	size_t owner_pos, uint16_t* owner_ptr, int owner_labs)
{
	struct compress_tree_node* p;
	struct compress_tree_node** insertpt = NULL;
	if(!*owner_ptr) {
		/* compress first time dname */
		if((p = compress_tree_lookup(tree, key->rk.dname, 
			owner_labs, &insertpt))) {
			if(p->labs == owner_labs) 
				/* avoid ptr chains, since some software is
				 * not capable of decoding ptr after a ptr. */
				*owner_ptr = htons(PTR_CREATE(p->offset));
			if(!write_compressed_dname(pkt, key->rk.dname, 
				owner_labs, p))
				return RETVAL_TRUNC;
			/* check if typeclass+4 ttl + rdatalen is available */
			if(sldns_buffer_remaining(pkt) < 4+4+2)
				return RETVAL_TRUNC;
		} else {
			/* no compress */
			if(sldns_buffer_remaining(pkt) < key->rk.dname_len+4+4+2)
				return RETVAL_TRUNC;
			sldns_buffer_write(pkt, key->rk.dname, 
				key->rk.dname_len);
			if(owner_pos <= PTR_MAX_OFFSET)
				*owner_ptr = htons(PTR_CREATE(owner_pos));
		}
		if(!compress_tree_store(key->rk.dname, owner_labs, 
			owner_pos, region, p, insertpt))
			return RETVAL_OUTMEM;
	} else {
		/* always compress 2nd-further RRs in RRset */
		if(owner_labs == 1) {
			if(sldns_buffer_remaining(pkt) < 1+4+4+2) 
				return RETVAL_TRUNC;
			sldns_buffer_write_u8(pkt, 0);
		} else {
			if(sldns_buffer_remaining(pkt) < 2+4+4+2) 
				return RETVAL_TRUNC;
			sldns_buffer_write(pkt, owner_ptr, 2);
		}
	}
	return RETVAL_OK;
}
Пример #2
0
/** compress any domain name to the packet, return RETVAL_* */
static int
compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs, 
	struct regional* region, struct compress_tree_node** tree)
{
	struct compress_tree_node* p;
	struct compress_tree_node** insertpt = NULL;
	size_t pos = sldns_buffer_position(pkt);
	if((p = compress_tree_lookup(tree, dname, labs, &insertpt))) {
		if(!write_compressed_dname(pkt, dname, labs, p))
			return RETVAL_TRUNC;
	} else {
		if(!dname_buffer_write(pkt, dname))
			return RETVAL_TRUNC;
	}
	if(!compress_tree_store(dname, labs, pos, region, p, insertpt))
		return RETVAL_OUTMEM;
	return RETVAL_OK;
}
Пример #3
0
/** store query section in wireformat buffer, return RETVAL */
static int
insert_query(struct query_info* qinfo, struct compress_tree_node** tree, 
	ldns_buffer* buffer, struct regional* region)
{
	if(ldns_buffer_remaining(buffer) < 
		qinfo->qname_len+sizeof(uint16_t)*2)
		return RETVAL_TRUNC; /* buffer too small */
	/* the query is the first name inserted into the tree */
	if(!compress_tree_store(qinfo->qname, 
		dname_count_labels(qinfo->qname), 
		ldns_buffer_position(buffer), region, NULL, tree))
		return RETVAL_OUTMEM;
	if(ldns_buffer_current(buffer) == qinfo->qname)
		ldns_buffer_skip(buffer, (ssize_t)qinfo->qname_len);
	else	ldns_buffer_write(buffer, qinfo->qname, qinfo->qname_len);
	ldns_buffer_write_u16(buffer, qinfo->qtype);
	ldns_buffer_write_u16(buffer, qinfo->qclass);
	return RETVAL_OK;
}