Exemplo n.º 1
0
const dname_type *
dname_replace(region_type* region,
		const dname_type* name,
		const dname_type* src,
		const dname_type* dest)
{
	/* nomenclature: name is said to be <x>.<src>. x can be null. */
	dname_type* res;
	int x_labels = name->label_count - src->label_count;
	int x_len = name->name_size - src->name_size;
	int i;
	assert(dname_is_subdomain(name, src));

	/* check if final size is acceptable */
	if(x_len+dest->name_size > MAXDOMAINLEN)
		return NULL;

	res = (dname_type*)region_alloc(region, sizeof(dname_type) +
		(x_labels+dest->label_count + x_len+dest->name_size)
		*sizeof(uint8_t));
	res->name_size = x_len+dest->name_size;
	res->label_count = x_labels+dest->label_count;
	for(i=0; i<dest->label_count; i++)
		((uint8_t*)dname_label_offsets(res))[i] =
			dname_label_offsets(dest)[i] + x_len;
	for(i=dest->label_count; i<res->label_count; i++)
		((uint8_t*)dname_label_offsets(res))[i] =
			dname_label_offsets(name)[i - dest->label_count +
				src->label_count];
	memcpy((uint8_t*)dname_name(res), dname_name(name), x_len);
	memcpy((uint8_t*)dname_name(res)+x_len, dname_name(dest), dest->name_size);
	assert(dname_is_subdomain(res, dest));
	return res;
}
Exemplo n.º 2
0
/** create and write a zone */
int
write_zone_to_udb(udb_base* udb, zone_type* zone, struct timespec* mtime,
	const char* file_str)
{
	udb_ptr z;
	/* make udb dirty */
	udb_base_set_userflags(udb, 1);
	/* find or create zone */
	if(udb_zone_search(udb, &z, dname_name(domain_dname(zone->apex)),
		domain_dname(zone->apex)->name_size)) {
		/* wipe existing contents */
		udb_zone_clear(udb, &z);
	} else {
		if(!udb_zone_create(udb, &z, dname_name(domain_dname(
			zone->apex)), domain_dname(zone->apex)->name_size)) {
			udb_base_set_userflags(udb, 0);
			return 0;
		}
	}
	/* set mtime */
	ZONE(&z)->mtime = (uint64_t)mtime->tv_sec;
	ZONE(&z)->mtime_nsec = (uint64_t)mtime->tv_nsec;
	ZONE(&z)->is_changed = 0;
	udb_zone_set_log_str(udb, &z, NULL);
	udb_zone_set_file_str(udb, &z, file_str);
	/* write zone */
	if(!write_zone(udb, &z, zone)) {
		udb_base_set_userflags(udb, 0);
		return 0;
	}
	udb_ptr_unlink(&z, udb);
	udb_base_set_userflags(udb, 0);
	return 1;
}
Exemplo n.º 3
0
static void
encode_dname(query_type *q, domain_type *domain)
{
	while (domain->parent && query_get_dname_offset(q, domain) == 0) {
		query_put_dname_offset(q, domain, buffer_position(q->packet));
		DEBUG(DEBUG_NAME_COMPRESSION, 2,
		      (LOG_INFO, "dname: %s, number: %lu, offset: %u\n",
		       dname_to_string(domain_dname(domain), NULL),
		       (unsigned long) domain->number,
		       query_get_dname_offset(q, domain)));
		buffer_write(q->packet, dname_name(domain_dname(domain)),
			     label_length(dname_name(domain_dname(domain))) + 1U);
		domain = domain->parent;
	}
	if (domain->parent) {
		DEBUG(DEBUG_NAME_COMPRESSION, 2,
		      (LOG_INFO, "dname: %s, number: %lu, pointer: %u\n",
		       dname_to_string(domain_dname(domain), NULL),
		       (unsigned long) domain->number,
		       query_get_dname_offset(q, domain)));
		assert(query_get_dname_offset(q, domain) <= MAX_COMPRESSION_OFFSET);
		buffer_write_u16(q->packet,
				 0xc000 | query_get_dname_offset(q, domain));
	} else {
		buffer_write_u8(q->packet, 0);
	}
}
Exemplo n.º 4
0
const dname_type *
dname_concatenate(region_type *region,
		  const dname_type *left,
		  const dname_type *right)
{
	uint8_t temp[MAXDOMAINLEN];

	assert(left->name_size + right->name_size - 1 <= MAXDOMAINLEN);

	memcpy(temp, dname_name(left), left->name_size - 1);
	memcpy(temp + left->name_size - 1, dname_name(right), right->name_size);

	return dname_make(region, temp, 0);
}
Exemplo n.º 5
0
/**
 * Make wildcard synthesis.
 *
 */
