Ejemplo n.º 1
0
isc_result_t
dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
	       dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
	       dns_dbnode_t **nodep, dns_name_t *foundname,
	       dns_clientinfomethods_t *methods, dns_clientinfo_t *clientinfo,
	       dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{

	/*
	 * Find the best match for 'name' and 'type' in version 'version'
	 * of 'db', passing in 'arg'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(type != dns_rdatatype_rrsig);
	REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
	REQUIRE(dns_name_hasbuffer(foundname));
	REQUIRE(rdataset == NULL ||
		(DNS_RDATASET_VALID(rdataset) &&
		 ! dns_rdataset_isassociated(rdataset)));
	REQUIRE(sigrdataset == NULL ||
		(DNS_RDATASET_VALID(sigrdataset) &&
		 ! dns_rdataset_isassociated(sigrdataset)));

	if (db->methods->findext != NULL)
		return ((db->methods->findext)(db, name, version, type,
					       options, now, nodep, foundname,
					       methods, clientinfo,
					       rdataset, sigrdataset));
	else
		return ((db->methods->find)(db, name, version, type,
					    options, now, nodep, foundname,
					    rdataset, sigrdataset));
}
Ejemplo n.º 2
0
isc_result_t
dns_db_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
		   isc_stdtime_t now, dns_rdataset_t *rdataset,
		   unsigned int options, dns_rdataset_t *addedrdataset)
{
	/*
	 * Add 'rdataset' to 'node' in version 'version' of 'db'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(node != NULL);
	REQUIRE(((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL)||
		((db->attributes & DNS_DBATTR_CACHE) != 0 &&
		 version == NULL && (options & DNS_DBADD_MERGE) == 0));
	REQUIRE((options & DNS_DBADD_EXACT) == 0 ||
		(options & DNS_DBADD_MERGE) != 0);
	REQUIRE(DNS_RDATASET_VALID(rdataset));
	REQUIRE(dns_rdataset_isassociated(rdataset));
	REQUIRE(rdataset->rdclass == db->rdclass);
	REQUIRE(addedrdataset == NULL ||
		(DNS_RDATASET_VALID(addedrdataset) &&
		 ! dns_rdataset_isassociated(addedrdataset)));

	return ((db->methods->addrdataset)(db, node, version, now, rdataset,
					   options, addedrdataset));
}
Ejemplo n.º 3
0
static isc_result_t
build_event(dns_lookup_t *lookup) {
	dns_name_t *name = NULL;
	dns_rdataset_t *rdataset = NULL;
	dns_rdataset_t *sigrdataset = NULL;
	isc_result_t result;

	name = isc_mem_get(lookup->mctx, sizeof(dns_name_t));
	if (name == NULL) {
		result = ISC_R_NOMEMORY;
		goto fail;
	}
	dns_name_init(name, NULL);
	result = dns_name_dup(dns_fixedname_name(&lookup->name),
			      lookup->mctx, name);
	if (result != ISC_R_SUCCESS)
		goto fail;

	if (dns_rdataset_isassociated(&lookup->rdataset)) {
		rdataset = isc_mem_get(lookup->mctx, sizeof(dns_rdataset_t));
		if (rdataset == NULL) {
			result = ISC_R_NOMEMORY;
			goto fail;
		}
		dns_rdataset_init(rdataset);
		dns_rdataset_clone(&lookup->rdataset, rdataset);
	}

	if (dns_rdataset_isassociated(&lookup->sigrdataset)) {
		sigrdataset = isc_mem_get(lookup->mctx,
					  sizeof(dns_rdataset_t));
		if (sigrdataset == NULL) {
			result = ISC_R_NOMEMORY;
			goto fail;
		}
		dns_rdataset_init(sigrdataset);
		dns_rdataset_clone(&lookup->sigrdataset, sigrdataset);
	}

	lookup->event->name = name;
	lookup->event->rdataset = rdataset;
	lookup->event->sigrdataset = sigrdataset;

	return (ISC_R_SUCCESS);

 fail:
	if (name != NULL) {
		if (dns_name_dynamic(name))
			dns_name_free(name, lookup->mctx);
		isc_mem_put(lookup->mctx, name, sizeof(dns_name_t));
	}
	if (rdataset != NULL) {
		if (dns_rdataset_isassociated(rdataset))
			dns_rdataset_disassociate(rdataset);
		isc_mem_put(lookup->mctx, rdataset, sizeof(dns_rdataset_t));
	}
	return (result);
}
Ejemplo n.º 4
0
isc_result_t
dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist,
			 dns_rdataset_t *rdataset)
{
	/*
	 * Make 'rdataset' refer to the rdata in 'rdatalist'.
	 */

	REQUIRE(rdatalist != NULL);
	REQUIRE(DNS_RDATASET_VALID(rdataset));
	REQUIRE(! dns_rdataset_isassociated(rdataset));

	rdataset->methods = &methods;
	rdataset->rdclass = rdatalist->rdclass;
	rdataset->type = rdatalist->type;
	rdataset->covers = rdatalist->covers;
	rdataset->ttl = rdatalist->ttl;
	rdataset->trust = 0;
	rdataset->private1 = rdatalist;
	rdataset->private2 = NULL;
	rdataset->private3 = NULL;
	rdataset->privateuint4 = 0;
	rdataset->private5 = NULL;

	return (ISC_R_SUCCESS);
}
Ejemplo n.º 5
0
void
dns_rdataslab_tordataset(unsigned char *slab, unsigned int reservelen,
			 dns_rdataclass_t rdclass, dns_rdatatype_t rdtype,
			 dns_rdatatype_t covers, dns_ttl_t ttl,
			 dns_rdataset_t *rdataset)
{
	REQUIRE(slab != NULL);
	REQUIRE(!dns_rdataset_isassociated(rdataset));

	rdataset->methods = &rdataset_methods;
	rdataset->rdclass = rdclass;
	rdataset->type = rdtype;
	rdataset->covers = covers;
	rdataset->ttl = ttl;
	rdataset->trust = 0;
	rdataset->private1 = NULL;
	rdataset->private2 = NULL;
	rdataset->private3 = slab + reservelen;

	/*
	 * Reset iterator state.
	 */
	rdataset->privateuint4 = 0;
	rdataset->private5 = NULL;
}
Ejemplo n.º 6
0
/* Dump an rdataset for debug */
static isc_result_t print_rdataset (dns_rdataset_t * rdataset, dns_name_t * owner)
{
    isc_buffer_t target;

    isc_result_t result;

    isc_region_t r;

    char t[4096];

    if (!debug_mode)
        return (ISC_R_SUCCESS);

    isc_buffer_init (&target, t, sizeof (t));

    if (!dns_rdataset_isassociated (rdataset))
        return (ISC_R_SUCCESS);
    result = dns_rdataset_totext (rdataset, owner, ISC_FALSE, ISC_FALSE, &target);
    if (result != ISC_R_SUCCESS)
        return (result);
    isc_buffer_usedregion (&target, &r);
    printf ("%.*s", (int) r.length, (char *) r.base);

    return (ISC_R_SUCCESS);
}
Ejemplo n.º 7
0
static isc_result_t
check_node(dns_rdataset_t *rootns, dns_name_t *name,
	   dns_rdatasetiter_t *rdsiter) {
	isc_result_t result;
	dns_rdataset_t rdataset;

	dns_rdataset_init(&rdataset);
	result = dns_rdatasetiter_first(rdsiter);
	while (result == ISC_R_SUCCESS) {
		dns_rdatasetiter_current(rdsiter, &rdataset);
		switch (rdataset.type) {
		case dns_rdatatype_a:
		case dns_rdatatype_aaaa:
			result = in_rootns(rootns, name);
			if (result != ISC_R_SUCCESS)
				goto cleanup;
			break;
		case dns_rdatatype_ns:
			if (dns_name_compare(name, dns_rootname) == 0)
				break;
			/*FALLTHROUGH*/
		default:
			result = ISC_R_FAILURE;
			goto cleanup;
		}
		dns_rdataset_disassociate(&rdataset);
		result = dns_rdatasetiter_next(rdsiter);
	}
	if (result == ISC_R_NOMORE)
		result = ISC_R_SUCCESS;
 cleanup:
	if (dns_rdataset_isassociated(&rdataset))
		dns_rdataset_disassociate(&rdataset);
	return (result);
}
Ejemplo n.º 8
0
isc_result_t
dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
	       dns_name_t *target, dns_ttl_t ttl)
{
	isc_result_t result;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	unsigned char data[DNS_NSEC_BUFFERSIZE];
	dns_rdatalist_t rdatalist;
	dns_rdataset_t rdataset;

	dns_rdataset_init(&rdataset);
	dns_rdata_init(&rdata);

	RETERR(dns_nsec_buildrdata(db, version, node, target, data, &rdata));

	rdatalist.rdclass = dns_db_class(db);
	rdatalist.type = dns_rdatatype_nsec;
	rdatalist.covers = 0;
	rdatalist.ttl = ttl;
	ISC_LIST_INIT(rdatalist.rdata);
	ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
	RETERR(dns_rdatalist_tordataset(&rdatalist, &rdataset));
	result = dns_db_addrdataset(db, node, version, 0, &rdataset,
				    0, NULL);
	if (result == DNS_R_UNCHANGED)
		result = ISC_R_SUCCESS;
	RETERR(result);
 failure:
	if (dns_rdataset_isassociated(&rdataset))
		dns_rdataset_disassociate(&rdataset);
	return (result);
}
Ejemplo n.º 9
0
static void
db_rr_iterator_destroy(db_rr_iterator_t *it) {
	if (dns_rdataset_isassociated(&it->rdataset))
		dns_rdataset_disassociate(&it->rdataset);
	if (it->rdatasetit != NULL)
		dns_rdatasetiter_destroy(&it->rdatasetit);
	if (it->node != NULL)
		dns_db_detachnode(it->db, &it->node);
	dns_dbiterator_destroy(&it->dbit);
}
Ejemplo n.º 10
0
isc_result_t
dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
		    dns_rdatatype_t type, dns_rdatatype_t covers,
		    isc_stdtime_t now, dns_rdataset_t *rdataset,
		    dns_rdataset_t *sigrdataset)
{
	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(node != NULL);
	REQUIRE(DNS_RDATASET_VALID(rdataset));
	REQUIRE(! dns_rdataset_isassociated(rdataset));
	REQUIRE(covers == 0 || type == dns_rdatatype_rrsig);
	REQUIRE(type != dns_rdatatype_any);
	REQUIRE(sigrdataset == NULL ||
		(DNS_RDATASET_VALID(sigrdataset) &&
		 ! dns_rdataset_isassociated(sigrdataset)));

	return ((db->methods->findrdataset)(db, node, version, type,
					    covers, now, rdataset,
					    sigrdataset));
}
Ejemplo n.º 11
0
void
dns_rriterator_destroy(dns_rriterator_t *it) {
	REQUIRE(VALID_RRITERATOR(it));
	if (dns_rdataset_isassociated(&it->rdataset))
		dns_rdataset_disassociate(&it->rdataset);
	if (it->rdatasetit != NULL)
		dns_rdatasetiter_destroy(&it->rdatasetit);
	if (it->node != NULL)
		dns_db_detachnode(it->db, &it->node);
	dns_dbiterator_destroy(&it->dbit);
}
Ejemplo n.º 12
0
void
dns_lookup_destroy(dns_lookup_t **lookupp) {
	dns_lookup_t *lookup;

	REQUIRE(lookupp != NULL);
	lookup = *lookupp;
	REQUIRE(VALID_LOOKUP(lookup));
	REQUIRE(lookup->event == NULL);
	REQUIRE(lookup->task == NULL);
	REQUIRE(lookup->view == NULL);
	if (dns_rdataset_isassociated(&lookup->rdataset))
		dns_rdataset_disassociate(&lookup->rdataset);
	if (dns_rdataset_isassociated(&lookup->sigrdataset))
		dns_rdataset_disassociate(&lookup->sigrdataset);

	DESTROYLOCK(&lookup->lock);
	lookup->magic = 0;
	isc_mem_putanddetach(&lookup->mctx, lookup, sizeof(*lookup));

	*lookupp = NULL;
}
Ejemplo n.º 13
0
void dns_rdatasetiter_current (dns_rdatasetiter_t * iterator, dns_rdataset_t * rdataset)
{
    /*
     * Return the current rdataset.
     */

    REQUIRE (DNS_RDATASETITER_VALID (iterator));
    REQUIRE (DNS_RDATASET_VALID (rdataset));
    REQUIRE (!dns_rdataset_isassociated (rdataset));

    iterator->methods->current (iterator, rdataset);
}
Ejemplo n.º 14
0
static isc_result_t
check_hints(dns_db_t *db) {
	isc_result_t result;
	dns_rdataset_t rootns;
	dns_dbiterator_t *dbiter = NULL;
	dns_dbnode_t *node = NULL;
	isc_stdtime_t now;
	dns_fixedname_t fixname;
	dns_name_t *name;
	dns_rdatasetiter_t *rdsiter = NULL;

	isc_stdtime_get(&now);

	dns_fixedname_init(&fixname);
	name = dns_fixedname_name(&fixname);

	dns_rdataset_init(&rootns);
	(void)dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0,
			  now, NULL, name, &rootns, NULL);
	result = dns_db_createiterator(db, 0, &dbiter);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	result = dns_dbiterator_first(dbiter);
	while (result == ISC_R_SUCCESS) {
		result = dns_dbiterator_current(dbiter, &node, name);
		if (result != ISC_R_SUCCESS)
			goto cleanup;
		result = dns_db_allrdatasets(db, node, NULL, now, &rdsiter);
		if (result != ISC_R_SUCCESS)
			goto cleanup;
		result = check_node(&rootns, name, rdsiter);
		if (result != ISC_R_SUCCESS)
			goto cleanup;
		dns_rdatasetiter_destroy(&rdsiter);
		dns_db_detachnode(db, &node);
		result = dns_dbiterator_next(dbiter);
	}
	if (result == ISC_R_NOMORE)
		result = ISC_R_SUCCESS;

 cleanup:
	if (dns_rdataset_isassociated(&rootns))
		dns_rdataset_disassociate(&rootns);
	if (rdsiter != NULL)
		dns_rdatasetiter_destroy(&rdsiter);
	if (node != NULL)
		dns_db_detachnode(db, &node);
	if (dbiter != NULL)
		dns_dbiterator_destroy(&dbiter);
	return (result);
}
Ejemplo n.º 15
0
static void
print_status(dns_rdataset_t *rdataset) {
	const char *astr = "", *tstr = "";

	REQUIRE(rdataset != NULL);

	if (!showtrust || !dns_rdataset_isassociated(rdataset))
		return;

	if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
		astr = "negative response, ";

	switch (rdataset->trust) {
	case dns_trust_none:
		tstr = "untrusted";
		break;
	case dns_trust_pending_additional:
		tstr = "signed additional data, pending validation";
		break;
	case dns_trust_pending_answer:
		tstr = "signed answer, pending validation";
		break;
	case dns_trust_additional:
		tstr = "unsigned additional data";
		break;
	case dns_trust_glue:
		tstr = "glue data";
		break;
	case dns_trust_answer:
		if (root_validation || dlv_validation)
			tstr = "unsigned answer";
		else
			tstr = "answer not validated";
		break;
	case dns_trust_authauthority:
		tstr = "authority data";
		break;
	case dns_trust_authanswer:
		tstr = "authoritative";
		break;
	case dns_trust_secure:
		tstr = "fully validated";
		break;
	case dns_trust_ultimate:
		tstr = "ultimate trust";
		break;
	}

	printf("; %s%s\n", astr, tstr);
}
Ejemplo n.º 16
0
isc_result_t
dns_db_subtractrdataset(dns_db_t *db, dns_dbnode_t *node,
			dns_dbversion_t *version, dns_rdataset_t *rdataset,
			unsigned int options, dns_rdataset_t *newrdataset)
{
	/*
	 * Remove any rdata in 'rdataset' from 'node' in version 'version' of
	 * 'db'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(node != NULL);
	REQUIRE((db->attributes & DNS_DBATTR_CACHE) == 0 && version != NULL);
	REQUIRE(DNS_RDATASET_VALID(rdataset));
	REQUIRE(dns_rdataset_isassociated(rdataset));
	REQUIRE(rdataset->rdclass == db->rdclass);
	REQUIRE(newrdataset == NULL ||
		(DNS_RDATASET_VALID(newrdataset) &&
		 ! dns_rdataset_isassociated(newrdataset)));

	return ((db->methods->subtractrdataset)(db, node, version, rdataset,
						options, newrdataset));
}
Ejemplo n.º 17
0
isc_result_t
dns_db_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
		    dns_rdatatype_t type, dns_rdatatype_t covers,
		    isc_stdtime_t now, dns_rdataset_t *rdataset,
		    dns_rdataset_t *sigrdataset)
{
	/*
	 * Search for an rdataset of type 'type' at 'node' that are in version
	 * 'version' of 'db'.  If found, make 'rdataset' refer to it.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE(node != NULL);
	REQUIRE(DNS_RDATASET_VALID(rdataset));
	REQUIRE(! dns_rdataset_isassociated(rdataset));
	REQUIRE(covers == 0 || type == dns_rdatatype_rrsig);
	REQUIRE(type != dns_rdatatype_any);
	REQUIRE(sigrdataset == NULL ||
		(DNS_RDATASET_VALID(sigrdataset) &&
		 ! dns_rdataset_isassociated(sigrdataset)));

	return ((db->methods->findrdataset)(db, node, version, type, covers,
					    now, rdataset, sigrdataset));
}
Ejemplo n.º 18
0
isc_result_t
dns_rriterator_first(dns_rriterator_t *it) {
	REQUIRE(VALID_RRITERATOR(it));
	/* Reset state */
	if (dns_rdataset_isassociated(&it->rdataset))
		dns_rdataset_disassociate(&it->rdataset);
	if (it->rdatasetit != NULL)
		dns_rdatasetiter_destroy(&it->rdatasetit);
	if (it->node != NULL)
		dns_db_detachnode(it->db, &it->node);
	it->result = dns_dbiterator_first(it->dbit);

	/*
	 * The top node may be empty when out of zone glue exists.
	 * Walk the tree to find the first node with data.
	 */
	while (it->result == ISC_R_SUCCESS) {
		it->result = dns_dbiterator_current(it->dbit, &it->node,
					   dns_fixedname_name(&it->fixedname));
		if (it->result != ISC_R_SUCCESS)
			return (it->result);

		it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
						 it->now, &it->rdatasetit);
		if (it->result != ISC_R_SUCCESS)
			return (it->result);

		it->result = dns_rdatasetiter_first(it->rdatasetit);
		if (it->result != ISC_R_SUCCESS) {
			/*
			 * This node is empty. Try next node.
			 */
			dns_rdatasetiter_destroy(&it->rdatasetit);
			dns_db_detachnode(it->db, &it->node);
			it->result = dns_dbiterator_next(it->dbit);
			continue;
		}
		dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
		dns_rdataset_getownercase(&it->rdataset,
					  dns_fixedname_name(&it->fixedname));
		it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
		it->result = dns_rdataset_first(&it->rdataset);
		return (it->result);
	}
	return (it->result);
}
Ejemplo n.º 19
0
static isc_result_t
db_rr_iterator_init(db_rr_iterator_t *it, dns_db_t *db, dns_dbversion_t *ver,
		    isc_stdtime_t now)
{
	isc_result_t result;
	it->db = db;
	it->dbit = NULL;
	it->ver = ver;
	it->now = now;
	it->node = NULL;
	result = dns_db_createiterator(it->db, 0, &it->dbit);
	if (result != ISC_R_SUCCESS)
		return (result);
	it->rdatasetit = NULL;
	dns_rdata_init(&it->rdata);
	dns_rdataset_init(&it->rdataset);
	dns_fixedname_init(&it->fixedname);
	INSIST(! dns_rdataset_isassociated(&it->rdataset));
	it->result = ISC_R_SUCCESS;
	return (it->result);
}
Ejemplo n.º 20
0
isc_result_t
dns_db_findzonecut(dns_db_t *db, dns_name_t *name,
		   unsigned int options, isc_stdtime_t now,
		   dns_dbnode_t **nodep, dns_name_t *foundname,
		   dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset)
{
	/*
	 * Find the deepest known zonecut which encloses 'name' in 'db'.
	 */

	REQUIRE(DNS_DB_VALID(db));
	REQUIRE((db->attributes & DNS_DBATTR_CACHE) != 0);
	REQUIRE(nodep == NULL || (nodep != NULL && *nodep == NULL));
	REQUIRE(dns_name_hasbuffer(foundname));
	REQUIRE(sigrdataset == NULL ||
		(DNS_RDATASET_VALID(sigrdataset) &&
		 ! dns_rdataset_isassociated(sigrdataset)));

	return ((db->methods->findzonecut)(db, name, options, now, nodep,
					   foundname, rdataset, sigrdataset));
}
Ejemplo n.º 21
0
isc_result_t
dns_rriterator_nextrrset(dns_rriterator_t *it) {
	REQUIRE(VALID_RRITERATOR(it));
	if (dns_rdataset_isassociated(&it->rdataset))
		dns_rdataset_disassociate(&it->rdataset);
	it->result = dns_rdatasetiter_next(it->rdatasetit);
	/*
	 * The while loop body is executed more than once
	 * only when an empty dbnode needs to be skipped.
	 */
	while (it->result == ISC_R_NOMORE) {
		dns_rdatasetiter_destroy(&it->rdatasetit);
		dns_db_detachnode(it->db, &it->node);
		it->result = dns_dbiterator_next(it->dbit);
		if (it->result == ISC_R_NOMORE) {
			/* We are at the end of the entire database. */
			return (it->result);
		}
		if (it->result != ISC_R_SUCCESS)
			return (it->result);
		it->result = dns_dbiterator_current(it->dbit, &it->node,
					   dns_fixedname_name(&it->fixedname));
		if (it->result != ISC_R_SUCCESS)
			return (it->result);
		it->result = dns_db_allrdatasets(it->db, it->node, it->ver,
						 it->now, &it->rdatasetit);
		if (it->result != ISC_R_SUCCESS)
			return (it->result);
		it->result = dns_rdatasetiter_first(it->rdatasetit);
	}
	if (it->result != ISC_R_SUCCESS)
		return (it->result);
	dns_rdatasetiter_current(it->rdatasetit, &it->rdataset);
	dns_rdataset_getownercase(&it->rdataset,
				  dns_fixedname_name(&it->fixedname));
	it->rdataset.attributes |= DNS_RDATASETATTR_LOADORDER;
	it->result = dns_rdataset_first(&it->rdataset);
	return (it->result);
}
Ejemplo n.º 22
0
static void
bind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node,
	      rdatasetheader_t *header, dns_rdataset_t *rdataset)
{
	unsigned char *raw;

	/*
	 * Caller must be holding the node lock.
	 */

	REQUIRE(!dns_rdataset_isassociated(rdataset));

	rdataset->methods = &rdataset_methods;
	rdataset->rdclass = ecdb->common.rdclass;
	rdataset->type = header->type;
	rdataset->covers = header->covers;
	rdataset->ttl = header->ttl;
	rdataset->trust = header->trust;
	if (NXDOMAIN(header))
		rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN;
	if (NEGATIVE(header))
		rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE;

	rdataset->private1 = ecdb;
	rdataset->private2 = node;
	raw = (unsigned char *)header + sizeof(*header);
	rdataset->private3 = raw;
	rdataset->count = 0;

	/*
	 * Reset iterator state.
	 */
	rdataset->privateuint4 = 0;
	rdataset->private5 = NULL;

	INSIST(node->references > 0);
	node->references++;
}
Ejemplo n.º 23
0
static isc_result_t
in_rootns(dns_rdataset_t *rootns, dns_name_t *name) {
	isc_result_t result;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_rdata_ns_t ns;
	
	if (!dns_rdataset_isassociated(rootns))
		return (ISC_R_NOTFOUND);

	result = dns_rdataset_first(rootns);
	while (result == ISC_R_SUCCESS) {
		dns_rdataset_current(rootns, &rdata);
		result = dns_rdata_tostruct(&rdata, &ns, NULL);
		if (result != ISC_R_SUCCESS)
			return (result);
		if (dns_name_compare(name, &ns.name) == 0)
			return (ISC_R_SUCCESS);
		result = dns_rdataset_next(rootns);
	}
	if (result == ISC_R_NOMORE)
		result = ISC_R_NOTFOUND;
	return (result);
}
Ejemplo n.º 24
0
/*
 * Arrange to send as much as we can of "stream" without blocking.
 *
 * Requires:
 *	The stream iterator is initialized and points at an RR,
 *      or possibly at the end of the stream (that is, the
 *      _first method of the iterator has been called).
 */
