+4385. [func] Add support for allow-query and allow-transfer ACLs
+ to catalog zones. [RT #42578]
+
4384. [bug] Change 4256 accidentally disabled logging of the
rndc command. [RT #42654]
/* Zone shouldn't already exist */
result = dns_zt_find(ev->view->zonetable,
dns_catz_entry_getname(ev->entry), 0, NULL, &zone);
- if (result == ISC_R_SUCCESS) {
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
- NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
- "catz: zone \"%s\" already exists", nameb);
- goto cleanup;
- } else if (result == DNS_R_PARTIALMATCH) {
- /* Create our sub-zone anyway */
- dns_zone_detach(&zone);
- zone = NULL;
- } else if (result != ISC_R_NOTFOUND) {
- isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
- NS_LOGMODULE_SERVER, ISC_LOG_ERROR,
- "catz: error \"%s\" while trying to "
- "add zone \"%s\"",
- isc_result_totext(result), nameb);
- goto cleanup;
- }
+ if (ev->mod == ISC_TRUE) {
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "catz: error \"%s\" while trying to"
+ "modify zone \"%s\"",
+ isc_result_totext(result),
+ nameb);
+ goto cleanup;
+ } else {
+ dns_zone_detach(&zone);
+ }
+
+ } else {
+ if (result != ISC_R_NOTFOUND && result != DNS_R_PARTIALMATCH) {
+ isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
+ NS_LOGMODULE_SERVER, ISC_LOG_WARNING,
+ "catz: error \"%s\" while trying to"
+ "add zone \"%s\"",
+ isc_result_totext(result),
+ nameb);
+ goto cleanup;
+ } else { /* this can happen in case of DNS_R_PARTIALMATCH */
+ if (zone != NULL)
+ dns_zone_detach(&zone);
+ }
+ }
+ RUNTIME_CHECK(zone == NULL);
/* Create a config for new zone */
confbuf = NULL;
dns_catz_generate_zonecfg(ev->origin, ev->entry, &confbuf);
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
+n=`expr $n + 1`
+echo "I:Adding a domain dom6.example to master via RNDC ($n)"
+ret=0
+echo "@ 3600 IN SOA . . 1 3600 3600 3600 3600" > ns1/dom6.example.db
+echo "@ IN NS invalid." >> ns1/dom6.example.db
+$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 addzone dom6.example '{type master; file "dom6.example.db";};' || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom6.example is now served by master ($n)"
+ret=0
+$DIG soa dom6.example @10.53.0.1 -p 5300 > dig.out.test$n
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run`
+
+n=`expr $n + 1`
+echo "I:Adding domain dom6.example to catalog1 zone with an allow-query statement ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+ server 10.53.0.1 5300
+ update add 4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example 3600 IN PTR dom6.example.
+ update add allow-query.4346f565b4d63ddb99e5d2497ff22d04e878e8f8.zones.catalog1.example 3600 IN APL 1:10.53.0.1/32 !1:10.53.0.0/30 1:0.0.0.0/0
+ send
+END
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:waiting for slave to sync up ($n)"
+ret=1
+try=0
+while test $try -lt 45
+do
+ sleep 1
+ sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom6.example' from catalog 'catalog1.example'" > /dev/null && {
+ ret=0
+ break
+ }
+ try=`expr $try + 1`
+done
+try=0
+while test $try -lt 45
+do
+ sleep 1
+ sed -n "$cur,"'$p' < ns2/named.run | grep "transfer of 'dom6.example/IN' from 10.53.0.1#5300: Transfer status: success" > /dev/null && {
+ ret=0
+ break
+ }
+ try=`expr $try + 1`
+done
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom6.example is accessible from 10.53.0.1 ($n)"
+ret=0
+$DIG soa dom6.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom6.example is not accessible from 10.53.0.2 ($n)"
+ret=0
+$DIG soa dom6.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n
+grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom6.example is accessible from 10.53.0.5 ($n)"
+ret=0
+$DIG soa dom6.example -b 10.53.0.5 @10.53.0.2 -p 5300 > dig.out.test$n
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run`
+n=`expr $n + 1`
+echo "I:Adding global allow-query and allow-domain ACLs ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+ server 10.53.0.1 5300
+ update add 636722929740e507aaf27c502812fc395d30fb17.zones.catalog1.example 3600 IN PTR dom2.example.
+ update add allow-query.catalog1.example 3600 IN APL 1:10.53.0.1/32
+ update add allow-transfer.catalog1.example 3600 IN APL 1:10.53.0.2/32
+ send
+END
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:waiting for slave to sync up ($n)"
+ret=1
+try=0
+while test $try -lt 45
+do
+ sleep 1
+ sed -n "$cur,"'$p' < ns2/named.run | grep "catz: adding zone 'dom2.example' from catalog 'catalog1.example'" > /dev/null && {
+ ret=0
+ break
+ }
+ try=`expr $try + 1`
+done
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom3.example is accessible from 10.53.0.1 ($n)"
+ret=0
+$DIG soa dom3.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom3.example is not accessible from 10.53.0.2 ($n)"
+ret=0
+$DIG soa dom3.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n
+grep "status: REFUSED" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom3.example is not AXFR accessible from 10.53.0.1 ($n)"
+ret=0
+$DIG axfr dom3.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n
+grep "Transfer failed." dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom3.example is AXFR accessible from 10.53.0.2 ($n)"
+ret=0
+$DIG axfr dom3.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n
+grep -v "Transfer failed." dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run`
+n=`expr $n + 1`
+echo "I:Deleting global allow-query and allow-domain ACLs ($n)"
+ret=0
+$NSUPDATE -d <<END >> nsupdate.out.test$n 2>&1 || ret=1
+ server 10.53.0.1 5300
+ update delete allow-query.catalog1.example 3600 IN APL 1:10.53.0.1/32
+ update delete allow-transfer.catalog1.example 3600 IN APL 1:10.53.0.2/32
+ send
+END
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+ret=0
+try=0
+while test $try -lt 45
+do
+ sleep 1
+ sed -n "$cur,"'$p' < ns2/named.run | grep "catz: update_from_db: new zone merged" > /dev/null && {
+ ret=0
+ break
+ }
+ try=`expr $try + 1`
+done
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom3.example is accessible from 10.53.0.1 ($n)"
+ret=0
+$DIG soa dom3.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom3.example is accessible from 10.53.0.2 ($n)"
+ret=0
+$DIG soa dom3.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom3.example is AXFR accessible from 10.53.0.1 ($n)"
+ret=0
+$DIG axfr dom3.example -b 10.53.0.1 @10.53.0.2 -p 5300 > dig.out.test$n
+grep -v "Transfer failed." dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+n=`expr $n + 1`
+echo "I:checking that dom3.example is AXFR accessible from 10.53.0.2 ($n)"
+ret=0
+$DIG axfr dom3.example -b 10.53.0.2 @10.53.0.2 -p 5300 > dig.out.test$n
+grep -v "Transfer failed." dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+
+
echo "I:exit status: $status"
[ $status -eq 0 ] || exit 1
options->masters.keys = NULL;
options->masters.count = 0;
+ options->allow_query = NULL;
+ options->allow_transfer = NULL;
+
options->in_memory = ISC_FALSE;
options->min_update_interval = 5;
options->zonedir = NULL;
isc_mem_free(mctx, options->zonedir);
options->zonedir = NULL;
}
+ if (options->allow_query != NULL)
+ isc_buffer_free(&options->allow_query);
+ if (options->allow_transfer != NULL)
+ isc_buffer_free(&options->allow_transfer);
}
isc_result_t
/* TODO error handling */
REQUIRE(dst != NULL);
REQUIRE(dst->masters.count == 0);
+ REQUIRE(dst->allow_query == NULL);
+ REQUIRE(dst->allow_transfer == NULL);
if (src->masters.count != 0)
dns_ipkeylist_copy(mctx, &src->masters, &dst->masters);
if (src->zonedir != NULL)
dst->zonedir = isc_mem_strdup(mctx, src->zonedir);
+ if (src->allow_query != NULL)
+ isc_buffer_dup(mctx, &dst->allow_query, src->allow_query);
+
+ if (src->allow_transfer != NULL)
+ isc_buffer_dup(mctx, &dst->allow_transfer, src->allow_transfer);
+
+
return (ISC_R_SUCCESS);
}
dns_catz_options_setdefault(isc_mem_t *mctx, const dns_catz_options_t *defaults,
dns_catz_options_t *opts)
{
- if (opts->masters.count == 0)
- dns_catz_options_copy(mctx, defaults, opts);
- else if (defaults->zonedir != NULL)
+ if (opts->masters.count == 0 && defaults->masters.count != 0)
+ dns_ipkeylist_copy(mctx, &defaults->masters, &opts->masters);
+
+ if (defaults->zonedir != NULL)
opts->zonedir = isc_mem_strdup(mctx, defaults->zonedir);
+ if (opts->allow_query == NULL && defaults->allow_query != NULL)
+ isc_buffer_dup(mctx, &opts->allow_query, defaults->allow_query);
+ if (opts->allow_transfer == NULL && defaults->allow_transfer != NULL)
+ isc_buffer_dup(mctx, &opts->allow_transfer,
+ defaults->allow_transfer);
+
/* This option is always taken from config, so it's always 'default' */
opts->in_memory = defaults->in_memory;
return (ISC_R_SUCCESS);
isc_boolean_t
dns_catz_entry_cmp(const dns_catz_entry_t *ea, const dns_catz_entry_t *eb) {
+ isc_region_t ra, rb;
if (ea->opts.masters.count != eb->opts.masters.count)
return (ISC_FALSE);
ea->opts.masters.count * sizeof(isc_sockaddr_t)))
return (ISC_FALSE);
+ /* If one is NULL and the other isn't, the entries don't match */
+ if ((ea->opts.allow_query == NULL) !=
+ (eb->opts.allow_query == NULL))
+ return (ISC_FALSE);
+
+ /* If one is non-NULL, then they both are */
+ if (ea->opts.allow_query != NULL) {
+ isc_buffer_usedregion(ea->opts.allow_query, &ra);
+ isc_buffer_usedregion(eb->opts.allow_query, &rb);
+ if (isc_region_compare(&ra, &rb))
+ return (ISC_FALSE);
+ }
+
+ /* Repeat the above checks with allow_transfer */
+ if ((ea->opts.allow_transfer == NULL) !=
+ (eb->opts.allow_transfer == NULL))
+ return (ISC_FALSE);
+
+ if (ea->opts.allow_transfer != NULL) {
+ isc_buffer_usedregion(ea->opts.allow_transfer, &ra);
+ isc_buffer_usedregion(eb->opts.allow_transfer, &rb);
+ if (isc_region_compare(&ra, &rb))
+ return (ISC_FALSE);
+ }
+
/* xxxwpk TODO compare dscps/keys! */
return (ISC_TRUE);
}
return (ISC_R_SUCCESS);
}
+static isc_result_t
+catz_process_apl(dns_catz_zone_t *zone, isc_buffer_t **aclbp,
+ dns_rdataset_t *value)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ dns_rdata_t rdata;
+ dns_rdata_in_apl_t rdata_apl;
+ dns_rdata_apl_ent_t apl_ent;
+ isc_netaddr_t addr;
+ isc_buffer_t *aclb = NULL;
+ unsigned char buf[256]; /* larger than INET6_ADDRSTRLEN */
+
+ REQUIRE(zone != NULL);
+ REQUIRE(aclbp != NULL);
+ REQUIRE(*aclbp == NULL);
+ REQUIRE(DNS_RDATASET_VALID(value));
+ REQUIRE(dns_rdataset_isassociated(value));
+
+ if (value->rdclass != dns_rdataclass_in ||
+ value->type != dns_rdatatype_apl)
+ return (ISC_R_FAILURE);
+
+
+ if (dns_rdataset_count(value) > 1) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_MASTER, ISC_LOG_WARNING,
+ "catz: more than one APL entry for member zone, "
+ "result is undefined");
+ }
+ result = dns_rdataset_first(value);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ dns_rdata_init(&rdata);
+ dns_rdataset_current(value, &rdata);
+ result = dns_rdata_tostruct(&rdata, &rdata_apl, zone->catzs->mctx);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = isc_buffer_allocate(zone->catzs->mctx, &aclb, 16);
+ isc_buffer_setautorealloc(aclb, ISC_TRUE);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ for (result = dns_rdata_apl_first(&rdata_apl);
+ result == ISC_R_SUCCESS;
+ result = dns_rdata_apl_next(&rdata_apl)) {
+ result = dns_rdata_apl_current(&rdata_apl, &apl_ent);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ memset(buf, 0, sizeof(buf));
+ memcpy(buf, apl_ent.data, apl_ent.length);
+ if (apl_ent.family == 1)
+ isc_netaddr_fromin(&addr, (struct in_addr*) buf);
+ else if (apl_ent.family == 2)
+ isc_netaddr_fromin6(&addr, (struct in6_addr*) buf);
+ else
+ continue; /* xxxwpk log it or simply ignore? */
+ if (apl_ent.negative)
+ isc_buffer_putuint8(aclb, '!');
+ isc_buffer_reserve(&aclb, INET6_ADDRSTRLEN);
+ result = isc_netaddr_totext(&addr, aclb);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if ((apl_ent.family == 1 && apl_ent.prefix < 32) ||
+ (apl_ent.family == 2 && apl_ent.prefix < 128)) {
+ isc_buffer_putuint8(aclb, '/');
+ isc_buffer_putdecint(aclb, apl_ent.prefix);
+ }
+ isc_buffer_putstr(aclb, "; ");
+ }
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+ else
+ goto cleanup;
+ *aclbp = aclb;
+ aclb = NULL;
+cleanup:
+ if (aclb != NULL)
+ isc_buffer_free(&aclb);
+ dns_rdata_freestruct(&rdata_apl);
+ return (result);
+}
+
static isc_result_t
catz_process_suboption(dns_catz_zone_t *zone, dns_label_t *mhash,
catz_opt_t subopt, dns_rdataset_t *value)
return (catz_process_ipkl(zone, &entry->opts.masters, value));
break;
case CATZ_OPT_ALLOW_QUERY:
-#if 0
- return (process_apl(zone, &entry->opts))
-#endif
+ return (catz_process_apl(zone, &entry->opts.allow_query,
+ value));
case CATZ_OPT_ALLOW_TRANSFER:
+ return (catz_process_apl(zone, &entry->opts.allow_transfer,
+ value));
default:
return (ISC_R_FAILURE);
}
case CATZ_OPT_MASTERS:
return (catz_process_ipkl(zone, &zone->zoneoptions.masters,
value));
- break;
case CATZ_OPT_VERSION:
return (catz_process_version(zone, value));
- break;
case CATZ_OPT_ALLOW_QUERY:
-#if 0
- return (process_apl(zone, &entry->opts))
-#endif
+ return (catz_process_apl(zone, &zone->zoneoptions.allow_query,
+ value));
case CATZ_OPT_ALLOW_TRANSFER:
+ return (catz_process_apl(zone, &zone->zoneoptions.allow_transfer,
+ value));
default:
return (ISC_R_FAILURE);
}
dns_catz_generate_zonecfg(dns_catz_zone_t *zone, dns_catz_entry_t *entry,
isc_buffer_t **buf)
{
- /* We have to generate a text buffer with regular zone config:
+ /*
+ * We have to generate a text buffer with regular zone config:
* zone foo.bar {
* type slave;
* masters { ip1 port1; ip2 port2; };
* }
*/
isc_buffer_t *buffer = NULL;
+ isc_region_t region;
isc_result_t result;
isc_uint32_t i;
isc_netaddr_t netaddr;
isc_buffer_putstr(buffer, "\";");
}
- isc_buffer_putstr(buffer, "};");
+ if (entry->opts.allow_query != NULL) {
+ isc_buffer_putstr(buffer, "allow-query { ");
+ isc_buffer_usedregion(entry->opts.allow_query, ®ion);
+ isc_buffer_copyregion(buffer, ®ion);
+ isc_buffer_putstr(buffer, "};");
+ }
+ if (entry->opts.allow_transfer != NULL) {
+ isc_buffer_putstr(buffer, "allow-transfer { ");
+ isc_buffer_usedregion(entry->opts.allow_transfer, ®ion);
+ isc_buffer_copyregion(buffer, ®ion);
+ isc_buffer_putstr(buffer, "};");
+ }
+ isc_buffer_putstr(buffer, "};");
*buf = buffer;
return (ISC_R_SUCCESS);
isc_ht_iter_current(iter, (void **) &zone);
if (zone->active == ISC_FALSE) {
char cname[DNS_NAME_FORMATSIZE];
- dns_name_format(&zone->name, cname, DNS_NAME_FORMATSIZE);
+ dns_name_format(&zone->name, cname,
+ DNS_NAME_FORMATSIZE);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTER,
ISC_LOG_WARNING,
/* default-masters definition */
dns_ipkeylist_t masters;
+ /* both as text in config format, NULL if none */
+ isc_buffer_t *allow_query;
+ isc_buffer_t *allow_transfer;
+
/*
* Options that are only set in named.conf
*/
*/
INSIST(apl->apl_len > 3U);
length = apl->apl[apl->offset + 3] & 0x7f;
- INSIST(length <= apl->apl_len);
+ INSIST(4 + length <= apl->apl_len);
apl->offset = 0;
return (ISC_R_SUCCESS);
* 16 to 32 bits promotion as 'length' is 32 bits so there is
* no overflow problems.
*/
- INSIST(length + apl->offset <= apl->apl_len);
+ INSIST(4 + length + apl->offset <= apl->apl_len);
- apl->offset += apl->apl[apl->offset + 3] & 0x7f;
- return ((apl->offset >= apl->apl_len) ? ISC_R_SUCCESS : ISC_R_NOMORE);
+ apl->offset += 4 + length;
+ return ((apl->offset < apl->apl_len) ? ISC_R_SUCCESS : ISC_R_NOMORE);
}
isc_result_t
*/
INSIST(apl->apl_len > 3U);
INSIST(apl->offset <= apl->apl_len - 4U);
- length = apl->apl[apl->offset + 3] & 0x7f;
+ length = (apl->apl[apl->offset + 3] & 0x7f);
/*
* 16 to 32 bits promotion as 'length' is 32 bits so there is
* no overflow problems.
*/
- INSIST(length + apl->offset <= apl->apl_len);
+ INSIST(4 + length + apl->offset <= apl->apl_len);
ent->family = (apl->apl[apl->offset] << 8) + apl->apl[apl->offset + 1];
ent->prefix = apl->apl[apl->offset + 2];
- ent->length = apl->apl[apl->offset + 3] & 0x7f;
+ ent->length = length;
ent->negative = ISC_TF((apl->apl[apl->offset + 3] & 0x80) != 0);
if (ent->length != 0)
ent->data = &apl->apl[apl->offset + 4];
return (ISC_R_SUCCESS);
}
+unsigned int
+dns_rdata_apl_count(const dns_rdata_in_apl_t *apl) {
+ return (apl->apl_len);
+}
+
static inline isc_result_t
additionaldata_in_apl(ARGS_ADDLDATA) {
REQUIRE(rdata->type == dns_rdatatype_apl);
isc_result_t
dns_rdata_apl_current(dns_rdata_in_apl_t *, dns_rdata_apl_ent_t *);
+unsigned int
+dns_rdata_apl_count(const dns_rdata_in_apl_t *apl);
+
#endif /* IN_1_APL_42_H */
}
void
-isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r) {
+isc__buffer_usedregion(const isc_buffer_t *b, isc_region_t *r) {
/*
* Make 'r' refer to the used region of 'b'.
*/
b->used += l;
}
+void
+isc_buffer_putdecint(isc_buffer_t *b, isc_int64_t v) {
+ unsigned int l=0;
+ unsigned char *cp;
+ char buf[21];
+ isc_result_t result;
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+
+ /* xxxwpk do it more low-level way ? */
+ l = snprintf(buf, 21, "%lld", v);
+ RUNTIME_CHECK(l <= 21);
+ if (b->autore) {
+ result = isc_buffer_reserve(&b, l);
+ REQUIRE(result == ISC_R_SUCCESS);
+ }
+ REQUIRE(isc_buffer_availablelength(b) >= l);
+
+ cp = isc_buffer_used(b);
+ memmove(cp, buf, l);
+ b->used += l;
+}
+
+isc_result_t
+isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **dstp, const isc_buffer_t *src) {
+ isc_buffer_t *dst = NULL;
+ isc_region_t region;
+ isc_result_t result;
+
+ REQUIRE(dstp != NULL && *dstp == NULL);
+ REQUIRE(ISC_BUFFER_VALID(src));
+
+ isc_buffer_usedregion(src, ®ion);
+
+ result = isc_buffer_allocate(mctx, &dst, region.length);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = isc_buffer_copyregion(dst, ®ion);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS); /* NOSPACE is impossible */
+ *dstp = dst;
+ return (ISC_R_SUCCESS);
+}
+
isc_result_t
isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) {
unsigned char *base;
unsigned int available;
+ isc_result_t result;
REQUIRE(ISC_BUFFER_VALID(b));
REQUIRE(r != NULL);
*/
base = isc_buffer_used(b);
available = isc_buffer_availablelength(b);
+ if (b->autore) {
+ result = isc_buffer_reserve(&b, r->length);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
if (r->length > available)
return (ISC_R_NOSPACE);
memmove(base, r->base, r->length);
*/
void
-isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r);
+isc__buffer_usedregion(const isc_buffer_t *b, isc_region_t *r);
/*!<
* \brief Make 'r' refer to the used region of 'b'.
*
*\li strlen(source) <= isc_buffer_available(b) || b->mctx != NULL
*/
+void
+isc_buffer_putdecint(isc_buffer_t *b, isc_int64_t v);
+/*!<
+ * \brief Put decimal representation of 'v' in b
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li strlen(dec(v)) <= isc_buffer_available(b) || b->mctx != NULL
+ */
+
+
+
isc_result_t
isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r);
/*!<
* big enough.
*/
+isc_result_t
+isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **dstp, const isc_buffer_t *src);
+/*!<
+ * \brief Allocate 'dst' and copy used contents of 'src' into it
+ *
+ * Requires:
+ *\li 'dstp' is not NULL and *dst is NULL
+ *\li 'src' is a valid buffer.
+ *
+ * Returns:
+ *
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_NOSPACE The available region of 'b' is not
+ * big enough.
+ */
+
ISC_LANG_ENDDECLS
/*