int
dname_make_wildcard(struct region *region,
		    struct dname const *dname,
		    struct dname const **wildcard)
{
	uint8_t name_size;
	uint8_t label_count;
	uint8_t *names;
	uint8_t *labels;
	struct dname *new_dname;
	unsigned int i;
	/*
	 * Checks:
	 *	dname label_count + 1 < MAXLABELS
	 * 	dname size + 2 < MAXDOMAINLEN
	 */
	if (dname->label_count > (MAXLABELS - 1)) {
		return EINVAL;
	}
	if (dname->name_size > (MAXDOMAINLEN - 2)) {
		return EINVAL;
	}

	label_count = dname->label_count + 1;
	name_size = dname->name_size + 2;
	new_dname = (struct dname *) region_alloc(region,
						  sizeof(dname_type) +
						  (label_count * sizeof(uint8_t)) +
						  (name_size * sizeof(uint8_t)));
	if (new_dname == NULL) {
		return ENOMEM;
	}
	new_dname->label_count = label_count;
	new_dname->name_size = name_size;
	labels = (uint8_t *) dname_label_offsets(new_dname);
	memcpy(labels, dname_label_offsets(dname),
	       dname->label_count * sizeof(uint8_t));
	for (i = 0; i < dname->label_count; i++) {
		labels[i] += 2;
	}
	labels[i] = 0;