static void
sendstream(xfrout_ctx_t *xfr) {
	dns_message_t *tcpmsg = NULL;
	dns_message_t *msg = NULL; /* Client message if UDP, tcpmsg if TCP */
	isc_result_t result;
	isc_region_t used;
	isc_region_t region;
	dns_rdataset_t *qrdataset;
	dns_name_t *msgname = NULL;
	dns_rdata_t *msgrdata = NULL;
	dns_rdatalist_t *msgrdl = NULL;
	dns_rdataset_t *msgrds = NULL;
	dns_compress_t cctx;
	isc_boolean_t cleanup_cctx = ISC_FALSE;
	isc_boolean_t is_tcp;

	int n_rrs;

	isc_buffer_clear(&xfr->buf);
	isc_buffer_clear(&xfr->txlenbuf);
	isc_buffer_clear(&xfr->txbuf);

	is_tcp = ISC_TF((xfr->client->attributes & NS_CLIENTATTR_TCP) != 0);
	if (!is_tcp) {
		/*
		 * In the UDP case, we put the response data directly into
		 * the client message.
		 */
		msg = xfr->client->message;
		CHECK(dns_message_reply(msg, ISC_TRUE));
	} else {
		/*
		 * TCP. Build a response dns_message_t, temporarily storing
		 * the raw, uncompressed owner names and RR data contiguously
		 * in xfr->buf.  We know that if the uncompressed data fits
		 * in xfr->buf, the compressed data will surely fit in a TCP
		 * message.
		 */

		CHECK(dns_message_create(xfr->mctx,
					 DNS_MESSAGE_INTENTRENDER, &tcpmsg));
		msg = tcpmsg;

		msg->id = xfr->id;
		msg->rcode = dns_rcode_noerror;
		msg->flags = DNS_MESSAGEFLAG_QR | DNS_MESSAGEFLAG_AA;
		if ((xfr->client->attributes & NS_CLIENTATTR_RA) != 0)
			msg->flags |= DNS_MESSAGEFLAG_RA;
		CHECK(dns_message_settsigkey(msg, xfr->tsigkey));
		CHECK(dns_message_setquerytsig(msg, xfr->lasttsig));
		if (xfr->lasttsig != NULL)
			isc_buffer_free(&xfr->lasttsig);

		/*
		 * Add a EDNS option to the message?
		 */
		if ((xfr->client->attributes & NS_CLIENTATTR_WANTOPT) != 0) {
			dns_rdataset_t *opt = NULL;

			CHECK(ns_client_addopt(xfr->client, msg, &opt));
			CHECK(dns_message_setopt(msg, opt));
			/*
			 * Add to first message only.
			 */
			xfr->client->attributes &= ~NS_CLIENTATTR_WANTNSID;
			xfr->client->attributes &= ~NS_CLIENTATTR_HAVEEXPIRE;
		}

		/*
		 * Account for reserved space.
		 */
		if (xfr->tsigkey != NULL)
			INSIST(msg->reserved != 0U);
		isc_buffer_add(&xfr->buf, msg->reserved);

		/*
		 * Include a question section in the first message only.
		 * BIND 8.2.1 will not recognize an IXFR if it does not
		 * have a question section.
		 */
		if (xfr->nmsg == 0) {
			dns_name_t *qname = NULL;
			isc_region_t r;

			/*
			 * Reserve space for the 12-byte message header
			 * and 4 bytes of question.
			 */
			isc_buffer_add(&xfr->buf, 12 + 4);

			qrdataset = NULL;
			result = dns_message_gettemprdataset(msg, &qrdataset);
			if (result != ISC_R_SUCCESS)
				goto failure;
			dns_rdataset_makequestion(qrdataset,
					xfr->client->message->rdclass,
					xfr->qtype);

			result = dns_message_gettempname(msg, &qname);
			if (result != ISC_R_SUCCESS)
				goto failure;
			dns_name_init(qname, NULL);
			isc_buffer_availableregion(&xfr->buf, &r);
			INSIST(r.length >= xfr->qname->length);
			r.length = xfr->qname->length;
			isc_buffer_putmem(&xfr->buf, xfr->qname->ndata,
					  xfr->qname->length);
			dns_name_fromregion(qname, &r);
			ISC_LIST_INIT(qname->list);
			ISC_LIST_APPEND(qname->list, qrdataset, link);

			dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
		} else {
			/*
			 * Reserve space for the 12-byte message header
			 */
			isc_buffer_add(&xfr->buf, 12);
			msg->tcp_continuation = 1;
		}
	}

	/*
	 * Try to fit in as many RRs as possible, unless "one-answer"
	 * format has been requested.
	 */
	for (n_rrs = 0; ; n_rrs++) {
		dns_name_t *name = NULL;
		isc_uint32_t ttl;
		dns_rdata_t *rdata = NULL;

		unsigned int size;
		isc_region_t r;

		msgname = NULL;
		msgrdata = NULL;
		msgrdl = NULL;
		msgrds = NULL;

		xfr->stream->methods->current(xfr->stream,
					      &name, &ttl, &rdata);
		size = name->length + 10 + rdata->length;
		isc_buffer_availableregion(&xfr->buf, &r);
		if (size >= r.length) {
			/*
			 * RR would not fit.  If there are other RRs in the
			 * buffer, send them now and leave this RR to the
			 * next message.  If this RR overflows the buffer
			 * all by itself, fail.
			 *
			 * In theory some RRs might fit in a TCP message
			 * when compressed even if they do not fit when
			 * uncompressed, but surely we don't want
			 * to send such monstrosities to an unsuspecting
			 * slave.
			 */
			if (n_rrs == 0) {
				xfrout_log(xfr, ISC_LOG_WARNING,
					   "RR too large for zone transfer "
					   "(%d bytes)", size);
				/* XXX DNS_R_RRTOOLARGE? */
				result = ISC_R_NOSPACE;
				goto failure;
			}
			break;
		}

		if (isc_log_wouldlog(ns_g_lctx, XFROUT_RR_LOGLEVEL))
			log_rr(name, rdata, ttl); /* XXX */

		result = dns_message_gettempname(msg, &msgname);
		if (result != ISC_R_SUCCESS)
			goto failure;
		dns_name_init(msgname, NULL);
		isc_buffer_availableregion(&xfr->buf, &r);
		INSIST(r.length >= name->length);
		r.length = name->length;
		isc_buffer_putmem(&xfr->buf, name->ndata, name->length);
		dns_name_fromregion(msgname, &r);

		/* Reserve space for RR header. */
		isc_buffer_add(&xfr->buf, 10);

		result = dns_message_gettemprdata(msg, &msgrdata);
		if (result != ISC_R_SUCCESS)
			goto failure;
		isc_buffer_availableregion(&xfr->buf, &r);
		r.length = rdata->length;
		isc_buffer_putmem(&xfr->buf, rdata->data, rdata->length);
		dns_rdata_init(msgrdata);
		dns_rdata_fromregion(msgrdata,
				     rdata->rdclass, rdata->type, &r);

		result = dns_message_gettemprdatalist(msg, &msgrdl);
		if (result != ISC_R_SUCCESS)
			goto failure;
		msgrdl->type = rdata->type;
		msgrdl->rdclass = rdata->rdclass;
		msgrdl->ttl = ttl;
		if (rdata->type == dns_rdatatype_sig ||
		    rdata->type == dns_rdatatype_rrsig)
			msgrdl->covers = dns_rdata_covers(rdata);
		else
			msgrdl->covers = dns_rdatatype_none;
		ISC_LIST_APPEND(msgrdl->rdata, msgrdata, link);

		result = dns_message_gettemprdataset(msg, &msgrds);
		if (result != ISC_R_SUCCESS)
			goto failure;
		result = dns_rdatalist_tordataset(msgrdl, msgrds);
		INSIST(result == ISC_R_SUCCESS);

		ISC_LIST_APPEND(msgname->list, msgrds, link);

		dns_message_addname(msg, msgname, DNS_SECTION_ANSWER);
		msgname = NULL;

		result = xfr->stream->methods->next(xfr->stream);
		if (result == ISC_R_NOMORE) {
			xfr->end_of_stream = ISC_TRUE;
			break;
		}
		CHECK(result);

		if (! xfr->many_answers)
			break;
		/*
		 * At this stage, at least 1 RR has been rendered into
		 * the message. Check if we want to clamp this message
		 * here (TCP only). 20480 was set as an upper limit to
		 * improve message compression.
		 */
		if ((isc_buffer_usedlength(&xfr->buf) >= 20480) && is_tcp)
			break;
	}

	if (is_tcp) {
		CHECK(dns_compress_init(&cctx, -1, xfr->mctx));
		dns_compress_setsensitive(&cctx, ISC_TRUE);
		cleanup_cctx = ISC_TRUE;
		CHECK(dns_message_renderbegin(msg, &cctx, &xfr->txbuf));
		CHECK(dns_message_rendersection(msg, DNS_SECTION_QUESTION, 0));
		CHECK(dns_message_rendersection(msg, DNS_SECTION_ANSWER, 0));
		CHECK(dns_message_renderend(msg));
		dns_compress_invalidate(&cctx);
		cleanup_cctx = ISC_FALSE;

		isc_buffer_usedregion(&xfr->txbuf, &used);
		isc_buffer_putuint16(&xfr->txlenbuf,
				     (isc_uint16_t)used.length);
		region.base = xfr->txlenbuf.base;
		region.length = 2 + used.length;
		xfrout_log(xfr, ISC_LOG_DEBUG(8),
			   "sending TCP message of %d bytes",
			   used.length);
		CHECK(isc_socket_send(xfr->client->tcpsocket, /* XXX */
				      &region, xfr->client->task,
				      xfrout_senddone,
				      xfr));
		xfr->sends++;
	} else {
		xfrout_log(xfr, ISC_LOG_DEBUG(8), "sending IXFR UDP response");
		ns_client_send(xfr->client);
		xfr->stream->methods->pause(xfr->stream);
		xfrout_ctx_destroy(&xfr);
		return;
	}

	/* Advance lasttsig to be the last TSIG generated */
	CHECK(dns_message_getquerytsig(msg, xfr->mctx, &xfr->lasttsig));

	xfr->nmsg++;

 failure:
	if (msgname != NULL) {
		if (msgrds != NULL) {
			if (dns_rdataset_isassociated(msgrds))
				dns_rdataset_disassociate(msgrds);
			dns_message_puttemprdataset(msg, &msgrds);
		}
		if (msgrdl != NULL) {
			ISC_LIST_UNLINK(msgrdl->rdata, msgrdata, link);
			dns_message_puttemprdatalist(msg, &msgrdl);
		}
		if (msgrdata != NULL)
			dns_message_puttemprdata(msg, &msgrdata);
		dns_message_puttempname(msg, &msgname);
	}

	if (tcpmsg != NULL)
		dns_message_destroy(&tcpmsg);

	if (cleanup_cctx)
		dns_compress_invalidate(&cctx);
	/*
	 * Make sure to release any locks held by database
	 * iterators before returning from the event handler.
	 */
	xfr->stream->methods->pause(xfr->stream);

	if (result == ISC_R_SUCCESS)
		return;

	xfrout_fail(xfr, result, "sending zone data");
}
Ejemplo n.º 25
0
void
dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
		   dns_rdataset_t *rdataset)
{
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_trust_t trust;
	isc_region_t remaining, sigregion;
	isc_buffer_t source;
	dns_name_t tname;
	dns_rdatatype_t type;
	unsigned int count;
	dns_rdata_rrsig_t rrsig;
	unsigned char *raw;

	REQUIRE(ncacherdataset != NULL);
	REQUIRE(ncacherdataset->type == 0);
	REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
	REQUIRE(found != NULL);
	REQUIRE(!dns_rdataset_isassociated(rdataset));

	dns_rdataset_current(ncacherdataset, &rdata);
	isc_buffer_init(&source, rdata.data, rdata.length);
	isc_buffer_add(&source, rdata.length);

	dns_name_init(&tname, NULL);
	isc_buffer_remainingregion(&source, &remaining);
	dns_name_fromregion(found, &remaining);
	INSIST(remaining.length >= found->length);
	isc_buffer_forward(&source, found->length);
	remaining.length -= found->length;

	INSIST(remaining.length >= 5);
	type = isc_buffer_getuint16(&source);
	trust = isc_buffer_getuint8(&source);
	INSIST(trust <= dns_trust_ultimate);
	isc_buffer_remainingregion(&source, &remaining);

	rdataset->methods = &rdataset_methods;
	rdataset->rdclass = ncacherdataset->rdclass;
	rdataset->type = type;
	if (type == dns_rdatatype_rrsig) {
		/*
		 * Extract covers from RRSIG.
		 */
		raw = remaining.base;
		count = raw[0] * 256 + raw[1];
		INSIST(count > 0);
		raw += 2;
		sigregion.length = raw[0] * 256 + raw[1];
		raw += 2;
		sigregion.base = raw;
		dns_rdata_reset(&rdata);
		dns_rdata_fromregion(&rdata, rdataset->rdclass,
				     rdataset->type, &sigregion);
		(void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
		rdataset->covers = rrsig.covered;
	} else
		rdataset->covers = 0;
	rdataset->ttl = ncacherdataset->ttl;
	rdataset->trust = trust;
	rdataset->private1 = NULL;
	rdataset->private2 = NULL;

	rdataset->private3 = remaining.base;

	/*
	 * Reset iterator state.
	 */
	rdataset->privateuint4 = 0;
	rdataset->private5 = NULL;
	rdataset->private6 = NULL;
}
Ejemplo n.º 26
0
isc_result_t
dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
			  dns_rdatatype_t covers, dns_rdataset_t *rdataset)
{
	dns_name_t tname;
	dns_rdata_rrsig_t rrsig;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_rdataset_t clone;
	dns_rdatatype_t type;
	dns_trust_t trust = dns_trust_none;
	isc_buffer_t source;
	isc_region_t remaining, sigregion;
	isc_result_t result;
	unsigned char *raw;
	unsigned int count;

	REQUIRE(ncacherdataset != NULL);
	REQUIRE(ncacherdataset->type == 0);
	REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
	REQUIRE(name != NULL);
	REQUIRE(!dns_rdataset_isassociated(rdataset));

	dns_rdataset_init(&clone);
	dns_rdataset_clone(ncacherdataset, &clone);
	result = dns_rdataset_first(&clone);
	while (result == ISC_R_SUCCESS) {
		dns_rdataset_current(&clone, &rdata);
		isc_buffer_init(&source, rdata.data, rdata.length);
		isc_buffer_add(&source, rdata.length);
		dns_name_init(&tname, NULL);
		isc_buffer_remainingregion(&source, &remaining);
		dns_name_fromregion(&tname, &remaining);
		INSIST(remaining.length >= tname.length);
		isc_buffer_forward(&source, tname.length);
		isc_region_consume(&remaining, tname.length);

		INSIST(remaining.length >= 2);
		type = isc_buffer_getuint16(&source);
		isc_region_consume(&remaining, 2);

		if (type != dns_rdatatype_rrsig ||
		    !dns_name_equal(&tname, name)) {
			result = dns_rdataset_next(&clone);
			dns_rdata_reset(&rdata);
			continue;
		}

		INSIST(remaining.length >= 1);
		trust = isc_buffer_getuint8(&source);
		INSIST(trust <= dns_trust_ultimate);
		isc_region_consume(&remaining, 1);

		raw = remaining.base;
		count = raw[0] * 256 + raw[1];
		INSIST(count > 0);
		raw += 2;
		sigregion.length = raw[0] * 256 + raw[1];
		raw += 2;
		sigregion.base = raw;
		dns_rdata_reset(&rdata);
		dns_rdata_fromregion(&rdata, rdataset->rdclass,
				     dns_rdatatype_rrsig, &sigregion);
		(void)dns_rdata_tostruct(&rdata, &rrsig, NULL);
		if (rrsig.covered == covers) {
			isc_buffer_remainingregion(&source, &remaining);
			break;
		}

		result = dns_rdataset_next(&clone);
		dns_rdata_reset(&rdata);
	}
	dns_rdataset_disassociate(&clone);
	if (result == ISC_R_NOMORE)
		return (ISC_R_NOTFOUND);
	if (result != ISC_R_SUCCESS)
		return (result);

	INSIST(remaining.length != 0);

	rdataset->methods = &rdataset_methods;
	rdataset->rdclass = ncacherdataset->rdclass;
	rdataset->type = dns_rdatatype_rrsig;
	rdataset->covers = covers;
	rdataset->ttl = ncacherdataset->ttl;
	rdataset->trust = trust;
	rdataset->private1 = NULL;
	rdataset->private2 = NULL;

	rdataset->private3 = remaining.base;

	/*
	 * Reset iterator state.
	 */
	rdataset->privateuint4 = 0;
	rdataset->private5 = NULL;
	rdataset->private6 = NULL;
	return (ISC_R_SUCCESS);
}
Ejemplo n.º 27
0
isc_result_t
dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
		       dns_rdatatype_t type, dns_rdataset_t *rdataset)
{
	isc_result_t result;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	isc_region_t remaining;
	isc_buffer_t source;
	dns_name_t tname;
	dns_rdatatype_t ttype;
	dns_trust_t trust = dns_trust_none;
	dns_rdataset_t clone;

	REQUIRE(ncacherdataset != NULL);
	REQUIRE(ncacherdataset->type == 0);
	REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
	REQUIRE(name != NULL);
	REQUIRE(!dns_rdataset_isassociated(rdataset));
	REQUIRE(type != dns_rdatatype_rrsig);

	dns_rdataset_init(&clone);
	dns_rdataset_clone(ncacherdataset, &clone);
	result = dns_rdataset_first(&clone);
	while (result == ISC_R_SUCCESS) {
		dns_rdataset_current(&clone, &rdata);
		isc_buffer_init(&source, rdata.data, rdata.length);
		isc_buffer_add(&source, rdata.length);
		dns_name_init(&tname, NULL);
		isc_buffer_remainingregion(&source, &remaining);
		dns_name_fromregion(&tname, &remaining);
		INSIST(remaining.length >= tname.length);
		isc_buffer_forward(&source, tname.length);
		remaining.length -= tname.length;

		INSIST(remaining.length >= 3);
		ttype = isc_buffer_getuint16(&source);

		if (ttype == type && dns_name_equal(&tname, name)) {
			trust = isc_buffer_getuint8(&source);
			INSIST(trust <= dns_trust_ultimate);
			isc_buffer_remainingregion(&source, &remaining);
			break;
		}
		result = dns_rdataset_next(&clone);
		dns_rdata_reset(&rdata);
	}
	dns_rdataset_disassociate(&clone);
	if (result == ISC_R_NOMORE)
		return (ISC_R_NOTFOUND);
	if (result != ISC_R_SUCCESS)
		return (result);

	INSIST(remaining.length != 0);

	rdataset->methods = &rdataset_methods;
	rdataset->rdclass = ncacherdataset->rdclass;
	rdataset->type = type;
	rdataset->covers = 0;
	rdataset->ttl = ncacherdataset->ttl;
	rdataset->trust = trust;
	rdataset->private1 = NULL;
	rdataset->private2 = NULL;

	rdataset->private3 = remaining.base;

	/*
	 * Reset iterator state.
	 */
	rdataset->privateuint4 = 0;
	rdataset->private5 = NULL;
	rdataset->private6 = NULL;
	return (ISC_R_SUCCESS);
}
Ejemplo n.º 28
0
void
dns_root_checkhints(dns_view_t *view, dns_db_t *hints, dns_db_t *db) {
	isc_result_t result;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_rdata_ns_t ns;
	dns_rdataset_t hintns, rootns;
	const char *viewname = "", *sep = "";
	isc_stdtime_t now;
	dns_name_t *name;
	dns_fixedname_t fixed;

	REQUIRE(hints != NULL);
	REQUIRE(db != NULL);
	REQUIRE(view != NULL);

	isc_stdtime_get(&now);

	if (strcmp(view->name, "_bind") != 0 &&
	    strcmp(view->name, "_default") != 0) {
		viewname = view->name;
		sep = ": view ";
	}

	dns_rdataset_init(&hintns);
	dns_rdataset_init(&rootns);
	dns_fixedname_init(&fixed);
	name = dns_fixedname_name(&fixed);

	result = dns_db_find(hints, dns_rootname, NULL, dns_rdatatype_ns, 0,
			     now, NULL, name, &hintns, NULL);
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
			      DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
			      "checkhints%s%s: unable to get root NS rrset "
			      "from hints: %s", sep, viewname,
			      dns_result_totext(result));
		goto cleanup;
	}

	result = dns_db_find(db, dns_rootname, NULL, dns_rdatatype_ns, 0,
			     now, NULL, name, &rootns, NULL);
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
			      DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
			      "checkhints%s%s: unable to get root NS rrset "
			      "from cache: %s", sep, viewname,
			      dns_result_totext(result));
		goto cleanup;
	}

	/*
	 * Look for missing root NS names.
	 */
	result = dns_rdataset_first(&rootns);
	while (result == ISC_R_SUCCESS) {
		dns_rdataset_current(&rootns, &rdata);
		result = dns_rdata_tostruct(&rdata, &ns, NULL);
		RUNTIME_CHECK(result == ISC_R_SUCCESS);
		result = in_rootns(&hintns, &ns.name);
		if (result != ISC_R_SUCCESS) {
			char namebuf[DNS_NAME_FORMATSIZE];
			/* missing from hints */
			dns_name_format(&ns.name, namebuf, sizeof(namebuf));
			isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
				      DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
				      "checkhints%s%s: unable to find root "
				      "NS '%s' in hints", sep, viewname,
				      namebuf);
		} else
			check_address_records(view, hints, db, &ns.name, now);
		dns_rdata_reset(&rdata);
		result = dns_rdataset_next(&rootns);
	}
	if (result != ISC_R_NOMORE) {
		goto cleanup;
	}

	/*
	 * Look for extra root NS names.
	 */
	result = dns_rdataset_first(&hintns);
	while (result == ISC_R_SUCCESS) {
		dns_rdataset_current(&hintns, &rdata);
		result = dns_rdata_tostruct(&rdata, &ns, NULL);
		RUNTIME_CHECK(result == ISC_R_SUCCESS);
		result = in_rootns(&rootns, &ns.name);
		if (result != ISC_R_SUCCESS) {
			char namebuf[DNS_NAME_FORMATSIZE];
			/* extra entry in hints */
			dns_name_format(&ns.name, namebuf, sizeof(namebuf));
			isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
				      DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
				      "checkhints%s%s: extra NS '%s' in hints",
				      sep, viewname, namebuf);
		}
		dns_rdata_reset(&rdata);
		result = dns_rdataset_next(&hintns);
	}
	if (result != ISC_R_NOMORE) {
		goto cleanup;
	}

 cleanup:
	if (dns_rdataset_isassociated(&rootns))
		dns_rdataset_disassociate(&rootns);
	if (dns_rdataset_isassociated(&hintns))
		dns_rdataset_disassociate(&hintns);
}
Ejemplo n.º 29
0
static void
check_address_records(dns_view_t *view, dns_db_t *hints, dns_db_t *db,
		      dns_name_t *name, isc_stdtime_t now)
{
	isc_result_t hresult, rresult, result;
	dns_rdataset_t hintrrset, rootrrset;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_name_t *foundname;
	dns_fixedname_t fixed;

	dns_rdataset_init(&hintrrset);
	dns_rdataset_init(&rootrrset);
	dns_fixedname_init(&fixed);
	foundname = dns_fixedname_name(&fixed);

	hresult = dns_db_find(hints, name, NULL, dns_rdatatype_a, 0,
			      now, NULL, foundname, &hintrrset, NULL);
	rresult = dns_db_find(db, name, NULL, dns_rdatatype_a,
			      DNS_DBFIND_GLUEOK, now, NULL, foundname,
			      &rootrrset, NULL);
	if (hresult == ISC_R_SUCCESS &&
	    (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
		result = dns_rdataset_first(&rootrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&rootrrset, &rdata);
			if (!inrrset(&hintrrset, &rdata))
				report(view, name, ISC_TRUE, &rdata);
			result = dns_rdataset_next(&rootrrset);
		}
		result = dns_rdataset_first(&hintrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&hintrrset, &rdata);
			if (!inrrset(&rootrrset, &rdata))
				report(view, name, ISC_FALSE, &rdata);
			result = dns_rdataset_next(&hintrrset);
		}
	}
	if (hresult == ISC_R_NOTFOUND &&
	    (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
		result = dns_rdataset_first(&rootrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&rootrrset, &rdata);
			report(view, name, ISC_TRUE, &rdata);
			result = dns_rdataset_next(&rootrrset);
		}
	}
	if (dns_rdataset_isassociated(&rootrrset))
		dns_rdataset_disassociate(&rootrrset);
	if (dns_rdataset_isassociated(&hintrrset))
		dns_rdataset_disassociate(&hintrrset);

	/*
	 * Check AAAA records.
	 */
	hresult = dns_db_find(hints, name, NULL, dns_rdatatype_aaaa, 0,
			      now, NULL, foundname, &hintrrset, NULL);
	rresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
			      DNS_DBFIND_GLUEOK, now, NULL, foundname,
			      &rootrrset, NULL);
	if (hresult == ISC_R_SUCCESS &&
	    (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
		result = dns_rdataset_first(&rootrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&rootrrset, &rdata);
			if (!inrrset(&hintrrset, &rdata))
				report(view, name, ISC_TRUE, &rdata);
			dns_rdata_reset(&rdata);
			result = dns_rdataset_next(&rootrrset);
		}
		result = dns_rdataset_first(&hintrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&hintrrset, &rdata);
			if (!inrrset(&rootrrset, &rdata))
				report(view, name, ISC_FALSE, &rdata);
			dns_rdata_reset(&rdata);
			result = dns_rdataset_next(&hintrrset);
		}
	}
	if (hresult == ISC_R_NOTFOUND &&
	    (rresult == ISC_R_SUCCESS || rresult == DNS_R_GLUE)) {
		result = dns_rdataset_first(&rootrrset);
		while (result == ISC_R_SUCCESS) {
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&rootrrset, &rdata);
			report(view, name, ISC_TRUE, &rdata);
			dns_rdata_reset(&rdata);
			result = dns_rdataset_next(&rootrrset);
		}
	}
	if (dns_rdataset_isassociated(&rootrrset))
		dns_rdataset_disassociate(&rootrrset);
	if (dns_rdataset_isassociated(&hintrrset))
		dns_rdataset_disassociate(&hintrrset);
}
Ejemplo n.º 30
0
static void
query(void) {
	char buf[1024];
	dns_fixedname_t name;
	dns_fixedname_t found;
	dns_db_t *db;
	char *s;
	isc_buffer_t buffer;
	isc_result_t result;
	dns_rdataset_t rdataset;
	dns_rdataset_t sigset;
	fd_set rfdset;

	db = NULL;
	result = dns_zone_getdb(zone, &db);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "%s() returned %s\n", "dns_zone_getdb",
			dns_result_totext(result));
		return;
	}

	dns_fixedname_init(&found);
	dns_rdataset_init(&rdataset);
	dns_rdataset_init(&sigset);

	do {

		fprintf(stdout, "zone_test ");
		fflush(stdout);
		FD_ZERO(&rfdset);
		FD_SET(0, &rfdset);
		select(1, &rfdset, NULL, NULL, NULL);
		if (fgets(buf, sizeof(buf), stdin) == NULL) {
			fprintf(stdout, "\n");
			break;
		}
		buf[sizeof(buf) - 1] = '\0';

		s = strchr(buf, '\n');
		if (s != NULL)
			*s = '\0';
		s = strchr(buf, '\r');
		if (s != NULL)
			*s = '\0';
		if (strcmp(buf, "dump") == 0) {
			dns_zone_dumptostream(zone, stdout);
			continue;
		}
		if (strlen(buf) == 0U)
			continue;
		dns_fixedname_init(&name);
		isc_buffer_init(&buffer, buf, strlen(buf));
		isc_buffer_add(&buffer, strlen(buf));
		result = dns_name_fromtext(dns_fixedname_name(&name),
				  &buffer, dns_rootname, 0, NULL);
		ERRCONT(result, "dns_name_fromtext");

		result = dns_db_find(db, dns_fixedname_name(&name),
				     NULL /*vesion*/,
				     dns_rdatatype_a,
				     0 /*options*/,
				     0 /*time*/,
				     NULL /*nodep*/,
				     dns_fixedname_name(&found),
				     &rdataset, &sigset);
		fprintf(stderr, "%s() returned %s\n", "dns_db_find",
			dns_result_totext(result));
		switch (result) {
		case DNS_R_DELEGATION:
			print_rdataset(dns_fixedname_name(&found), &rdataset);
			break;
		case ISC_R_SUCCESS:
			print_rdataset(dns_fixedname_name(&name), &rdataset);
			break;
		default:
			break;
		}

		if (dns_rdataset_isassociated(&rdataset))
			dns_rdataset_disassociate(&rdataset);
		if (dns_rdataset_isassociated(&sigset))
			dns_rdataset_disassociate(&sigset);
	} while (1);
	dns_rdataset_invalidate(&rdataset);
	dns_db_detach(&db);
}