Ejemplo n.º 1
0
Archivo: md_3.c Proyecto: 274914765/C
static inline isc_result_t totext_md (ARGS_TOTEXT)
{
    isc_region_t region;

    dns_name_t name;

    dns_name_t prefix;

    isc_boolean_t sub;

    REQUIRE (rdata->type == 3);
    REQUIRE (rdata->length != 0);

    dns_name_init (&name, NULL);
    dns_name_init (&prefix, NULL);

    dns_rdata_toregion (rdata, &region);
    dns_name_fromregion (&name, &region);

    sub = name_prefix (&name, tctx->origin, &prefix);

    return (dns_name_totext (&prefix, sub, target));
}
static inline isc_result_t
tostruct_in_nsap_ptr(ARGS_TOSTRUCT) {
	isc_region_t region;
	dns_rdata_in_nsap_ptr_t *nsap_ptr = target;
	dns_name_t name;

	REQUIRE(rdata->type == 23);
	REQUIRE(rdata->rdclass == 1);
	REQUIRE(target != NULL);
	REQUIRE(rdata->length != 0);

	nsap_ptr->common.rdclass = rdata->rdclass;
	nsap_ptr->common.rdtype = rdata->type;
	ISC_LINK_INIT(&nsap_ptr->common, link);

	dns_name_init(&name, NULL);
	dns_rdata_toregion(rdata, &region);
	dns_name_fromregion(&name, &region);
	dns_name_init(&nsap_ptr->owner, NULL);
	RETERR(name_duporclone(&name, mctx, &nsap_ptr->owner));
	nsap_ptr->mctx = mctx;
	return (ISC_R_SUCCESS);
}
Ejemplo n.º 3
0
Archivo: md_3.c Proyecto: 274914765/C
static inline isc_result_t tostruct_md (ARGS_TOSTRUCT)
{
    dns_rdata_md_t *md = target;

    isc_region_t r;

    dns_name_t name;

    REQUIRE (rdata->type == 3);
    REQUIRE (target != NULL);
    REQUIRE (rdata->length != 0);

    md->common.rdclass = rdata->rdclass;
    md->common.rdtype = rdata->type;
    ISC_LINK_INIT (&md->common, link);

    dns_name_init (&name, NULL);
    dns_rdata_toregion (rdata, &r);
    dns_name_fromregion (&name, &r);
    dns_name_init (&md->md, NULL);
    RETERR (name_duporclone (&name, mctx, &md->md));
    md->mctx = mctx;
    return (ISC_R_SUCCESS);
}
Ejemplo n.º 4
0
static inline isc_result_t
tostruct_lp(ARGS_TOSTRUCT) {
	isc_region_t region;
	dns_rdata_lp_t *lp = target;
	dns_name_t name;

	REQUIRE(rdata->type == dns_rdatatype_lp);
	REQUIRE(target != NULL);
	REQUIRE(rdata->length != 0);

	lp->common.rdclass = rdata->rdclass;
	lp->common.rdtype = rdata->type;
	ISC_LINK_INIT(&lp->common, link);

	dns_name_init(&name, NULL);
	dns_rdata_toregion(rdata, &region);
	lp->pref = uint16_fromregion(&region);
	isc_region_consume(&region, 2);
	dns_name_fromregion(&name, &region);
	dns_name_init(&lp->lp, NULL);
	RETERR(name_duporclone(&name, mctx, &lp->lp));
	lp->mctx = mctx;
	return (ISC_R_SUCCESS);
}
static inline isc_result_t
towire_rt(ARGS_TOWIRE) {
	dns_name_t name;
	dns_offsets_t offsets;
	isc_region_t region;
	isc_region_t tr;

	REQUIRE(rdata->type == 21);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	isc_buffer_availableregion(target, &tr);
	dns_rdata_toregion(rdata, &region);
	if (tr.length < 2)
		return (ISC_R_NOSPACE);
	memmove(tr.base, region.base, 2);
	isc_region_consume(&region, 2);
	isc_buffer_add(target, 2);

	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &region);

	return (dns_name_towire(&name, cctx, target));
}
Ejemplo n.º 6
0
static inline isc_result_t
totext_afsdb(ARGS_TOTEXT) {
	dns_name_t name;
	dns_name_t prefix;
	isc_region_t region;
	char buf[sizeof("64000 ")];
	isc_boolean_t sub;
	unsigned int num;

	REQUIRE(rdata->type == 18);
	REQUIRE(rdata->length != 0);

	dns_name_init(&name, NULL);
	dns_name_init(&prefix, NULL);

	dns_rdata_toregion(rdata, &region);
	num = uint16_fromregion(&region);
	isc_region_consume(&region, 2);
	sprintf(buf, "%u ", num);
	RETERR(str_totext(buf, target));
	dns_name_fromregion(&name, &region);
	sub = name_prefix(&name, tctx->origin, &prefix);
	return (dns_name_totext(&prefix, sub, target));
}
Ejemplo n.º 7
0
static inline isc_result_t
towire_sig(ARGS_TOWIRE) {
	isc_region_t sr;
	dns_name_t name;
	dns_offsets_t offsets;

	REQUIRE(rdata->type == dns_rdatatype_sig);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	dns_rdata_toregion(rdata, &sr);
	/*
	 * type covered: 2
	 * algorithm: 1
	 * labels: 1
	 * original ttl: 4
	 * signature expiration: 4
	 * time signed: 4
	 * key footprint: 2
	 */
	RETERR(mem_tobuffer(target, sr.base, 18));
	isc_region_consume(&sr, 18);

	/*
	 * Signer.
	 */
	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &sr);
	isc_region_consume(&sr, name_length(&name));
	RETERR(dns_name_towire(&name, cctx, target));

	/*
	 * Signature.
	 */
	return (mem_tobuffer(target, sr.base, sr.length));
}
Ejemplo n.º 8
0
static inline isc_boolean_t
checknames_ptr(ARGS_CHECKNAMES) {
	isc_region_t region;
	dns_name_t name;

	REQUIRE(rdata->type == 12);

	if (rdata->rdclass != dns_rdataclass_in)
	    return (ISC_TRUE);

	if (dns_name_issubdomain(owner, &in_addr_arpa) ||
	    dns_name_issubdomain(owner, &ip6_arpa) ||
	    dns_name_issubdomain(owner, &ip6_int)) {
		dns_rdata_toregion(rdata, &region);
		dns_name_init(&name, NULL);
		dns_name_fromregion(&name, &region);
		if (!dns_name_ishostname(&name, ISC_FALSE)) {
			if (bad != NULL)
				dns_name_clone(&name, bad);
			return (ISC_FALSE);
		}
	}
	return (ISC_TRUE);
}
Ejemplo n.º 9
0
static inline isc_result_t
towire_in_srv(ARGS_TOWIRE) {
	dns_name_t name;
	dns_offsets_t offsets;
	isc_region_t sr;

	REQUIRE(rdata->type == 33);
	REQUIRE(rdata->length != 0);

	dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
	/*
	 * Priority, weight, port.
	 */
	dns_rdata_toregion(rdata, &sr);
	RETERR(mem_tobuffer(target, sr.base, 6));
	isc_region_consume(&sr, 6);

	/*
	 * Target.
	 */
	dns_name_init(&name, offsets);
	dns_name_fromregion(&name, &sr);
	return (dns_name_towire(&name, cctx, target));
}
Ejemplo n.º 10
0
static inline isc_result_t
totext_tkey(ARGS_TOTEXT) {
	isc_region_t sr, dr;
	char buf[sizeof("4294967295 ")];
	unsigned long n;
	dns_name_t name;
	dns_name_t prefix;
	isc_boolean_t sub;

	REQUIRE(rdata->type == 249);
	REQUIRE(rdata->length != 0);

	dns_rdata_toregion(rdata, &sr);

	/*
	 * Algorithm.
	 */
	dns_name_init(&name, NULL);
	dns_name_init(&prefix, NULL);
	dns_name_fromregion(&name, &sr);
	sub = name_prefix(&name, tctx->origin, &prefix);
	RETERR(dns_name_totext(&prefix, sub, target));
	RETERR(str_totext(" ", target));
	isc_region_consume(&sr, name_length(&name));

	/*
	 * Inception.
	 */
	n = uint32_fromregion(&sr);
	isc_region_consume(&sr, 4);
	sprintf(buf, "%lu ", n);
	RETERR(str_totext(buf, target));

	/*
	 * Expiration.
	 */
	n = uint32_fromregion(&sr);
	isc_region_consume(&sr, 4);
	sprintf(buf, "%lu ", n);
	RETERR(str_totext(buf, target));

	/*
	 * Mode.
	 */
	n = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);
	sprintf(buf, "%lu ", n);
	RETERR(str_totext(buf, target));

	/*
	 * Error.
	 */
	n = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);
	if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS)
		RETERR(str_totext(" ", target));
	else {
		sprintf(buf, "%lu ", n);
		RETERR(str_totext(buf, target));
	}

	/*
	 * Key Size.
	 */
	n = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);
	sprintf(buf, "%lu", n);
	RETERR(str_totext(buf, target));

	/*
	 * Key Data.
	 */
	REQUIRE(n <= sr.length);
	dr = sr;
	dr.length = n;
	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext(" (", target));
	RETERR(str_totext(tctx->linebreak, target));
	RETERR(isc_base64_totext(&dr, tctx->width - 2,
				 tctx->linebreak, target));
	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext(" ) ", target));
	else
		RETERR(str_totext(" ", target));
	isc_region_consume(&sr, n);

	/*
	 * Other Size.
	 */
	n = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);
	sprintf(buf, "%lu", n);
	RETERR(str_totext(buf, target));

	/*
	 * Other Data.
	 */
	REQUIRE(n <= sr.length);
	if (n != 0U) {
	    dr = sr;
	    dr.length = n;
	    if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		    RETERR(str_totext(" (", target));
	    RETERR(str_totext(tctx->linebreak, target));
	    RETERR(isc_base64_totext(&dr, tctx->width - 2,
				     tctx->linebreak, target));
	    if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		    RETERR(str_totext(" )", target));
	}
	return (ISC_R_SUCCESS);
}
Ejemplo n.º 11
0
static inline isc_result_t
tostruct_sig(ARGS_TOSTRUCT) {
	isc_region_t sr;
	dns_rdata_sig_t *sig = target;
	dns_name_t signer;

	REQUIRE(rdata->type == dns_rdatatype_sig);
	REQUIRE(target != NULL);
	REQUIRE(rdata->length != 0);

	sig->common.rdclass = rdata->rdclass;
	sig->common.rdtype = rdata->type;
	ISC_LINK_INIT(&sig->common, link);

	dns_rdata_toregion(rdata, &sr);

	/*
	 * Type covered.
	 */
	sig->covered = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);

	/*
	 * Algorithm.
	 */
	sig->algorithm = uint8_fromregion(&sr);
	isc_region_consume(&sr, 1);

	/*
	 * Labels.
	 */
	sig->labels = uint8_fromregion(&sr);
	isc_region_consume(&sr, 1);

	/*
	 * Original TTL.
	 */
	sig->originalttl = uint32_fromregion(&sr);
	isc_region_consume(&sr, 4);

	/*
	 * Expire time.
	 */
	sig->timeexpire = uint32_fromregion(&sr);
	isc_region_consume(&sr, 4);

	/*
	 * Time signed.
	 */
	sig->timesigned = uint32_fromregion(&sr);
	isc_region_consume(&sr, 4);

	/*
	 * Key ID.
	 */
	sig->keyid = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);

	dns_name_init(&signer, NULL);
	dns_name_fromregion(&signer, &sr);
	dns_name_init(&sig->signer, NULL);
	RETERR(name_duporclone(&signer, mctx, &sig->signer));
	isc_region_consume(&sr, name_length(&sig->signer));

	/*
	 * Signature.
	 */
	sig->siglen = sr.length;
	sig->signature = mem_maybedup(mctx, sr.base, sig->siglen);
	if (sig->signature == NULL)
		goto cleanup;


	sig->mctx = mctx;
	return (ISC_R_SUCCESS);

 cleanup:
	if (mctx != NULL)
		dns_name_free(&sig->signer, mctx);
	return (ISC_R_NOMEMORY);
}
Ejemplo n.º 12
0
static inline isc_result_t
totext_sig(ARGS_TOTEXT) {
	isc_region_t sr;
	char buf[sizeof("4294967295")];
	dns_rdatatype_t covered;
	unsigned long ttl;
	unsigned long when;
	unsigned long exp;
	unsigned long foot;
	dns_name_t name;
	dns_name_t prefix;
	isc_boolean_t sub;

	REQUIRE(rdata->type == dns_rdatatype_sig);
	REQUIRE(rdata->length != 0);

	dns_rdata_toregion(rdata, &sr);

	/*
	 * Type covered.
	 */
	covered = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);
	/*
	 * XXXAG We should have something like dns_rdatatype_isknown()
	 * that does the right thing with type 0.
	 */
	if (dns_rdatatype_isknown(covered) && covered != 0) {
		RETERR(dns_rdatatype_totext(covered, target));
	} else {
		sprintf(buf, "%u", covered);
		RETERR(str_totext(buf, target));
	}
	RETERR(str_totext(" ", target));

	/*
	 * Algorithm.
	 */
	sprintf(buf, "%u", sr.base[0]);
	isc_region_consume(&sr, 1);
	RETERR(str_totext(buf, target));
	RETERR(str_totext(" ", target));

	/*
	 * Labels.
	 */
	sprintf(buf, "%u", sr.base[0]);
	isc_region_consume(&sr, 1);
	RETERR(str_totext(buf, target));
	RETERR(str_totext(" ", target));

	/*
	 * Ttl.
	 */
	ttl = uint32_fromregion(&sr);
	isc_region_consume(&sr, 4);
	sprintf(buf, "%lu", ttl);
	RETERR(str_totext(buf, target));
	RETERR(str_totext(" ", target));

	/*
	 * Sig exp.
	 */
	exp = uint32_fromregion(&sr);
	isc_region_consume(&sr, 4);
	RETERR(dns_time32_totext(exp, target));

	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext(" (", target));
	RETERR(str_totext(tctx->linebreak, target));

	/*
	 * Time signed.
	 */
	when = uint32_fromregion(&sr);
	isc_region_consume(&sr, 4);
	RETERR(dns_time32_totext(when, target));
	RETERR(str_totext(" ", target));

	/*
	 * Footprint.
	 */
	foot = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);
	sprintf(buf, "%lu", foot);
	RETERR(str_totext(buf, target));
	RETERR(str_totext(" ", target));

	/*
	 * Signer.
	 */
	dns_name_init(&name, NULL);
	dns_name_init(&prefix, NULL);
	dns_name_fromregion(&name, &sr);
	isc_region_consume(&sr, name_length(&name));
	sub = name_prefix(&name, tctx->origin, &prefix);
	RETERR(dns_name_totext(&prefix, sub, target));

	/*
	 * Sig.
	 */
	RETERR(str_totext(tctx->linebreak, target));
	if (tctx->width == 0)   /* No splitting */
		RETERR(isc_base64_totext(&sr, 60, "", target));
	else
		RETERR(isc_base64_totext(&sr, tctx->width - 2,
					 tctx->linebreak, target));
	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext(" )", target));

	return (ISC_R_SUCCESS);
}
Ejemplo n.º 13
0
static inline int
compare_naptr(ARGS_COMPARE) {
	dns_name_t name1;
	dns_name_t name2;
	isc_region_t region1;
	isc_region_t region2;
	int order, len;

	REQUIRE(rdata1->type == rdata2->type);
	REQUIRE(rdata1->rdclass == rdata2->rdclass);
	REQUIRE(rdata1->type == dns_rdatatype_naptr);
	REQUIRE(rdata1->length != 0);
	REQUIRE(rdata2->length != 0);

	dns_rdata_toregion(rdata1, &region1);
	dns_rdata_toregion(rdata2, &region2);

	/*
	 * Order, preference.
	 */
	order = memcmp(region1.base, region2.base, 4);
	if (order != 0)
		return (order < 0 ? -1 : 1);
	isc_region_consume(&region1, 4);
	isc_region_consume(&region2, 4);

	/*
	 * Flags.
	 */
	len = ISC_MIN(region1.base[0], region2.base[0]);
	order = memcmp(region1.base, region2.base, len + 1);
	if (order != 0)
		return (order < 0 ? -1 : 1);
	isc_region_consume(&region1, region1.base[0] + 1);
	isc_region_consume(&region2, region2.base[0] + 1);

	/*
	 * Service.
	 */
	len = ISC_MIN(region1.base[0], region2.base[0]);
	order = memcmp(region1.base, region2.base, len + 1);
	if (order != 0)
		return (order < 0 ? -1 : 1);
	isc_region_consume(&region1, region1.base[0] + 1);
	isc_region_consume(&region2, region2.base[0] + 1);

	/*
	 * Regexp.
	 */
	len = ISC_MIN(region1.base[0], region2.base[0]);
	order = memcmp(region1.base, region2.base, len + 1);
	if (order != 0)
		return (order < 0 ? -1 : 1);
	isc_region_consume(&region1, region1.base[0] + 1);
	isc_region_consume(&region2, region2.base[0] + 1);

	/*
	 * Replacement.
	 */
	dns_name_init(&name1, NULL);
	dns_name_init(&name2, NULL);

	dns_name_fromregion(&name1, &region1);
	dns_name_fromregion(&name2, &region2);

	return (dns_name_rdatacompare(&name1, &name2));
}
Ejemplo n.º 14
0
void
dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
		 const dns_name_t *prefix, isc_uint16_t offset)
{
	dns_name_t tname, xname;
	unsigned int start;
	unsigned int n;
	unsigned int count;
	unsigned int i;
	dns_compressnode_t *node;
	unsigned int length;
	unsigned int tlength;
	isc_uint16_t toffset;
	unsigned char *tmp;
	isc_region_t r;

	REQUIRE(VALID_CCTX(cctx));
	REQUIRE(dns_name_isabsolute(name));

	if (ISC_UNLIKELY((cctx->allowed & DNS_COMPRESS_ENABLED) == 0))
		return;

	if (offset >= 0x4000)
		return;
	dns_name_init(&tname, NULL);
	dns_name_init(&xname, NULL);

	n = dns_name_countlabels(name);
	count = dns_name_countlabels(prefix);
	if (dns_name_isabsolute(prefix))
		count--;
	if (count == 0)
		return;
	start = 0;
	dns_name_toregion(name, &r);
	length = r.length;
	tmp = isc_mem_get(cctx->mctx, length);
	if (tmp == NULL)
		return;
	/*
	 * Copy name data to 'tmp' and make 'r' use 'tmp'.
	 */
	memmove(tmp, r.base, r.length);
	r.base = tmp;
	dns_name_fromregion(&xname, &r);

	if (count > 2U)
		count = 2U;

	while (count > 0) {
		unsigned char ch;

		dns_name_getlabelsequence(&xname, start, n, &tname);
		/*
		 * We calculate the table index using the first
		 * character in the first label of tname.
		 */
		ch = tname.ndata[1];
		i = tableindex[ch];
		tlength = name_length(&tname);
		toffset = (isc_uint16_t)(offset + (length - tlength));
		if (toffset >= 0x4000)
			break;
		/*
		 * Create a new node and add it.
		 */
		if (cctx->count < DNS_COMPRESS_INITIALNODES)
			node = &cctx->initialnodes[cctx->count];
		else {
			node = isc_mem_get(cctx->mctx,
					   sizeof(dns_compressnode_t));
			if (node == NULL)
				break;
		}
		node->count = cctx->count++;
		/*
		 * 'node->r.base' becomes 'tmp' when start == 0.
		 * Record this by setting 0x8000 so it can be freed later.
		 */
		if (start == 0)
			toffset |= 0x8000;
		node->offset = toffset;
		dns_name_toregion(&tname, &node->r);
		dns_name_init(&node->name, NULL);
		node->name.length = node->r.length;
		node->name.ndata = node->r.base;
		node->name.labels = tname.labels;
		node->name.attributes = DNS_NAMEATTR_ABSOLUTE;
		node->next = cctx->table[i];
		cctx->table[i] = node;
		start++;
		n--;
		count--;
	}

	if (start == 0)
		isc_mem_put(cctx->mctx, tmp, length);
}
Ejemplo n.º 15
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.º 16
0
static inline isc_result_t
totext_soa(ARGS_TOTEXT) {
	isc_region_t dregion;
	dns_name_t mname;
	dns_name_t rname;
	dns_name_t prefix;
	isc_boolean_t sub;
	int i;
	isc_boolean_t multiline;
	isc_boolean_t comment;

	REQUIRE(rdata->type == 6);
	REQUIRE(rdata->length != 0);

	multiline = ISC_TF((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0);
	comment = ISC_TF((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0);

	dns_name_init(&mname, NULL);
	dns_name_init(&rname, NULL);
	dns_name_init(&prefix, NULL);

	dns_rdata_toregion(rdata, &dregion);

	dns_name_fromregion(&mname, &dregion);
	isc_region_consume(&dregion, name_length(&mname));

	dns_name_fromregion(&rname, &dregion);
	isc_region_consume(&dregion, name_length(&rname));

	sub = name_prefix(&mname, tctx->origin, &prefix);
	RETERR(dns_name_totext(&prefix, sub, target));

	RETERR(str_totext(" ", target));

	sub = name_prefix(&rname, tctx->origin, &prefix);
	RETERR(dns_name_totext(&prefix, sub, target));

	if (multiline)
		RETERR(str_totext(" (" , target));
	RETERR(str_totext(tctx->linebreak, target));

	for (i = 0; i < 5; i++) {
		char buf[sizeof("2147483647")];
		unsigned long num;
		int numlen;
		num = uint32_fromregion(&dregion);
		isc_region_consume(&dregion, 4);
		numlen = snprintf(buf, sizeof(buf), "%lu", num);
		INSIST(numlen != -1 && (size_t)numlen < sizeof(buf));
		RETERR(str_totext(buf, target));
		if (multiline && comment) {
			RETERR(str_totext("           ; " +
			    (unsigned int)numlen, target));
			RETERR(str_totext(soa_fieldnames[i], target));
			/* Print times in week/day/hour/minute/second form */
			if (i >= 1) {
				RETERR(str_totext(" (", target));
				RETERR(dns_ttl_totext(num, ISC_TRUE, target));
				RETERR(str_totext(")", target));
			}
			RETERR(str_totext(tctx->linebreak, target));
		} else if (i < 4) {
			RETERR(str_totext(tctx->linebreak, target));			
		}
	}

	if (multiline)
		RETERR(str_totext(")", target));

	return (ISC_R_SUCCESS);
}
Ejemplo n.º 17
0
static inline isc_result_t
tostruct_ipseckey(ARGS_TOSTRUCT) {
	isc_region_t region;
	dns_rdata_ipseckey_t *ipseckey = target;
	dns_name_t name;
	isc_uint32_t n;

	REQUIRE(rdata->type == 45);
	REQUIRE(target != NULL);
	REQUIRE(rdata->length >= 3);

	if (rdata->data[1] > 3U)
		return (ISC_R_NOTIMPLEMENTED);

	ipseckey->common.rdclass = rdata->rdclass;
	ipseckey->common.rdtype = rdata->type;
	ISC_LINK_INIT(&ipseckey->common, link);

	dns_name_init(&name, NULL);
	dns_rdata_toregion(rdata, &region);

	ipseckey->precedence = uint8_fromregion(&region);
	isc_region_consume(&region, 1);

	ipseckey->gateway_type = uint8_fromregion(&region);
	isc_region_consume(&region, 1);

	ipseckey->algorithm = uint8_fromregion(&region);
	isc_region_consume(&region, 1);

	switch (ipseckey->gateway_type) {
	case 0:
		break;

	case 1:
		n = uint32_fromregion(&region);
		ipseckey->in_addr.s_addr = htonl(n);
		isc_region_consume(&region, 4);
		break;

	case 2:
		memmove(ipseckey->in6_addr.s6_addr, region.base, 16);
		isc_region_consume(&region, 16);
		break;

	case 3:
		dns_name_init(&ipseckey->gateway, NULL);
		dns_name_fromregion(&name, &region);
		RETERR(name_duporclone(&name, mctx, &ipseckey->gateway));
		isc_region_consume(&region, name_length(&name));
		break;
	}

	ipseckey->keylength = region.length;
	if (ipseckey->keylength != 0U) {
		ipseckey->key = mem_maybedup(mctx, region.base,
					     ipseckey->keylength);
		if (ipseckey->key == NULL) {
			if (ipseckey->gateway_type == 3)
				dns_name_free(&ipseckey->gateway,
					      ipseckey->mctx);
			return (ISC_R_NOMEMORY);
		}
	} else
		ipseckey->key = NULL;

	ipseckey->mctx = mctx;
	return (ISC_R_SUCCESS);
}
Ejemplo n.º 18
0
static inline isc_result_t
totext_ipseckey(ARGS_TOTEXT) {
	isc_region_t region;
	dns_name_t name;
	char buf[sizeof("255 ")];
	unsigned short num;
	unsigned short gateway;

	REQUIRE(rdata->type == 45);
	REQUIRE(rdata->length >= 3);

	dns_name_init(&name, NULL);

	if (rdata->data[1] > 3U)
		return (ISC_R_NOTIMPLEMENTED);

	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext("( ", target));

	/*
	 * Precedence.
	 */
	dns_rdata_toregion(rdata, &region);
	num = uint8_fromregion(&region);
	isc_region_consume(&region, 1);
	sprintf(buf, "%u ", num);
	RETERR(str_totext(buf, target));

	/*
	 * Gateway type.
	 */
	gateway = uint8_fromregion(&region);
	isc_region_consume(&region, 1);
	sprintf(buf, "%u ", gateway);
	RETERR(str_totext(buf, target));

	/*
	 * Algorithm.
	 */
	num = uint8_fromregion(&region);
	isc_region_consume(&region, 1);
	sprintf(buf, "%u ", num);
	RETERR(str_totext(buf, target));

	/*
	 * Gateway.
	 */
	switch (gateway) {
	case 0:
		RETERR(str_totext(".", target));
		break;

	case 1:
		RETERR(inet_totext(AF_INET, &region, target));
		isc_region_consume(&region, 4);
		break;

	case 2:
		RETERR(inet_totext(AF_INET6, &region, target));
		isc_region_consume(&region, 16);
		break;

	case 3:
		dns_name_fromregion(&name, &region);
		RETERR(dns_name_totext(&name, ISC_FALSE, target));
		isc_region_consume(&region, name_length(&name));
		break;
	}

	/*
	 * Key.
	 */
	if (region.length > 0U) {
		RETERR(str_totext(tctx->linebreak, target));
		if (tctx->width == 0)   /* No splitting */
			RETERR(isc_base64_totext(&region, 60, "", target));
		else
			RETERR(isc_base64_totext(&region, tctx->width - 2,
						 tctx->linebreak, target));
	}

	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext(" )", target));
	return (ISC_R_SUCCESS);
}
Ejemplo n.º 19
0
static inline isc_result_t
tostruct_tkey(ARGS_TOSTRUCT) {
	dns_rdata_tkey_t *tkey = target;
	dns_name_t alg;
	isc_region_t sr;

	REQUIRE(rdata->type == 249);
	REQUIRE(target != NULL);
	REQUIRE(rdata->length != 0);

	tkey->common.rdclass = rdata->rdclass;
	tkey->common.rdtype = rdata->type;
	ISC_LINK_INIT(&tkey->common, link);

	dns_rdata_toregion(rdata, &sr);

	/*
	 * Algorithm Name.
	 */
	dns_name_init(&alg, NULL);
	dns_name_fromregion(&alg, &sr);
	dns_name_init(&tkey->algorithm, NULL);
	RETERR(name_duporclone(&alg, mctx, &tkey->algorithm));
	isc_region_consume(&sr, name_length(&tkey->algorithm));

	/*
	 * Inception.
	 */
	tkey->inception = uint32_fromregion(&sr);
	isc_region_consume(&sr, 4);

	/*
	 * Expire.
	 */
	tkey->expire = uint32_fromregion(&sr);
	isc_region_consume(&sr, 4);

	/*
	 * Mode.
	 */
	tkey->mode = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);

	/*
	 * Error.
	 */
	tkey->error = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);

	/*
	 * Key size.
	 */
	tkey->keylen = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);

	/*
	 * Key.
	 */
	tkey->key = mem_maybedup(mctx, sr.base, tkey->keylen);
	if (tkey->key == NULL)
		goto cleanup;
	isc_region_consume(&sr, tkey->keylen);

	/*
	 * Other size.
	 */
	tkey->otherlen = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);

	/*
	 * Other.
	 */
	tkey->other = mem_maybedup(mctx, sr.base, tkey->otherlen);
	if (tkey->other == NULL)
		goto cleanup;

	tkey->mctx = mctx;
	return (ISC_R_SUCCESS);

 cleanup:
	if (mctx != NULL)
		dns_name_free(&tkey->algorithm, mctx);
	if (mctx != NULL && tkey->key != NULL)
		isc_mem_free(mctx, tkey->key);
	return (ISC_R_NOMEMORY);
}
Ejemplo n.º 20
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.º 21
0
Archivo: soa_6.c Proyecto: fanf2/bind-9
static inline isc_result_t
totext_soa(ARGS_TOTEXT) {
	isc_region_t dregion;
	dns_name_t mname;
	dns_name_t rname;
	dns_name_t prefix;
	isc_boolean_t sub;
	int i;
	isc_boolean_t multiline;
	isc_boolean_t comment;

	REQUIRE(rdata->type == 6);
	REQUIRE(rdata->length != 0);

	multiline = ISC_TF((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0);
	if (multiline)
		comment = ISC_TF((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0);
	else
		comment = ISC_FALSE;


	dns_name_init(&mname, NULL);
	dns_name_init(&rname, NULL);
	dns_name_init(&prefix, NULL);

	dns_rdata_toregion(rdata, &dregion);

	dns_name_fromregion(&mname, &dregion);
	isc_region_consume(&dregion, name_length(&mname));

	dns_name_fromregion(&rname, &dregion);
	isc_region_consume(&dregion, name_length(&rname));

	sub = name_prefix(&mname, tctx->origin, &prefix);
	RETERR(dns_name_totext(&prefix, sub, target));

	RETERR(str_totext(" ", target));

	sub = name_prefix(&rname, tctx->origin, &prefix);
	RETERR(dns_name_totext(&prefix, sub, target));

	if (multiline)
		RETERR(str_totext(" (" , target));
	RETERR(str_totext(tctx->linebreak, target));

	for (i = 0; i < 5; i++) {
		unsigned long num;
		unsigned int len = target->used;
		num = uint32_fromregion(&dregion);
		isc_region_consume(&dregion, 4);
		if (i >= 1 && (tctx->flags & DNS_STYLEFLAG_TTL_UNITS) != 0) {
			RETERR(dns_ttl_totext(num, ISC_FALSE, target));
		} else {
			char buf[12];
			sprintf(buf, "%lu", num);
			RETERR(str_totext(buf, target));
		}
		if (comment) {
			len = target->used - len;
			INSIST(len <= 10); /* "0123456789 ; " */
			RETERR(str_totext(len+"           ; ", target));
			RETERR(str_totext(soa_fieldnames[i], target));
			/* Print times in week/day/hour/minute/second form */
			if (i >= 1) {
				RETERR(str_totext(" (", target));
				RETERR(dns_ttl_totext(num, ISC_TRUE, target));
				RETERR(str_totext(")", target));
			}
			RETERR(str_totext(tctx->linebreak, target));
		} else if (i < 4) {
			RETERR(str_totext(tctx->linebreak, target));
		}
	}

	if (multiline)
		RETERR(str_totext(")", target));

	return (ISC_R_SUCCESS);
}
Ejemplo n.º 22
0
static inline isc_result_t
tostruct_naptr(ARGS_TOSTRUCT) {
	dns_rdata_naptr_t *naptr = target;
	isc_region_t r;
	isc_result_t result;
	dns_name_t name;

	REQUIRE(rdata->type == dns_rdatatype_naptr);
	REQUIRE(target != NULL);
	REQUIRE(rdata->length != 0);

	naptr->common.rdclass = rdata->rdclass;
	naptr->common.rdtype = rdata->type;
	ISC_LINK_INIT(&naptr->common, link);

	naptr->flags = NULL;
	naptr->service = NULL;
	naptr->regexp = NULL;

	dns_rdata_toregion(rdata, &r);

	naptr->order = uint16_fromregion(&r);
	isc_region_consume(&r, 2);

	naptr->preference = uint16_fromregion(&r);
	isc_region_consume(&r, 2);

	naptr->flags_len = uint8_fromregion(&r);
	isc_region_consume(&r, 1);
	INSIST(naptr->flags_len <= r.length);
	naptr->flags = mem_maybedup(mctx, r.base, naptr->flags_len);
	if (naptr->flags == NULL)
		goto cleanup;
	isc_region_consume(&r, naptr->flags_len);

	naptr->service_len = uint8_fromregion(&r);
	isc_region_consume(&r, 1);
	INSIST(naptr->service_len <= r.length);
	naptr->service = mem_maybedup(mctx, r.base, naptr->service_len);
	if (naptr->service == NULL)
		goto cleanup;
	isc_region_consume(&r, naptr->service_len);

	naptr->regexp_len = uint8_fromregion(&r);
	isc_region_consume(&r, 1);
	INSIST(naptr->regexp_len <= r.length);
	naptr->regexp = mem_maybedup(mctx, r.base, naptr->regexp_len);
	if (naptr->regexp == NULL)
		goto cleanup;
	isc_region_consume(&r, naptr->regexp_len);

	dns_name_init(&name, NULL);
	dns_name_fromregion(&name, &r);
	dns_name_init(&naptr->replacement, NULL);
	result = name_duporclone(&name, mctx, &naptr->replacement);
	if (result != ISC_R_SUCCESS)
		goto cleanup;
	naptr->mctx = mctx;
	return (ISC_R_SUCCESS);

 cleanup:
	if (mctx != NULL && naptr->flags != NULL)
		isc_mem_free(mctx, naptr->flags);
	if (mctx != NULL && naptr->service != NULL)
		isc_mem_free(mctx, naptr->service);
	if (mctx != NULL && naptr->regexp != NULL)
		isc_mem_free(mctx, naptr->regexp);
	return (ISC_R_NOMEMORY);
}
Ejemplo n.º 23
0
isc_result_t
dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
		  isc_buffer_t *target, unsigned int options,
		  unsigned int *countp)
{
	dns_rdata_t rdata = DNS_RDATA_INIT;
	isc_result_t result;
	isc_region_t remaining, tavailable;
	isc_buffer_t source, savedbuffer, rdlen;
	dns_name_t name;
	dns_rdatatype_t type;
	unsigned int i, rcount, count;

	/*
	 * Convert the negative caching rdataset 'rdataset' to wire format,
	 * compressing names as specified in 'cctx', and storing the result in
	 * 'target'.
	 */

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

	savedbuffer = *target;
	count = 0;

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

		INSIST(remaining.length >= 5);
		type = isc_buffer_getuint16(&source);
		isc_buffer_forward(&source, 1);
		rcount = isc_buffer_getuint16(&source);

		for (i = 0; i < rcount; i++) {
			/*
			 * Get the length of this rdata and set up an
			 * rdata structure for it.
			 */
			isc_buffer_remainingregion(&source, &remaining);
			INSIST(remaining.length >= 2);
			dns_rdata_reset(&rdata);
			rdata.length = isc_buffer_getuint16(&source);
			isc_buffer_remainingregion(&source, &remaining);
			rdata.data = remaining.base;
			rdata.type = type;
			rdata.rdclass = rdataset->rdclass;
			INSIST(remaining.length >= rdata.length);
			isc_buffer_forward(&source, rdata.length);

			if ((options & DNS_NCACHETOWIRE_OMITDNSSEC) != 0 &&
			    dns_rdatatype_isdnssec(type))
				continue;

			/*
			 * Write the name.
			 */
			dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
			result = dns_name_towire(&name, cctx, target);
			if (result != ISC_R_SUCCESS)
				goto rollback;

			/*
			 * See if we have space for type, class, ttl, and
			 * rdata length.  Write the type, class, and ttl.
			 */
			isc_buffer_availableregion(target, &tavailable);
			if (tavailable.length < 10) {
				result = ISC_R_NOSPACE;
				goto rollback;
			}
			isc_buffer_putuint16(target, type);
			isc_buffer_putuint16(target, rdataset->rdclass);
			isc_buffer_putuint32(target, rdataset->ttl);

			/*
			 * Save space for rdata length.
			 */
			rdlen = *target;
			isc_buffer_add(target, 2);

			/*
			 * Write the rdata.
			 */
			result = dns_rdata_towire(&rdata, cctx, target);
			if (result != ISC_R_SUCCESS)
				goto rollback;

			/*
			 * Set the rdata length field to the compressed
			 * length.
			 */
			INSIST((target->used >= rdlen.used + 2) &&
			       (target->used - rdlen.used - 2 < 65536));
			isc_buffer_putuint16(&rdlen,
					     (isc_uint16_t)(target->used -
							    rdlen.used - 2));

			count++;
		}
		INSIST(isc_buffer_remaininglength(&source) == 0);
		result = dns_rdataset_next(rdataset);
		dns_rdata_reset(&rdata);
	}
	if (result != ISC_R_NOMORE)
		goto rollback;

	*countp = count;

	return (ISC_R_SUCCESS);

 rollback:
	INSIST(savedbuffer.used < 65536);
	dns_compress_rollback(cctx, (isc_uint16_t)savedbuffer.used);
	*countp = 0;
	*target = savedbuffer;

	return (result);
}
Ejemplo n.º 24
0
static inline isc_result_t
totext_dnskey(ARGS_TOTEXT) {
	isc_region_t sr;
	char buf[sizeof("64000")];
	unsigned int flags;
	unsigned char algorithm;
	char algbuf[DNS_NAME_FORMATSIZE];
	const char *keyinfo;

	REQUIRE(rdata->type == 48);
	REQUIRE(rdata->length != 0);

	dns_rdata_toregion(rdata, &sr);

	/* flags */
	flags = uint16_fromregion(&sr);
	isc_region_consume(&sr, 2);
	sprintf(buf, "%u", flags);
	RETERR(str_totext(buf, target));
	RETERR(str_totext(" ", target));
	if ((flags & DNS_KEYFLAG_KSK) != 0) {
		if (flags & DNS_KEYFLAG_REVOKE)
			keyinfo = "revoked KSK";
		else
			keyinfo = "KSK";
	} else
		keyinfo = "ZSK";

	/* protocol */
	sprintf(buf, "%u", sr.base[0]);
	isc_region_consume(&sr, 1);
	RETERR(str_totext(buf, target));
	RETERR(str_totext(" ", target));

	/* algorithm */
	algorithm = sr.base[0];
	sprintf(buf, "%u", algorithm);
	isc_region_consume(&sr, 1);
	RETERR(str_totext(buf, target));

	/* No Key? */
	if ((flags & 0xc000) == 0xc000)
		return (ISC_R_SUCCESS);

	if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0 &&
	     algorithm == DNS_KEYALG_PRIVATEDNS) {
		dns_name_t name;
		dns_name_init(&name, NULL);
		dns_name_fromregion(&name, &sr);
		dns_name_format(&name, algbuf, sizeof(algbuf));
	} else {
		dns_secalg_format((dns_secalg_t) algorithm, algbuf,
				  sizeof(algbuf));
	}

	/* key */
	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext(" (", target));
	RETERR(str_totext(tctx->linebreak, target));
	if (tctx->width == 0)   /* No splitting */
		RETERR(isc_base64_totext(&sr, 0, "", target));
	else
		RETERR(isc_base64_totext(&sr, tctx->width - 2,
					 tctx->linebreak, target));

	if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0)
		RETERR(str_totext(tctx->linebreak, target));
	else if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext(" ", target));

	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext(")", target));

	if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
		isc_region_t tmpr;

		RETERR(str_totext(" ; ", target));
		RETERR(str_totext(keyinfo, target));
		RETERR(str_totext("; alg = ", target));
		RETERR(str_totext(algbuf, target));
		RETERR(str_totext("; key id = ", target));
		dns_rdata_toregion(rdata, &tmpr);
		sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
		RETERR(str_totext(buf, target));
	}
	return (ISC_R_SUCCESS);
}
Ejemplo n.º 25
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.º 26
0
static inline isc_result_t
totext_hip(ARGS_TOTEXT) {
	isc_region_t region;
	dns_name_t name;
	unsigned int length, key_len, hit_len;
	unsigned char algorithm;
	char buf[sizeof("225 ")];

	REQUIRE(rdata->type == dns_rdatatype_hip);
	REQUIRE(rdata->length != 0);

	dns_rdata_toregion(rdata, &region);

	hit_len = uint8_fromregion(&region);
	isc_region_consume(&region, 1);

	algorithm = uint8_fromregion(&region);
	isc_region_consume(&region, 1);

	key_len = uint16_fromregion(&region);
	isc_region_consume(&region, 2);

	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext("( ", target));

	/*
	 * Algorithm
	 */
	sprintf(buf, "%u ", algorithm);
	RETERR(str_totext(buf, target));

	/*
	 * HIT.
	 */
	INSIST(hit_len < region.length);
	length = region.length;
	region.length = hit_len;
	RETERR(isc_hex_totext(&region, 1, "", target));
	region.length = length - hit_len;
	RETERR(str_totext(tctx->linebreak, target));

	/*
	 * Public KEY.
	 */
	INSIST(key_len <= region.length);
	length = region.length;
	region.length = key_len;
	RETERR(isc_base64_totext(&region, 1, "", target));
	region.length = length - key_len;
	RETERR(str_totext(tctx->linebreak, target));

	/*
	 * Rendezvous Servers.
	 */
	dns_name_init(&name, NULL);
	while (region.length > 0) {
		dns_name_fromregion(&name, &region);

		RETERR(dns_name_totext(&name, ISC_FALSE, target));
		isc_region_consume(&region, name.length);
		if (region.length > 0)
			RETERR(str_totext(tctx->linebreak, target));
	}
	if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
		RETERR(str_totext(" )", target));
	return (ISC_R_SUCCESS);
}
Ejemplo n.º 27
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.º 28
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;
	unsigned int i, rcount;
	isc_uint16_t length;

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

	result = dns_rdataset_first(ncacherdataset);
	if (result != ISC_R_SUCCESS)
		return (result);
	dns_rdataset_current(ncacherdataset, &rdata);
	INSIST(dns_rdataset_next(ncacherdataset) == ISC_R_NOMORE);
	isc_buffer_init(&source, rdata.data, rdata.length);
	isc_buffer_add(&source, rdata.length);

	do {
		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 >= 4);
		ttype = isc_buffer_getuint16(&source);

		if (ttype == type && dns_name_equal(&tname, name)) {
			isc_buffer_remainingregion(&source, &remaining);
			break;
		}

		rcount = isc_buffer_getuint16(&source);
		for (i = 0; i < rcount; i++) {
			isc_buffer_remainingregion(&source, &remaining);
			INSIST(remaining.length >= 2);
			length = isc_buffer_getuint16(&source);
			isc_buffer_remainingregion(&source, &remaining);
			INSIST(remaining.length >= length);
			isc_buffer_forward(&source, length);
		}
		isc_buffer_remainingregion(&source, &remaining);
	} while (remaining.length > 0);

	if (remaining.length == 0)
		return (ISC_R_NOTFOUND);

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

	rdataset->private3 = remaining.base;

	/*
	 * Reset iterator state.
	 */
	rdataset->privateuint4 = 0;
	rdataset->private5 = NULL;
	return (ISC_R_SUCCESS);
}