	names = (uint8_t *) dname_name(new_dname);
	*names++ = '\001';
	*names++ = '*';
	memcpy(names, dname_name(dname),
	       dname->name_size * sizeof(uint8_t));
	*wildcard = new_dname;
	return 0;
}
Exemplo n.º 6
0
int
packet_encode_rr(query_type *q, domain_type *owner, rr_type *rr)
{
	size_t truncation_mark;
	uint16_t rdlength = 0;
	size_t rdlength_pos;
	uint16_t j;

	assert(q);
	assert(owner);
	assert(rr);

	/*
	 * If the record does not in fit in the packet the packet size
	 * will be restored to the mark.
	 */
	truncation_mark = buffer_position(q->packet);

	encode_dname(q, owner);
	buffer_write_u16(q->packet, rr->type);
	buffer_write_u16(q->packet, rr->klass);
	buffer_write_u32(q->packet, rr->ttl);

	/* Reserve space for rdlength. */
	rdlength_pos = buffer_position(q->packet);
	buffer_skip(q->packet, sizeof(rdlength));

	for (j = 0; j < rr->rdata_count; ++j) {
		switch (rdata_atom_wireformat_type(rr->type, j)) {
		case RDATA_WF_COMPRESSED_DNAME:
			encode_dname(q, rdata_atom_domain(rr->rdatas[j]));
			break;
		case RDATA_WF_UNCOMPRESSED_DNAME:
		{
			const dname_type *dname = domain_dname(
				rdata_atom_domain(rr->rdatas[j]));
			buffer_write(q->packet,
				     dname_name(dname), dname->name_size);
			break;
		}
		default:
			buffer_write(q->packet,
				     rdata_atom_data(rr->rdatas[j]),
				     rdata_atom_size(rr->rdatas[j]));
			break;
		}
	}

	if (!query_overflow(q)) {
		rdlength = (buffer_position(q->packet) - rdlength_pos
			    - sizeof(rdlength));
		buffer_write_u16_at(q->packet, rdlength_pos, rdlength);
		return 1;
	} else {
		buffer_set_position(q->packet, truncation_mark);
		query_clear_dname_offsets(q, truncation_mark);
		assert(!query_overflow(q));
		return 0;
	}
}
Exemplo n.º 7
0
/** delete an RR */
void
udb_del_rr(udb_base* udb, udb_ptr* z, rr_type* rr)
{
	/* marshal the rdata (uncompressed) into a buffer */
	uint8_t rdata[MAX_RDLENGTH];
	size_t rdatalen = rr_marshal_rdata(rr, rdata, sizeof(rdata));
	assert(udb);
	udb_zone_del_rr(udb, z, dname_name(domain_dname(rr->owner)),
		domain_dname(rr->owner)->name_size, rr->type, rr->klass,
		rdata, rdatalen);
}
Exemplo n.º 8
0
const char *
dname_to_string_r(const dname_type *dname, const dname_type *origin,
	char* buf)
{
	size_t i;
	size_t labels_to_convert = 0;
	int absolute = 1;
	char *dst;
	const uint8_t *src;
	if (!dname) {
		*buf = '\0';
		return buf;
	}
	if (dname->label_count == 1) {
		strlcpy(buf, ".", sizeof(buf));
		return buf;
	}
	labels_to_convert = dname->label_count - 1;

	if (origin && dname_is_subdomain(dname, origin)) {
		int common_labels = dname_label_match_count(dname, origin);
		labels_to_convert = dname->label_count - common_labels;
		absolute = 0;
	}

	dst = buf;
	src = dname_name(dname);
	for (i = 0; i < labels_to_convert; ++i) {
		size_t len = label_length(src);
		size_t j;
		++src;
		for (j = 0; j < len; ++j) {
			uint8_t ch = *src++;
			if (isalnum(ch) || ch == '-' || ch == '_') {
				*dst++ = ch;
			} else if (ch == '.' || ch == '\\') {
				*dst++ = '\\';
				*dst++ = ch;
			} else {
				snprintf(dst, 5, "\\%03u", (unsigned int)ch);
				dst += 4;
			}
		}
		*dst++ = '.';
	}
	if (absolute) {
		*dst = '\0';
	} else {
		*--dst = '\0';
	}
	return buf;
}
Exemplo n.º 9
0
void
xfrd_copy_soa(xfrd_soa_t* soa, rr_type* rr)
{
	const uint8_t* rr_ns_wire = dname_name(domain_dname(rdata_atom_domain(rr->rdatas[0])));
	uint8_t rr_ns_len = domain_dname(rdata_atom_domain(rr->rdatas[0]))->name_size;
	const uint8_t* rr_em_wire = dname_name(domain_dname(rdata_atom_domain(rr->rdatas[1])));
	uint8_t rr_em_len = domain_dname(rdata_atom_domain(rr->rdatas[1]))->name_size;

	if(rr->type != TYPE_SOA || rr->rdata_count != 7) {
		log_msg(LOG_ERR, "xfrd: copy_soa called with bad rr, type %d rrs %u.",
			rr->type, rr->rdata_count);
		return;
	}
	DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: copy_soa rr, type %d rrs %u, ttl %u.",
			rr->type, rr->rdata_count, rr->ttl));
	soa->type = htons(rr->type);
	soa->klass = htons(rr->klass);
	soa->ttl = htonl(rr->ttl);
	soa->rdata_count = htons(rr->rdata_count);

	/* copy dnames */
	soa->prim_ns[0] = rr_ns_len;
	memcpy(soa->prim_ns+1, rr_ns_wire, rr_ns_len);
	soa->email[0] = rr_em_len;
	memcpy(soa->email+1, rr_em_wire, rr_em_len);

	/* already in network format */
	memcpy(&soa->serial, rdata_atom_data(rr->rdatas[2]), sizeof(uint32_t));
	memcpy(&soa->refresh, rdata_atom_data(rr->rdatas[3]), sizeof(uint32_t));
	memcpy(&soa->retry, rdata_atom_data(rr->rdatas[4]), sizeof(uint32_t));
	memcpy(&soa->expire, rdata_atom_data(rr->rdatas[5]), sizeof(uint32_t));
	memcpy(&soa->minimum, rdata_atom_data(rr->rdatas[6]), sizeof(uint32_t));
	DEBUG(DEBUG_XFRD,1, (LOG_INFO,
		"xfrd: copy_soa rr, serial %u refresh %u retry %u expire %u",
		ntohl(soa->serial), ntohl(soa->refresh), ntohl(soa->retry),
		ntohl(soa->expire)));
}
Exemplo n.º 10
0
Arquivo: dname.c Projeto: matje/rzonec
/**
 * Create new domain name.
 *
 */
