Beispiel #1
0
/*
 * Driver-specific implementation of dns_db_create().
 *
 * @param[in] argv      Database-specific parameters from dns_db_create().
 * @param[in] driverarg Driver-specific parameter from dns_db_register().
 */
isc_result_t
create_db(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
	  dns_rdataclass_t rdclass, unsigned int argc, char *argv[],
	  void *driverarg, dns_db_t **dbp)
{
	sampledb_t *sampledb = NULL;
	isc_result_t result;
	dns_dbversion_t *version = NULL;
	struct in_addr a_addr;

	REQUIRE(type == dns_dbtype_zone);
	REQUIRE(rdclass == dns_rdataclass_in);
	REQUIRE(argc == 0);
	REQUIRE(argv != NULL);
	REQUIRE(driverarg != NULL); /* pointer to driver instance */
	REQUIRE(dbp != NULL && *dbp == NULL);

	UNUSED(driverarg); /* no driver-specific configuration */

	a_addr.s_addr = 0x0100007fU;

	CHECKED_MEM_GET_PTR(mctx, sampledb);
	ZERO_PTR(sampledb);

	isc_mem_attach(mctx, &sampledb->common.mctx);
	dns_name_init(&sampledb->common.origin, NULL);
	isc_ondestroy_init(&sampledb->common.ondest);

	sampledb->common.magic = DNS_DB_MAGIC;
	sampledb->common.impmagic = SAMPLEDB_MAGIC;

	sampledb->common.methods = &sampledb_methods;
	sampledb->common.attributes = 0;
	sampledb->common.rdclass = rdclass;

	CHECK(dns_name_dupwithoffsets(origin, mctx, &sampledb->common.origin));

	CHECK(isc_refcount_init(&sampledb->refs, 1));

	/* Translate instance name to instance pointer. */
	sampledb->inst = driverarg;

	/* Create internal instance of RBT DB implementation from BIND. */
	CHECK(dns_db_create(mctx, "rbt", origin, dns_dbtype_zone,
			    dns_rdataclass_in, 0, NULL, &sampledb->rbtdb));

	/* Create fake SOA, NS, and A records to make database loadable. */
	CHECK(dns_db_newversion(sampledb->rbtdb, &version));
	CHECK(add_soa(sampledb->rbtdb, version, origin, origin, origin));
	CHECK(add_ns(sampledb->rbtdb, version, origin, origin));
	CHECK(add_a(sampledb->rbtdb, version, origin, a_addr));
	dns_db_closeversion(sampledb->rbtdb, &version, ISC_TRUE);

	*dbp = (dns_db_t *)sampledb;

	return (ISC_R_SUCCESS);

cleanup:
	if (sampledb != NULL) {
		if (dns_name_dynamic(&sampledb->common.origin))
			dns_name_free(&sampledb->common.origin, mctx);

		isc_mem_putanddetach(&sampledb->common.mctx, sampledb,
				     sizeof(*sampledb));
	}

	return (result);
}
Beispiel #2
0
struct dns_msg* 
val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo, 
	struct regional* region, struct rrset_cache* rrset_cache, 
	ldns_buffer* buf, uint32_t now, int addsoa, uint8_t* topname)
{
	struct dns_msg* msg;
	struct ub_packed_rrset_key* rrset;
	uint8_t* zname;
	size_t zname_len;
	int zname_labs;
	struct val_neg_zone* zone;

	/* only for DS queries */
	if(qinfo->qtype != LDNS_RR_TYPE_DS)
		return NULL;
	log_assert(!topname || dname_subdomain_c(qinfo->qname, topname));

	/* see if info from neg cache is available 
	 * For NSECs, because there is no optout; a DS next to a delegation
	 * always has exactly an NSEC for it itself; check its DS bit.
	 * flags=0 (not the zone apex).
	 */
	rrset = grab_nsec(rrset_cache, qinfo->qname, qinfo->qname_len,
		LDNS_RR_TYPE_NSEC, qinfo->qclass, 0, region, 1, 
		qinfo->qtype, now);
	if(rrset) {
		/* return msg with that rrset */
		if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len, 
			qinfo->qtype, qinfo->qclass, region, 2))) 
			return NULL;
		/* TTL already subtracted in grab_nsec */
		if(!dns_msg_authadd(msg, region, rrset, 0)) 
			return NULL;
		if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL))
			return NULL;
		return msg;
	}

	/* check NSEC3 neg cache for type DS */
	/* need to look one zone higher for DS type */
	zname = qinfo->qname;
	zname_len = qinfo->qname_len;
	dname_remove_label(&zname, &zname_len);
	zname_labs = dname_count_labels(zname);

	/* lookup closest zone */
	lock_basic_lock(&neg->lock);
	zone = neg_closest_zone_parent(neg, zname, zname_len, zname_labs, 
		qinfo->qclass);
	while(zone && !zone->in_use)
		zone = zone->parent;
	/* check that the zone is not too high up so that we do not pick data
	 * out of a zone that is above the last-seen key (or trust-anchor). */
	if(zone && topname) {
		if(!dname_subdomain_c(zone->name, topname))
			zone = NULL;
	}
	if(!zone) {
		lock_basic_unlock(&neg->lock);
		return NULL;
	}

	msg = neg_nsec3_proof_ds(zone, qinfo->qname, qinfo->qname_len, 
		zname_labs+1, buf, rrset_cache, region, now, topname);
	if(msg && addsoa && !add_soa(rrset_cache, now, region, msg, zone)) {
		lock_basic_unlock(&neg->lock);
		return NULL;
	}
	lock_basic_unlock(&neg->lock);
	return msg;
}