dname_type*
dname_create(region_type* r, const char* str)
{
    uint8_t wire[DNAME_MAXLEN];
    uint8_t label_offsets[DNAME_MAXLEN];
    uint8_t label_count = 0;
    size_t size = 0;
    const uint8_t* label = wire;
    dname_type *dname;
    ssize_t i;
    assert(r);
    assert(str);
    if (!dname_str2wire(wire, str)) {
        fprintf(stderr, "[%s] error: parse dname %s failed", logstr, str);
        return NULL;
    }
    while (1) {
        if (label_is_pointer(label)) {
            return NULL;
        }
        label_offsets[label_count] = (uint8_t) (label - wire);
        ++label_count;
        size += label_length(label) + 1;
        if (label_is_root(label)) {
            break;
        }
        label = label_next(label);
    }
    if (size > DNAME_MAXLEN) {
        return NULL;
    }
    assert(label_count <= DNAME_MAXLEN / 2 + 1);
    /* reverse label offsets. */

    /* reverse label offsets. */
    for (i = 0; i < label_count / 2; ++i) {
        uint8_t tmp = label_offsets[i];
        label_offsets[i] = label_offsets[label_count - i - 1];
        label_offsets[label_count - i - 1] = tmp;
    }
    dname = (dname_type *) region_alloc(r, (sizeof(dname_type)
        + (label_count + size) * sizeof(uint8_t)));
    dname->size = size;
    dname->label_count = label_count;
    memcpy((uint8_t *) dname_label_offsets(dname), label_offsets,
        label_count * sizeof(uint8_t));
    memcpy((uint8_t *) dname_name(dname), wire, size * sizeof(uint8_t));
    return dname;
}
Exemplo n.º 11
0
/** write rr */
int
udb_write_rr(udb_base* udb, udb_ptr* z, rr_type* rr)
{
	/* marshal the rdata (uncompressed) into a buffer */
	uint8_t rdata[MAX_RDLENGTH];
	size_t rdatalen = 0;
	unsigned i;
	assert(rr);
	for(i=0; i<rr->rdata_count; i++) {
		rdatalen += add_rdata(rr, i, rdata+rdatalen,
			sizeof(rdata)-rdatalen);
	}
	assert(udb);
	return udb_zone_add_rr(udb, z, dname_name(domain_dname(rr->owner)),
		domain_dname(rr->owner)->name_size, rr->type, rr->klass,
		rr->ttl, rdata, rdatalen);
}
Exemplo n.º 12
0
Arquivo: dname.c Projeto: matje/rzonec
/**
 * Print domain name.
 *
 */
void dname_print(FILE* fd, dname_type* dname)
{
    static char buf[DNAME_MAXLEN*5];
    size_t i;
    size_t labels_to_convert;
    char* dst;
    const uint8_t* src;

    if (!dname || !fd) {
        return;
    }
    assert(dname->label_count > 0);
    if (dname->label_count == 1) {
        fprintf(fd, ".");
        return;
    }
    labels_to_convert = dname->label_count - 1;
    dst = buf;
    src = dname_name(dname);
    for (i = 0; i < labels_to_convert; ++i) {
        size_t len = label_length(src);
        size_t j;
        ++src;
        for (j = 0; j < len; ++j) {
            uint8_t ch = *src++;
            if (isalnum(ch) || ch == '-' || ch == '_') {
                *dst++ = ch;
            } else if (ch == '.' || ch == '\\' || ch == '(' || ch == ')'
                || ch == ';') {
                *dst++ = '\\';
                *dst++ = ch;
            } else {
                snprintf(dst, 5, "\\%03u", (unsigned int)ch);
                dst += 4;
            }
        }
        *dst++ = '.';
    }
    *dst = '\0';
    fprintf(fd, "%s", buf);
    return;
}
Exemplo n.º 13
0
void
xfrd_setup_packet(buffer_type* packet,
	uint16_t type, uint16_t klass, const dname_type* dname)
{
	/* Set up the header */
	buffer_clear(packet);
	ID_SET(packet, qid_generate());
	FLAGS_SET(packet, 0);
	OPCODE_SET(packet, OPCODE_QUERY);
	QDCOUNT_SET(packet, 1);
	ANCOUNT_SET(packet, 0);
	NSCOUNT_SET(packet, 0);
	ARCOUNT_SET(packet, 0);
	buffer_skip(packet, QHEADERSZ);

	/* The question record. */
	buffer_write(packet, dname_name(dname), dname->name_size);
	buffer_write_u16(packet, type);
	buffer_write_u16(packet, klass);
}
Exemplo n.º 14
0
/** add an rdata (uncompressed) to the destination */
static size_t
add_rdata(rr_type* rr, unsigned i, uint8_t* buf, size_t buflen)
{
	switch(rdata_atom_wireformat_type(rr->type, i)) {
		case RDATA_WF_COMPRESSED_DNAME:
		case RDATA_WF_UNCOMPRESSED_DNAME:
		{
			const dname_type* dname = domain_dname(
				rdata_atom_domain(rr->rdatas[i]));
			if(dname->name_size > buflen)
				return 0;
			memmove(buf, dname_name(dname), dname->name_size);
			return dname->name_size;
		}
		default:
			break;
	}
	if(rdata_atom_size(rr->rdatas[i]) > buflen)
		return 0;
	memmove(buf, rdata_atom_data(rr->rdatas[i]),
		rdata_atom_size(rr->rdatas[i]));
	return rdata_atom_size(rr->rdatas[i]);
}
Exemplo n.º 15
0
int
rdata_atoms_to_unknown_string(buffer_type *output,
			      rrtype_descriptor_type *descriptor,
			      size_t rdata_count,
			      rdata_atom_type *rdatas)
{
	size_t i;
	size_t size =
		rdata_maximum_wireformat_size(descriptor, rdata_count, rdatas);
	buffer_printf(output, " \\# %lu ", (unsigned long) size);
	for (i = 0; i < rdata_count; ++i) {
		if (rdata_atom_is_domain(descriptor->type, i)) {
			const dname_type *dname =
				domain_dname(rdata_atom_domain(rdatas[i]));
			hex_to_string(
				output, dname_name(dname), dname->name_size);
		} else {
			hex_to_string(output, rdata_atom_data(rdatas[i]),
				rdata_atom_size(rdatas[i]));
		}
	}
	return 1;
}
Exemplo n.º 16
0
const dname_type *
dname_make(region_type *region, const uint8_t *name, int normalize)
{
	size_t name_size = 0;
	uint8_t label_offsets[MAXDOMAINLEN];
	uint8_t label_count = 0;
	const uint8_t *label = name;
	dname_type *result;
	ssize_t i;

	assert(name);

	while (1) {
		if (label_is_pointer(label))
			return NULL;

		label_offsets[label_count] = (uint8_t) (label - name);
		++label_count;
		name_size += label_length(label) + 1;

		if (label_is_root(label))
			break;

		label = label_next(label);
	}

	if (name_size > MAXDOMAINLEN)
		return NULL;

	assert(label_count <= MAXDOMAINLEN / 2 + 1);

	/* Reverse label offsets.  */
	for (i = 0; i < label_count / 2; ++i) {
		uint8_t tmp = label_offsets[i];
		label_offsets[i] = label_offsets[label_count - i - 1];
		label_offsets[label_count - i - 1] = tmp;
	}

	result = (dname_type *) region_alloc(
		region,
		(sizeof(dname_type)
		 + (label_count + name_size) * sizeof(uint8_t)));
	result->name_size = name_size;
	result->label_count = label_count;
	memcpy((uint8_t *) dname_label_offsets(result),
	       label_offsets,
	       label_count * sizeof(uint8_t));
	if (normalize) {
		uint8_t *dst = (uint8_t *) dname_name(result);
		const uint8_t *src = name;
		while (!label_is_root(src)) {
			ssize_t len = label_length(src);
			*dst++ = *src++;
			for (i = 0; i < len; ++i) {
				*dst++ = DNAME_NORMALIZE(*src++);
			}
		}
		*dst = *src;
	} else {
		memcpy((uint8_t *) dname_name(result),
		       name,
		       name_size * sizeof(uint8_t));
	}
	return result;
}
Exemplo n.º 17
0
ssize_t
rdata_wireformat_to_rdata_atoms(region_type *region,
				domain_table_type *owners,
				uint16_t rrtype,
				uint16_t data_size,
				buffer_type *packet,
				rdata_atom_type **rdatas)
{
	size_t end = buffer_position(packet) + data_size;
	size_t i;
	rdata_atom_type temp_rdatas[MAXRDATALEN];
	rrtype_descriptor_type *descriptor = rrtype_descriptor_by_type(rrtype);
	region_type *temp_region;

	assert(descriptor->maximum <= MAXRDATALEN);

	if (!buffer_available(packet, data_size)) {
		return -1;
	}

	temp_region = region_create(xalloc, free);

	for (i = 0; i < descriptor->maximum; ++i) {
		int is_domain = 0;
		int is_normalized = 0;
		int is_wirestore = 0;
		size_t length = 0;
		int required = i < descriptor->minimum;

		switch (rdata_atom_wireformat_type(rrtype, i)) {
		case RDATA_WF_COMPRESSED_DNAME:
		case RDATA_WF_UNCOMPRESSED_DNAME:
			is_domain = 1;
			is_normalized = 1;
			break;
		case RDATA_WF_LITERAL_DNAME:
			is_domain = 1;
			is_wirestore = 1;
			break;
		case RDATA_WF_BYTE:
			length = sizeof(uint8_t);
			break;
		case RDATA_WF_SHORT:
			length = sizeof(uint16_t);
			break;
		case RDATA_WF_LONG:
			length = sizeof(uint32_t);
			break;
		case RDATA_WF_TEXTS:
		case RDATA_WF_LONG_TEXT:
			length = end - buffer_position(packet);
			break;
		case RDATA_WF_TEXT:
		case RDATA_WF_BINARYWITHLENGTH:
			/* Length is stored in the first byte.  */
			length = 1;
			if (buffer_position(packet) + length <= end) {
				length += buffer_current(packet)[length - 1];
			}
			break;
		case RDATA_WF_A:
			length = sizeof(in_addr_t);
			break;
		case RDATA_WF_AAAA:
			length = IP6ADDRLEN;
			break;
		case RDATA_WF_ILNP64:
			length = IP6ADDRLEN/2;
			break;
		case RDATA_WF_EUI48:
			length = EUI48ADDRLEN;
			break;
		case RDATA_WF_EUI64:
			length = EUI64ADDRLEN;
			break;
		case RDATA_WF_BINARY:
			/* Remaining RDATA is binary.  */
			length = end - buffer_position(packet);
			break;
		case RDATA_WF_APL:
			length = (sizeof(uint16_t)    /* address family */
				  + sizeof(uint8_t)   /* prefix */
				  + sizeof(uint8_t)); /* length */
			if (buffer_position(packet) + length <= end) {
				/* Mask out negation bit.  */
				length += (buffer_current(packet)[length - 1]
					   & APL_LENGTH_MASK);
			}
			break;
		case RDATA_WF_IPSECGATEWAY:
			switch(rdata_atom_data(temp_rdatas[1])[0]) /* gateway type */ {
			default:
			case IPSECKEY_NOGATEWAY:
				length = 0;
				break;
			case IPSECKEY_IP4:
				length = IP4ADDRLEN;
				break;
			case IPSECKEY_IP6:
				length = IP6ADDRLEN;
				break;
			case IPSECKEY_DNAME:
				is_domain = 1;
				is_normalized = 1;
				is_wirestore = 1;
				break;
			}
			break;
		}

		if (is_domain) {
			const dname_type *dname;

			if (!required && buffer_position(packet) == end) {
				break;
			}

			dname = dname_make_from_packet(
				temp_region, packet, 1, is_normalized);
			if (!dname || buffer_position(packet) > end) {
				/* Error in domain name.  */
				region_destroy(temp_region);
				return -1;
			}
			if(is_wirestore) {
				temp_rdatas[i].data = (uint16_t *) region_alloc(
                                	region, sizeof(uint16_t) + ((size_t)dname->name_size));
				temp_rdatas[i].data[0] = dname->name_size;
				memcpy(temp_rdatas[i].data+1, dname_name(dname),
					dname->name_size);
			} else {
				temp_rdatas[i].domain
					= domain_table_insert(owners, dname);
				temp_rdatas[i].domain->usage ++;
			}
		} else {
			if (buffer_position(packet) + length > end) {
				if (required) {
					/* Truncated RDATA.  */
					region_destroy(temp_region);
					return -1;
				} else {
					break;
				}
			}
			if (!required && buffer_position(packet) == end) {
				break;
			}

			temp_rdatas[i].data = (uint16_t *) region_alloc(
				region, sizeof(uint16_t) + length);
			temp_rdatas[i].data[0] = length;
			buffer_read(packet, temp_rdatas[i].data + 1, length);
		}
	}

	if (buffer_position(packet) < end) {
		/* Trailing garbage.  */
		region_destroy(temp_region);
		return -1;
	}

	*rdatas = (rdata_atom_type *) region_alloc_array_init(
		region, temp_rdatas, i, sizeof(rdata_atom_type));
	region_destroy(temp_region);
	return (ssize_t)i;
}
Exemplo n.º 18
0
void
namedb_write_zonefile(struct nsd* nsd, struct zone_options* zopt)
{
	const char* zfile;
	int notexist = 0;
	zone_type* zone;
	/* if no zone exists, it has no contents or it has no zonefile
	 * configured, then no need to write data to disk */
	if(!zopt->pattern->zonefile)
		return;
	zone = namedb_find_zone(nsd->db, (const dname_type*)zopt->node.key);
	if(!zone || !zone->apex || !zone->soa_rrset)
		return;
	/* write if file does not exist, or if changed */
	/* so, determine filename, create directory components, check exist*/
	zfile = config_make_zonefile(zopt, nsd);
	if(!create_path_components(zfile, &notexist)) {
		log_msg(LOG_ERR, "could not write zone %s to file %s because "
			"the path could not be created", zopt->name, zfile);
		return;
	}

	/* if not changed, do not write. */
	if(notexist || zone->is_changed) {
		char logs[4096];
		char bakfile[4096];
		struct timespec mtime;
		udb_ptr zudb;
		if(nsd->db->udb) {
			if(!udb_zone_search(nsd->db->udb, &zudb,
				dname_name(domain_dname(zone->apex)),
				domain_dname(zone->apex)->name_size))
				return; /* zone does not exist in db */
		}
		/* write to zfile~ first, then rename if that works */
		snprintf(bakfile, sizeof(bakfile), "%s~", zfile);
		if(nsd->db->udb && ZONE(&zudb)->log_str.data) {
			udb_ptr s;
			udb_ptr_new(&s, nsd->db->udb, &ZONE(&zudb)->log_str);
			strlcpy(logs, (char*)udb_ptr_data(&s), sizeof(logs));
			udb_ptr_unlink(&s, nsd->db->udb);
		} else if(zone->logstr) {
			strlcpy(logs, zone->logstr, sizeof(logs));
		} else logs[0] = 0;
		VERBOSITY(1, (LOG_INFO, "writing zone %s to file %s",
			zone->opts->name, zfile));
		if(!write_to_zonefile(zone, bakfile, logs)) {
			if(nsd->db->udb)
				udb_ptr_unlink(&zudb, nsd->db->udb);
			(void)unlink(bakfile); /* delete failed file */
			return; /* error already printed */
		}
		if(rename(bakfile, zfile) == -1) {
			log_msg(LOG_ERR, "rename(%s to %s) failed: %s",
				bakfile, zfile, strerror(errno));
			if(nsd->db->udb)
				udb_ptr_unlink(&zudb, nsd->db->udb);
			(void)unlink(bakfile); /* delete failed file */
			return;
		}
		zone->is_changed = 0;
		/* fetch the mtime of the just created zonefile so we
		 * do not waste effort reading it back in */
		if(!file_get_mtime(zfile, &mtime, &notexist)) {
			get_time(&mtime);
		}
		if(nsd->db->udb) {
			ZONE(&zudb)->mtime = (uint64_t)mtime.tv_sec;
			ZONE(&zudb)->mtime_nsec = (uint64_t)mtime.tv_nsec;
			ZONE(&zudb)->is_changed = 0;
			udb_zone_set_log_str(nsd->db->udb, &zudb, NULL);
			udb_ptr_unlink(&zudb, nsd->db->udb);
		} else {
			zone->mtime = mtime;
			if(zone->filename)
				region_recycle(nsd->db->region, zone->filename,
					strlen(zone->filename)+1);
			zone->filename = region_strdup(nsd->db->region, zfile);
			if(zone->logstr)
				region_recycle(nsd->db->region, zone->logstr,
					strlen(zone->logstr)+1);
			zone->logstr = NULL;
		}
	}
}
Exemplo n.º 19
0
/** classify the query in a number of different types, each has separate
 * ratelimiting, so that positive queries are not impeded by others */
static uint16_t rrl_classify(query_type* query, const uint8_t** d,	
	size_t* d_len)
{
	if(RCODE(query->packet) == RCODE_NXDOMAIN) {
		if(query->zone && query->zone->apex) {
			*d = dname_name(domain_dname(query->zone->apex));
			*d_len = domain_dname(query->zone->apex)->name_size;
		}
		return rrl_type_nxdomain;
	}
	if(RCODE(query->packet) != RCODE_OK) {
		if(query->zone && query->zone->apex) {
			*d = dname_name(domain_dname(query->zone->apex));
			*d_len = domain_dname(query->zone->apex)->name_size;
		}
		return rrl_type_error;
	}
	if(query->delegation_domain) {
		*d = dname_name(domain_dname(query->delegation_domain));
		*d_len = domain_dname(query->delegation_domain)->name_size;
		return rrl_type_referral;
	}
	if(query->qtype == TYPE_ANY) {
		if(query->qname) {
			*d = dname_name(query->qname);
			*d_len = query->qname->name_size;
		}
		return rrl_type_any;
	}
	if(query->qtype == TYPE_RRSIG) {
		if(query->qname) {
			*d = dname_name(query->qname);
			*d_len = query->qname->name_size;
		}
		return rrl_type_rrsig;
	}
	if(query->wildcard_domain) {
		*d = dname_name(domain_dname(query->wildcard_domain));
		*d_len = domain_dname(query->wildcard_domain)->name_size;
		return rrl_type_wildcard;
	}
	if(ANCOUNT(query->packet) == 0) {
		if(query->zone && query->zone->apex) {
			*d = dname_name(domain_dname(query->zone->apex));
			*d_len = domain_dname(query->zone->apex)->name_size;
		}
		return rrl_type_nodata;
	}
	if(query->qtype == TYPE_DNSKEY) {
		if(query->qname) {
			*d = dname_name(query->qname);
			*d_len = query->qname->name_size;
		}
		return rrl_type_dnskey;
	}
	/* positive */
	if(query->qname) {
		*d = dname_name(query->qname);
		*d_len = query->qname->name_size;
	}
	return rrl_type_positive;
}