obj = NULL;
if (get_maps(maps, "max-zone-ttl", &obj)) {
- maxttl = cfg_obj_asuint32(obj);
+ maxttl = cfg_obj_asduration(obj);
zone_options |= DNS_ZONEOPT_CHECKTTL;
}
[ dscp <replaceable>integer</replaceable> ] { ( <replaceable>masters</replaceable> | <replaceable>ipv4_address</replaceable> [ port
<replaceable>integer</replaceable> ] | <replaceable>ipv6_address</replaceable> [ port <replaceable>integer</replaceable> ] ) [ key
<replaceable>string</replaceable> ]; ... } ] [ zone-directory <replaceable>quoted_string</replaceable> ] [
- in-memory <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>ttlval</replaceable> ]; ... };
+ in-memory <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>duration</replaceable> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <replaceable>boolean</replaceable>;
check-mx ( fail | warn | ignore );
fstrm-set-output-notify-threshold <replaceable>integer</replaceable>;
fstrm-set-output-queue-model ( mpsc | spsc );
fstrm-set-output-queue-size <replaceable>integer</replaceable>;
- fstrm-set-reopen-interval <replaceable>ttlval</replaceable>;
+ fstrm-set-reopen-interval <replaceable>duration</replaceable>;
geoip-directory ( <replaceable>quoted_string</replaceable> | none );
glue-cache <replaceable>boolean</replaceable>;
heartbeat-interval <replaceable>integer</replaceable>;
hostname ( <replaceable>quoted_string</replaceable> | none );
inline-signing <replaceable>boolean</replaceable>;
- interface-interval <replaceable>ttlval</replaceable>;
+ interface-interval <replaceable>duration</replaceable>;
ixfr-from-differences ( primary | master | secondary | slave |
<replaceable>boolean</replaceable> );
keep-response-order { <replaceable>address_match_element</replaceable>; ... };
key-directory <replaceable>quoted_string</replaceable>;
- lame-ttl <replaceable>ttlval</replaceable>;
+ lame-ttl <replaceable>duration</replaceable>;
listen-on [ port <replaceable>integer</replaceable> ] [ dscp
<replaceable>integer</replaceable> ] {
<replaceable>address_match_element</replaceable>; ... };
masterfile-style ( full | relative );
match-mapped-addresses <replaceable>boolean</replaceable>;
max-cache-size ( default | unlimited | <replaceable>sizeval</replaceable> | <replaceable>percentage</replaceable> );
- max-cache-ttl <replaceable>ttlval</replaceable>;
+ max-cache-ttl <replaceable>duration</replaceable>;
max-clients-per-query <replaceable>integer</replaceable>;
max-journal-size ( default | unlimited | <replaceable>sizeval</replaceable> );
- max-ncache-ttl <replaceable>ttlval</replaceable>;
+ max-ncache-ttl <replaceable>duration</replaceable>;
max-records <replaceable>integer</replaceable>;
max-recursion-depth <replaceable>integer</replaceable>;
max-recursion-queries <replaceable>integer</replaceable>;
max-refresh-time <replaceable>integer</replaceable>;
max-retry-time <replaceable>integer</replaceable>;
max-rsa-exponent-size <replaceable>integer</replaceable>;
- max-stale-ttl <replaceable>ttlval</replaceable>;
+ max-stale-ttl <replaceable>duration</replaceable>;
max-transfer-idle-in <replaceable>integer</replaceable>;
max-transfer-idle-out <replaceable>integer</replaceable>;
max-transfer-time-in <replaceable>integer</replaceable>;
max-transfer-time-out <replaceable>integer</replaceable>;
max-udp-size <replaceable>integer</replaceable>;
- max-zone-ttl ( unlimited | <replaceable>ttlval</replaceable> );
+ max-zone-ttl ( unlimited | <replaceable>duration</replaceable> );
memstatistics <replaceable>boolean</replaceable>;
memstatistics-file <replaceable>quoted_string</replaceable>;
message-compression <replaceable>boolean</replaceable>;
- min-cache-ttl <replaceable>ttlval</replaceable>;
- min-ncache-ttl <replaceable>ttlval</replaceable>;
+ min-cache-ttl <replaceable>duration</replaceable>;
+ min-ncache-ttl <replaceable>duration</replaceable>;
min-refresh-time <replaceable>integer</replaceable>;
min-retry-time <replaceable>integer</replaceable>;
minimal-any <replaceable>boolean</replaceable>;
notify-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ]
[ dscp <replaceable>integer</replaceable> ];
notify-to-soa <replaceable>boolean</replaceable>;
- nta-lifetime <replaceable>ttlval</replaceable>;
- nta-recheck <replaceable>ttlval</replaceable>;
+ nta-lifetime <replaceable>duration</replaceable>;
+ nta-recheck <replaceable>duration</replaceable>;
nxdomain-redirect <replaceable>string</replaceable>;
pid-file ( <replaceable>quoted_string</replaceable> | none );
port <replaceable>integer</replaceable>;
response-padding { <replaceable>address_match_element</replaceable>; ... } block-size
<replaceable>integer</replaceable>;
response-policy { zone <replaceable>string</replaceable> [ add-soa <replaceable>boolean</replaceable> ] [ log
- <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [ min-update-interval
- <replaceable>ttlval</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
+ <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [ min-update-interval
+ <replaceable>duration</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
nodata | nxdomain | passthru | tcp-only <replaceable>quoted_string</replaceable> ) ] [
recursive-only <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
nsdname-enable <replaceable>boolean</replaceable> ]; ... } [ add-soa <replaceable>boolean</replaceable> ] [
- break-dnssec <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [
- min-update-interval <replaceable>ttlval</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
+ break-dnssec <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [
+ min-update-interval <replaceable>duration</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
nsip-wait-recurse <replaceable>boolean</replaceable> ] [ qname-wait-recurse <replaceable>boolean</replaceable> ]
[ recursive-only <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
nsdname-enable <replaceable>boolean</replaceable> ] [ dnsrps-enable <replaceable>boolean</replaceable> ] [
serial-query-rate <replaceable>integer</replaceable>;
serial-update-method ( date | increment | unixtime );
server-id ( <replaceable>quoted_string</replaceable> | none | hostname );
- servfail-ttl <replaceable>ttlval</replaceable>;
+ servfail-ttl <replaceable>duration</replaceable>;
session-keyalg <replaceable>string</replaceable>;
session-keyfile ( <replaceable>quoted_string</replaceable> | none );
session-keyname <replaceable>string</replaceable>;
sortlist { <replaceable>address_match_element</replaceable>; ... };
stacksize ( default | unlimited | <replaceable>sizeval</replaceable> );
stale-answer-enable <replaceable>boolean</replaceable>;
- stale-answer-ttl <replaceable>ttlval</replaceable>;
+ stale-answer-ttl <replaceable>duration</replaceable>;
startup-notify-rate <replaceable>integer</replaceable>;
statistics-file <replaceable>quoted_string</replaceable>;
synth-from-dnssec <replaceable>boolean</replaceable>;
[ dscp <replaceable>integer</replaceable> ] { ( <replaceable>masters</replaceable> | <replaceable>ipv4_address</replaceable> [ port
<replaceable>integer</replaceable> ] | <replaceable>ipv6_address</replaceable> [ port <replaceable>integer</replaceable> ] ) [ key
<replaceable>string</replaceable> ]; ... } ] [ zone-directory <replaceable>quoted_string</replaceable> ] [
- in-memory <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>ttlval</replaceable> ]; ... };
+ in-memory <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>duration</replaceable> ]; ... };
check-dup-records ( fail | warn | ignore );
check-integrity <replaceable>boolean</replaceable>;
check-mx ( fail | warn | ignore );
secret <replaceable>string</replaceable>;
};
key-directory <replaceable>quoted_string</replaceable>;
- lame-ttl <replaceable>ttlval</replaceable>;
+ lame-ttl <replaceable>duration</replaceable>;
lmdb-mapsize <replaceable>sizeval</replaceable>;
managed-keys { <replaceable>string</replaceable> (
static-key | initial-key
match-destinations { <replaceable>address_match_element</replaceable>; ... };
match-recursive-only <replaceable>boolean</replaceable>;
max-cache-size ( default | unlimited | <replaceable>sizeval</replaceable> | <replaceable>percentage</replaceable> );
- max-cache-ttl <replaceable>ttlval</replaceable>;
+ max-cache-ttl <replaceable>duration</replaceable>;
max-clients-per-query <replaceable>integer</replaceable>;
max-journal-size ( default | unlimited | <replaceable>sizeval</replaceable> );
- max-ncache-ttl <replaceable>ttlval</replaceable>;
+ max-ncache-ttl <replaceable>duration</replaceable>;
max-records <replaceable>integer</replaceable>;
max-recursion-depth <replaceable>integer</replaceable>;
max-recursion-queries <replaceable>integer</replaceable>;
max-refresh-time <replaceable>integer</replaceable>;
max-retry-time <replaceable>integer</replaceable>;
- max-stale-ttl <replaceable>ttlval</replaceable>;
+ max-stale-ttl <replaceable>duration</replaceable>;
max-transfer-idle-in <replaceable>integer</replaceable>;
max-transfer-idle-out <replaceable>integer</replaceable>;
max-transfer-time-in <replaceable>integer</replaceable>;
max-transfer-time-out <replaceable>integer</replaceable>;
max-udp-size <replaceable>integer</replaceable>;
- max-zone-ttl ( unlimited | <replaceable>ttlval</replaceable> );
+ max-zone-ttl ( unlimited | <replaceable>duration</replaceable> );
message-compression <replaceable>boolean</replaceable>;
- min-cache-ttl <replaceable>ttlval</replaceable>;
- min-ncache-ttl <replaceable>ttlval</replaceable>;
+ min-cache-ttl <replaceable>duration</replaceable>;
+ min-ncache-ttl <replaceable>duration</replaceable>;
min-refresh-time <replaceable>integer</replaceable>;
min-retry-time <replaceable>integer</replaceable>;
minimal-any <replaceable>boolean</replaceable>;
notify-source-v6 ( <replaceable>ipv6_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ]
[ dscp <replaceable>integer</replaceable> ];
notify-to-soa <replaceable>boolean</replaceable>;
- nta-lifetime <replaceable>ttlval</replaceable>;
- nta-recheck <replaceable>ttlval</replaceable>;
+ nta-lifetime <replaceable>duration</replaceable>;
+ nta-recheck <replaceable>duration</replaceable>;
nxdomain-redirect <replaceable>string</replaceable>;
plugin ( query ) <replaceable>string</replaceable> [ {
<replaceable>unspecified-text</replaceable> } ];
response-padding { <replaceable>address_match_element</replaceable>; ... } block-size
<replaceable>integer</replaceable>;
response-policy { zone <replaceable>string</replaceable> [ add-soa <replaceable>boolean</replaceable> ] [ log
- <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [ min-update-interval
- <replaceable>ttlval</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
+ <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [ min-update-interval
+ <replaceable>duration</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
nodata | nxdomain | passthru | tcp-only <replaceable>quoted_string</replaceable> ) ] [
recursive-only <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
nsdname-enable <replaceable>boolean</replaceable> ]; ... } [ add-soa <replaceable>boolean</replaceable> ] [
- break-dnssec <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [
- min-update-interval <replaceable>ttlval</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
+ break-dnssec <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [
+ min-update-interval <replaceable>duration</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
nsip-wait-recurse <replaceable>boolean</replaceable> ] [ qname-wait-recurse <replaceable>boolean</replaceable> ]
[ recursive-only <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
nsdname-enable <replaceable>boolean</replaceable> ] [ dnsrps-enable <replaceable>boolean</replaceable> ] [
<replaceable>integer</replaceable> | * ) ] [ dscp <replaceable>integer</replaceable> ];
transfers <replaceable>integer</replaceable>;
};
- servfail-ttl <replaceable>ttlval</replaceable>;
+ servfail-ttl <replaceable>duration</replaceable>;
sig-signing-nodes <replaceable>integer</replaceable>;
sig-signing-signatures <replaceable>integer</replaceable>;
sig-signing-type <replaceable>integer</replaceable>;
sig-validity-interval <replaceable>integer</replaceable> [ <replaceable>integer</replaceable> ];
sortlist { <replaceable>address_match_element</replaceable>; ... };
stale-answer-enable <replaceable>boolean</replaceable>;
- stale-answer-ttl <replaceable>ttlval</replaceable>;
+ stale-answer-ttl <replaceable>duration</replaceable>;
synth-from-dnssec <replaceable>boolean</replaceable>;
transfer-format ( many-answers | one-answer );
transfer-source ( <replaceable>ipv4_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ] [
max-transfer-idle-out <replaceable>integer</replaceable>;
max-transfer-time-in <replaceable>integer</replaceable>;
max-transfer-time-out <replaceable>integer</replaceable>;
- max-zone-ttl ( unlimited | <replaceable>ttlval</replaceable> );
+ max-zone-ttl ( unlimited | <replaceable>duration</replaceable> );
min-refresh-time <replaceable>integer</replaceable>;
min-retry-time <replaceable>integer</replaceable>;
multi-master <replaceable>boolean</replaceable>;
max-transfer-idle-out <replaceable>integer</replaceable>;
max-transfer-time-in <replaceable>integer</replaceable>;
max-transfer-time-out <replaceable>integer</replaceable>;
- max-zone-ttl ( unlimited | <replaceable>ttlval</replaceable> );
+ max-zone-ttl ( unlimited | <replaceable>duration</replaceable> );
min-refresh-time <replaceable>integer</replaceable>;
min-retry-time <replaceable>integer</replaceable>;
multi-master <replaceable>boolean</replaceable>;
return;
}
- conf_dnsrps_sadd(ctx, " %s %d", name, cfg_obj_asuint32(sub_obj));
+ if (cfg_obj_isduration(sub_obj)) {
+ conf_dnsrps_sadd(ctx, " %s %d", name,
+ cfg_obj_asduration(sub_obj));
+ } else {
+ conf_dnsrps_sadd(ctx, " %s %d", name,
+ cfg_obj_asuint32(sub_obj));
+ }
}
/*
}
obj = cfg_tuple_get(rpz_obj, "max-policy-ttl");
- if (cfg_obj_isuint32(obj)) {
- zone->max_policy_ttl = cfg_obj_asuint32(obj);
+ if (cfg_obj_isduration(obj)) {
+ zone->max_policy_ttl = cfg_obj_asduration(obj);
} else {
zone->max_policy_ttl = ttl_default;
}
obj = cfg_tuple_get(rpz_obj, "min-update-interval");
- if (cfg_obj_isuint32(obj)) {
- zone->min_update_interval = cfg_obj_asuint32(obj);
+ if (cfg_obj_isduration(obj)) {
+ zone->min_update_interval = cfg_obj_asduration(obj);
} else {
zone->min_update_interval = minupdateinterval_default;
}
}
sub_obj = cfg_tuple_get(rpz_obj, "max-policy-ttl");
- if (cfg_obj_isuint32(sub_obj))
- ttl_default = cfg_obj_asuint32(sub_obj);
+ if (cfg_obj_isduration(sub_obj))
+ ttl_default = cfg_obj_asduration(sub_obj);
else
ttl_default = DNS_RPZ_MAX_TTL_DEFAULT;
sub_obj = cfg_tuple_get(rpz_obj, "min-update-interval");
- if (cfg_obj_isuint32(sub_obj))
- minupdateinterval_default = cfg_obj_asuint32(sub_obj);
+ if (cfg_obj_isduration(sub_obj))
+ minupdateinterval_default = cfg_obj_asduration(sub_obj);
else
minupdateinterval_default = DNS_RPZ_MINUPDATEINTERVAL_DEFAULT;
}
obj = cfg_tuple_get(catz_obj, "min-update-interval");
- if (obj != NULL && cfg_obj_isuint32(obj))
- opts->min_update_interval = cfg_obj_asuint32(obj);
+ if (obj != NULL && cfg_obj_isduration(obj))
+ opts->min_update_interval = cfg_obj_asduration(obj);
cleanup:
if (pview != NULL)
result = named_config_get(maps, "fstrm-set-reopen-interval",
&obj);
if (result == ISC_R_SUCCESS) {
- i = cfg_obj_asuint32(obj);
+ i = cfg_obj_asduration(obj);
fstrm_iothr_options_set_reopen_interval(fopt, i);
}
obj = NULL;
result = named_config_get(maps, "max-cache-ttl", &obj);
INSIST(result == ISC_R_SUCCESS);
- view->maxcachettl = cfg_obj_asuint32(obj);
+ view->maxcachettl = cfg_obj_asduration(obj);
obj = NULL;
result = named_config_get(maps, "max-ncache-ttl", &obj);
INSIST(result == ISC_R_SUCCESS);
- view->maxncachettl = cfg_obj_asuint32(obj);
+ view->maxncachettl = cfg_obj_asduration(obj);
obj = NULL;
result = named_config_get(maps, "min-cache-ttl", &obj);
INSIST(result == ISC_R_SUCCESS);
- view->mincachettl = cfg_obj_asuint32(obj);
+ view->mincachettl = cfg_obj_asduration(obj);
obj = NULL;
result = named_config_get(maps, "min-ncache-ttl", &obj);
INSIST(result == ISC_R_SUCCESS);
- view->minncachettl = cfg_obj_asuint32(obj);
+ view->minncachettl = cfg_obj_asduration(obj);
obj = NULL;
result = named_config_get(maps, "synth-from-dnssec", &obj);
obj = NULL;
result = named_config_get(maps, "max-stale-ttl", &obj);
INSIST(result == ISC_R_SUCCESS);
- max_stale_ttl = ISC_MAX(cfg_obj_asuint32(obj), 1);
+ max_stale_ttl = ISC_MAX(cfg_obj_asduration(obj), 1);
obj = NULL;
result = named_config_get(maps, "stale-answer-enable", &obj);
obj = NULL;
result = named_config_get(maps, "stale-answer-ttl", &obj);
INSIST(result == ISC_R_SUCCESS);
- view->staleanswerttl = ISC_MAX(cfg_obj_asuint32(obj), 1);
+ view->staleanswerttl = ISC_MAX(cfg_obj_asduration(obj), 1);
/*
* Resolver.
obj = NULL;
result = named_config_get(maps, "lame-ttl", &obj);
INSIST(result == ISC_R_SUCCESS);
- lame_ttl = cfg_obj_asuint32(obj);
+ lame_ttl = cfg_obj_asduration(obj);
if (lame_ttl > 1800)
lame_ttl = 1800;
dns_resolver_setlamettl(view->resolver, lame_ttl);
obj = NULL;
result = named_config_get(maps, "nta-recheck", &obj);
INSIST(result == ISC_R_SUCCESS);
- view->nta_recheck = cfg_obj_asuint32(obj);
+ view->nta_recheck = cfg_obj_asduration(obj);
obj = NULL;
result = named_config_get(maps, "nta-lifetime", &obj);
INSIST(result == ISC_R_SUCCESS);
- view->nta_lifetime = cfg_obj_asuint32(obj);
+ view->nta_lifetime = cfg_obj_asduration(obj);
obj = NULL;
result = named_config_get(maps, "preferred-glue", &obj);
obj = NULL;
result = named_config_get(maps, "servfail-ttl", &obj);
INSIST(result == ISC_R_SUCCESS);
- fail_ttl = cfg_obj_asuint32(obj);
+ fail_ttl = cfg_obj_asduration(obj);
if (fail_ttl > 30)
fail_ttl = 30;
dns_view_setfailttl(view, fail_ttl);
obj = NULL;
result = named_config_get(maps, "interface-interval", &obj);
INSIST(result == ISC_R_SUCCESS);
- interface_interval = cfg_obj_asuint32(obj) * 60;
+ interface_interval = cfg_obj_asduration(obj);
if (interface_interval == 0) {
CHECK(isc_timer_reset(server->interface_timer,
isc_timertype_inactive,
} else if (result == ISC_R_SUCCESS) {
dns_ttl_t maxttl = 0; /* unlimited */
- if (cfg_obj_isuint32(obj))
- maxttl = cfg_obj_asuint32(obj);
+ if (cfg_obj_isduration(obj))
+ maxttl = cfg_obj_asduration(obj);
dns_zone_setmaxttl(zone, maxttl);
if (raw != NULL)
dns_zone_setmaxttl(raw, maxttl);
<command>max-records</command> <replaceable>integer</replaceable>;
<command>max-transfer-idle-out</command> <replaceable>integer</replaceable>;
<command>max-transfer-time-out</command> <replaceable>integer</replaceable>;
- <command>max-zone-ttl</command> ( unlimited | <replaceable>ttlval</replaceable> );
+ <command>max-zone-ttl</command> ( unlimited | <replaceable>duration</replaceable> );
<command>notify</command> ( explicit | master-only | <replaceable>boolean</replaceable> );
<command>notify-delay</command> <replaceable>integer</replaceable>;
<command>notify-source</command> ( <replaceable>ipv4_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ] [ dscp <replaceable>integer</replaceable> ];
[ dscp <replaceable>integer</replaceable> ] { ( <replaceable>masters</replaceable> | <replaceable>ipv4_address</replaceable> [ port
<replaceable>integer</replaceable> ] | <replaceable>ipv6_address</replaceable> [ port <replaceable>integer</replaceable> ] ) [ key
<replaceable>string</replaceable> ]; ... } ] [ zone-directory <replaceable>quoted_string</replaceable> ] [
- <command>in-memory</command> <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>ttlval</replaceable> ]; ... };
+ <command>in-memory</command> <replaceable>boolean</replaceable> ] [ min-update-interval <replaceable>duration</replaceable> ]; ... };
<command>check-dup-records</command> ( fail | warn | ignore );
<command>check-integrity</command> <replaceable>boolean</replaceable>;
<command>check-mx</command> ( fail | warn | ignore );
<command>fstrm-set-output-notify-threshold</command> <replaceable>integer</replaceable>;
<command>fstrm-set-output-queue-model</command> ( mpsc | spsc );
<command>fstrm-set-output-queue-size</command> <replaceable>integer</replaceable>;
- <command>fstrm-set-reopen-interval</command> <replaceable>ttlval</replaceable>;
+ <command>fstrm-set-reopen-interval</command> <replaceable>duration</replaceable>;
<command>geoip-directory</command> ( <replaceable>quoted_string</replaceable> | none );
<command>glue-cache</command> <replaceable>boolean</replaceable>;
<command>heartbeat-interval</command> <replaceable>integer</replaceable>;
<command>hostname</command> ( <replaceable>quoted_string</replaceable> | none );
<command>inline-signing</command> <replaceable>boolean</replaceable>;
- <command>interface-interval</command> <replaceable>ttlval</replaceable>;
+ <command>interface-interval</command> <replaceable>duration</replaceable>;
<command>ixfr-from-differences</command> ( primary | master | secondary | slave |
<replaceable>boolean</replaceable> );
<command>keep-response-order</command> { <replaceable>address_match_element</replaceable>; ... };
<command>key-directory</command> <replaceable>quoted_string</replaceable>;
- <command>lame-ttl</command> <replaceable>ttlval</replaceable>;
+ <command>lame-ttl</command> <replaceable>duration</replaceable>;
<command>listen-on</command> [ port <replaceable>integer</replaceable> ] [ dscp
<replaceable>integer</replaceable> ] {
<replaceable>address_match_element</replaceable>; ... };
<command>masterfile-style</command> ( full | relative );
<command>match-mapped-addresses</command> <replaceable>boolean</replaceable>;
<command>max-cache-size</command> ( default | unlimited | <replaceable>sizeval</replaceable> | <replaceable>percentage</replaceable> );
- <command>max-cache-ttl</command> <replaceable>ttlval</replaceable>;
+ <command>max-cache-ttl</command> <replaceable>duration</replaceable>;
<command>max-clients-per-query</command> <replaceable>integer</replaceable>;
<command>max-journal-size</command> ( default | unlimited | <replaceable>sizeval</replaceable> );
- <command>max-ncache-ttl</command> <replaceable>ttlval</replaceable>;
+ <command>max-ncache-ttl</command> <replaceable>duration</replaceable>;
<command>max-records</command> <replaceable>integer</replaceable>;
<command>max-recursion-depth</command> <replaceable>integer</replaceable>;
<command>max-recursion-queries</command> <replaceable>integer</replaceable>;
<command>max-refresh-time</command> <replaceable>integer</replaceable>;
<command>max-retry-time</command> <replaceable>integer</replaceable>;
<command>max-rsa-exponent-size</command> <replaceable>integer</replaceable>;
- <command>max-stale-ttl</command> <replaceable>ttlval</replaceable>;
+ <command>max-stale-ttl</command> <replaceable>duration</replaceable>;
<command>max-transfer-idle-in</command> <replaceable>integer</replaceable>;
<command>max-transfer-idle-out</command> <replaceable>integer</replaceable>;
<command>max-transfer-time-in</command> <replaceable>integer</replaceable>;
<command>max-transfer-time-out</command> <replaceable>integer</replaceable>;
<command>max-udp-size</command> <replaceable>integer</replaceable>;
- <command>max-zone-ttl</command> ( unlimited | <replaceable>ttlval</replaceable> );
+ <command>max-zone-ttl</command> ( unlimited | <replaceable>duration</replaceable> );
<command>memstatistics</command> <replaceable>boolean</replaceable>;
<command>memstatistics-file</command> <replaceable>quoted_string</replaceable>;
<command>message-compression</command> <replaceable>boolean</replaceable>;
- <command>min-cache-ttl</command> <replaceable>ttlval</replaceable>;
- <command>min-ncache-ttl</command> <replaceable>ttlval</replaceable>;
+ <command>min-cache-ttl</command> <replaceable>duration</replaceable>;
+ <command>min-ncache-ttl</command> <replaceable>duration</replaceable>;
<command>min-refresh-time</command> <replaceable>integer</replaceable>;
<command>min-retry-time</command> <replaceable>integer</replaceable>;
<command>minimal-any</command> <replaceable>boolean</replaceable>;
<command>notify-source-v6</command> ( <replaceable>ipv6_address</replaceable> | * ) [ port ( <replaceable>integer</replaceable> | * ) ]
[ dscp <replaceable>integer</replaceable> ];
<command>notify-to-soa</command> <replaceable>boolean</replaceable>;
- <command>nta-lifetime</command> <replaceable>ttlval</replaceable>;
- <command>nta-recheck</command> <replaceable>ttlval</replaceable>;
+ <command>nta-lifetime</command> <replaceable>duration</replaceable>;
+ <command>nta-recheck</command> <replaceable>duration</replaceable>;
<command>nxdomain-redirect</command> <replaceable>string</replaceable>;
<command>pid-file</command> ( <replaceable>quoted_string</replaceable> | none );
<command>port</command> <replaceable>integer</replaceable>;
<command>response-padding</command> { <replaceable>address_match_element</replaceable>; ... } block-size
<replaceable>integer</replaceable>;
<command>response-policy</command> { zone <replaceable>string</replaceable> [ add-soa <replaceable>boolean</replaceable> ] [ log
- <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [ min-update-interval
- <replaceable>ttlval</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
+ <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [ min-update-interval
+ <replaceable>duration</replaceable> ] [ policy ( cname | disabled | drop | given | no-op |
<command>nodata</command> | nxdomain | passthru | tcp-only <replaceable>quoted_string</replaceable> ) ] [
<command>recursive-only</command> <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
<command>nsdname-enable</command> <replaceable>boolean</replaceable> ]; ... } [ add-soa <replaceable>boolean</replaceable> ] [
- <command>break-dnssec</command> <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>ttlval</replaceable> ] [
- <command>min-update-interval</command> <replaceable>ttlval</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
+ <command>break-dnssec</command> <replaceable>boolean</replaceable> ] [ max-policy-ttl <replaceable>duration</replaceable> ] [
+ <command>min-update-interval</command> <replaceable>duration</replaceable> ] [ min-ns-dots <replaceable>integer</replaceable> ] [
<command>nsip-wait-recurse</command> <replaceable>boolean</replaceable> ] [ qname-wait-recurse <replaceable>boolean</replaceable> ]
[ recursive-only <replaceable>boolean</replaceable> ] [ nsip-enable <replaceable>boolean</replaceable> ] [
<command>nsdname-enable</command> <replaceable>boolean</replaceable> ] [ dnsrps-enable <replaceable>boolean</replaceable> ] [
<command>serial-query-rate</command> <replaceable>integer</replaceable>;
<command>serial-update-method</command> ( date | increment | unixtime );
<command>server-id</command> ( <replaceable>quoted_string</replaceable> | none | hostname );
- <command>servfail-ttl</command> <replaceable>ttlval</replaceable>;
+ <command>servfail-ttl</command> <replaceable>duration</replaceable>;
<command>session-keyalg</command> <replaceable>string</replaceable>;
<command>session-keyfile</command> ( <replaceable>quoted_string</replaceable> | none );
<command>session-keyname</command> <replaceable>string</replaceable>;
<command>sortlist</command> { <replaceable>address_match_element</replaceable>; ... };
<command>stacksize</command> ( default | unlimited | <replaceable>sizeval</replaceable> );
<command>stale-answer-enable</command> <replaceable>boolean</replaceable>;
- <command>stale-answer-ttl</command> <replaceable>ttlval</replaceable>;
+ <command>stale-answer-ttl</command> <replaceable>duration</replaceable>;
<command>startup-notify-rate</command> <replaceable>integer</replaceable>;
<command>statistics-file</command> <replaceable>quoted_string</replaceable>;
<command>synth-from-dnssec</command> <replaceable>boolean</replaceable>;
<command>masterfile-style</command> ( full | relative );
<command>masters</command> [ port <replaceable>integer</replaceable> ] [ dscp <replaceable>integer</replaceable> ] { ( <replaceable>masters</replaceable> | <replaceable>ipv4_address</replaceable> [ port <replaceable>integer</replaceable> ] | <replaceable>ipv6_address</replaceable> [ port <replaceable>integer</replaceable> ] ) [ key <replaceable>string</replaceable> ]; ... };
<command>max-records</command> <replaceable>integer</replaceable>;
- <command>max-zone-ttl</command> ( unlimited | <replaceable>ttlval</replaceable> );
+ <command>max-zone-ttl</command> ( unlimited | <replaceable>duration</replaceable> );
<command>zone-statistics</command> ( full | terse | none | <replaceable>boolean</replaceable> );
};
</programlisting>
(void)cfg_map_get(options, intervals[i].name, &obj);
if (obj == NULL)
continue;
- val = cfg_obj_asuint32(obj);
+ if (cfg_obj_isduration(obj)) {
+ val = cfg_obj_asduration(obj);
+ } else {
+ val = cfg_obj_asuint32(obj);
+ }
if (val > intervals[i].max) {
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"%s '%u' is out of range (0..%u)",
obj = NULL;
(void)cfg_map_get(options, "nta-lifetime", &obj);
if (obj != NULL) {
- lifetime = cfg_obj_asuint32(obj);
+ lifetime = cfg_obj_asduration(obj);
if (lifetime > 604800) { /* 7 days */
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"'nta-lifetime' cannot exceed one week");
obj = NULL;
(void)cfg_map_get(options, "nta-recheck", &obj);
if (obj != NULL) {
- uint32_t recheck = cfg_obj_asuint32(obj);
+ uint32_t recheck = cfg_obj_asduration(obj);
if (recheck > 604800) { /* 7 days */
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
"'nta-recheck' cannot exceed one week");
if (obj == NULL)
continue;
- value = cfg_obj_asuint32(obj);
+ if (cfg_obj_isduration(obj)) {
+ value = cfg_obj_asduration(obj);
+ } else {
+ value = cfg_obj_asuint32(obj);
+ }
if (value < fstrm[i].min ||
(fstrm[i].max != 0U && value > fstrm[i].max)) {
if (fstrm[i].max != 0U)
#include <inttypes.h>
#include <stdbool.h>
+#include <time.h>
#include <isc/formatcheck.h>
#include <isc/lang.h>
* \li A 32-bit unsigned integer.
*/
+bool
+cfg_obj_isduration(const cfg_obj_t *obj);
+/*%<
+ * Return true iff 'obj' is of duration type.
+ */
+
+uint32_t
+cfg_obj_asduration(const cfg_obj_t *obj);
+/*%<
+ * Returns the value of a configuration object of duration
+ *
+ * Requires:
+ * \li 'obj' points to a valid configuration object of duration type.
+ *
+ * Returns:
+ * \li A duration in seconds.
+ */
+
bool
cfg_obj_isstring(const cfg_obj_t *obj);
/*%<
typedef ISC_LIST(cfg_listelt_t) cfg_list_t;
typedef struct cfg_map cfg_map_t;
typedef struct cfg_rep cfg_rep_t;
+typedef struct cfg_duration cfg_duration_t;
+
+#define CFG_DURATION_MAXLEN 64
/*
* Function types for configuration object methods
unsigned int prefixlen;
};
+/*%
+ * A configuration object to store ISO 8601 durations.
+ */
+struct cfg_duration {
+ /*
+ * The duration is stored in multiple parts:
+ * [0] Years
+ * [1] Months
+ * [2] Weeks
+ * [3] Days
+ * [4] Hours
+ * [5] Minutes
+ * [6] Seconds
+ */
+ uint32_t parts[7];
+ bool iso8601;
+};
+
/*%
* A configuration data representation.
*/
isc_dscp_t dscp;
} sockaddrdscp;
cfg_netprefix_t netprefix;
+ cfg_duration_t duration;
} value;
isc_refcount_t references; /*%< reference counter */
const char * file;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_fixedpoint;
LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_percentage;
+LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_duration;
/*@}*/
/*@{*/
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_fixedpoint;
LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_percentage;
+LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_duration;
/*@}*/
isc_result_t
void
cfg_print_percentage(cfg_printer_t *pctx, const cfg_obj_t *obj);
+isc_result_t
+cfg_parse_duration(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret);
+
+void
+cfg_print_duration(cfg_printer_t *pctx, const cfg_obj_t *obj);
+
isc_result_t
cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
static cfg_type_t cfg_type_sockaddr4wild;
static cfg_type_t cfg_type_sockaddr6wild;
static cfg_type_t cfg_type_statschannels;
-static cfg_type_t cfg_type_ttlval;
static cfg_type_t cfg_type_view;
static cfg_type_t cfg_type_viewopts;
static cfg_type_t cfg_type_zone;
{ "fstrm-set-output-notify-threshold", &cfg_type_uint32, 0 },
{ "fstrm-set-output-queue-model", &cfg_type_fstrm_model, 0 },
{ "fstrm-set-output-queue-size", &cfg_type_uint32, 0 },
- { "fstrm-set-reopen-interval", &cfg_type_ttlval, 0 },
+ { "fstrm-set-reopen-interval", &cfg_type_duration, 0 },
#else
{ "fstrm-set-buffer-hint", &cfg_type_uint32,
CFG_CLAUSEFLAG_NOTCONFIGURED },
CFG_CLAUSEFLAG_NOTCONFIGURED },
{ "fstrm-set-output-queue-size", &cfg_type_uint32,
CFG_CLAUSEFLAG_NOTCONFIGURED },
- { "fstrm-set-reopen-interval", &cfg_type_ttlval,
+ { "fstrm-set-reopen-interval", &cfg_type_duration,
CFG_CLAUSEFLAG_NOTCONFIGURED },
#endif /* HAVE_DNSTAP */
#if defined(HAVE_GEOIP2)
{ "host-statistics", &cfg_type_boolean, CFG_CLAUSEFLAG_ANCIENT },
{ "host-statistics-max", &cfg_type_uint32, CFG_CLAUSEFLAG_ANCIENT },
{ "hostname", &cfg_type_qstringornone, 0 },
- { "interface-interval", &cfg_type_ttlval, 0 },
+ { "interface-interval", &cfg_type_duration, 0 },
{ "keep-response-order", &cfg_type_bracketed_aml, 0 },
{ "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
{ "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
{ "zone name", &cfg_type_rpz_zone, 0 },
{ "add-soa", &cfg_type_boolean, 0 },
{ "log", &cfg_type_boolean, 0 },
- { "max-policy-ttl", &cfg_type_ttlval, 0 },
- { "min-update-interval", &cfg_type_ttlval, 0 },
+ { "max-policy-ttl", &cfg_type_duration, 0 },
+ { "min-update-interval", &cfg_type_duration, 0 },
{ "policy", &cfg_type_rpz_policy, 0 },
{ "recursive-only", &cfg_type_boolean, 0 },
{ "nsip-enable", &cfg_type_boolean, 0 },
{ "zone list", &cfg_type_rpz_list, 0 },
{ "add-soa", &cfg_type_boolean, 0 },
{ "break-dnssec", &cfg_type_boolean, 0 },
- { "max-policy-ttl", &cfg_type_ttlval, 0 },
- { "min-update-interval", &cfg_type_ttlval, 0 },
+ { "max-policy-ttl", &cfg_type_duration, 0 },
+ { "min-update-interval", &cfg_type_duration, 0 },
{ "min-ns-dots", &cfg_type_uint32, 0 },
{ "nsip-wait-recurse", &cfg_type_boolean, 0 },
{ "qname-wait-recurse", &cfg_type_boolean, 0 },
{ "default-masters", &cfg_type_namesockaddrkeylist, 0 },
{ "zone-directory", &cfg_type_qstring, 0 },
{ "in-memory", &cfg_type_boolean, 0 },
- { "min-update-interval", &cfg_type_ttlval, 0 },
+ { "min-update-interval", &cfg_type_duration, 0 },
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_catz_tuple = {
{ "filter-aaaa-on-v6", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
{ "glue-cache", &cfg_type_boolean, 0 },
{ "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 },
- { "lame-ttl", &cfg_type_ttlval, 0 },
+ { "lame-ttl", &cfg_type_duration, 0 },
#ifdef HAVE_LMDB
{ "lmdb-mapsize", &cfg_type_sizeval, 0 },
#else
#endif
{ "max-acache-size", &cfg_type_sizenodefault, CFG_CLAUSEFLAG_OBSOLETE },
{ "max-cache-size", &cfg_type_sizeorpercent, 0 },
- { "max-cache-ttl", &cfg_type_ttlval, 0 },
+ { "max-cache-ttl", &cfg_type_duration, 0 },
{ "max-clients-per-query", &cfg_type_uint32, 0 },
- { "max-ncache-ttl", &cfg_type_ttlval, 0 },
+ { "max-ncache-ttl", &cfg_type_duration, 0 },
{ "max-recursion-depth", &cfg_type_uint32, 0 },
{ "max-recursion-queries", &cfg_type_uint32, 0 },
- { "max-stale-ttl", &cfg_type_ttlval, 0 },
+ { "max-stale-ttl", &cfg_type_duration, 0 },
{ "max-udp-size", &cfg_type_uint32, 0 },
{ "message-compression", &cfg_type_boolean, 0 },
- { "min-cache-ttl", &cfg_type_ttlval, 0 },
- { "min-ncache-ttl", &cfg_type_ttlval, 0 },
+ { "min-cache-ttl", &cfg_type_duration, 0 },
+ { "min-ncache-ttl", &cfg_type_duration, 0 },
{ "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_ANCIENT },
{ "minimal-any", &cfg_type_boolean, 0 },
{ "minimal-responses", &cfg_type_minimal, 0 },
{ "no-case-compress", &cfg_type_bracketed_aml, 0 },
{ "nocookie-udp-size", &cfg_type_uint32, 0 },
{ "nosit-udp-size", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE },
- { "nta-lifetime", &cfg_type_ttlval, 0 },
- { "nta-recheck", &cfg_type_ttlval, 0 },
+ { "nta-lifetime", &cfg_type_duration, 0 },
+ { "nta-recheck", &cfg_type_duration, 0 },
{ "nxdomain-redirect", &cfg_type_astring, 0 },
{ "preferred-glue", &cfg_type_astring, 0 },
{ "prefetch", &cfg_type_prefetch, 0 },
{ "root-key-sentinel", &cfg_type_boolean, 0 },
{ "rrset-order", &cfg_type_rrsetorder, 0 },
{ "send-cookie", &cfg_type_boolean, 0 },
- { "servfail-ttl", &cfg_type_ttlval, 0 },
+ { "servfail-ttl", &cfg_type_duration, 0 },
{ "sortlist", &cfg_type_bracketed_aml, 0 },
{ "stale-answer-enable", &cfg_type_boolean, 0 },
- { "stale-answer-ttl", &cfg_type_ttlval, 0 },
+ { "stale-answer-ttl", &cfg_type_duration, 0 },
{ "suppress-initial-notify", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI },
{ "synth-from-dnssec", &cfg_type_boolean, 0 },
{ "topology", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_ANCIENT },
doc_masterselement, NULL, NULL
};
-static isc_result_t
-parse_ttlval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
- isc_result_t result;
- cfg_obj_t *obj = NULL;
- uint32_t ttl;
-
- UNUSED(type);
-
- CHECK(cfg_gettoken(pctx, 0));
- if (pctx->token.type != isc_tokentype_string) {
- result = ISC_R_UNEXPECTEDTOKEN;
- goto cleanup;
- }
-
- result = dns_ttl_fromtext(&pctx->token.value.as_textregion, &ttl);
- if (result == ISC_R_RANGE ) {
- cfg_parser_error(pctx, CFG_LOG_NEAR, "TTL out of range ");
- return (result);
- } else if (result != ISC_R_SUCCESS)
- goto cleanup;
-
- CHECK(cfg_create_obj(pctx, &cfg_type_uint32, &obj));
- obj->value.uint32 = ttl;
- *ret = obj;
- return (ISC_R_SUCCESS);
-
- cleanup:
- cfg_parser_error(pctx, CFG_LOG_NEAR,
- "expected integer and optional unit");
- return (result);
-}
-
-/*%
- * A TTL value (number + optional unit).
- */
-static cfg_type_t cfg_type_ttlval = {
- "ttlval", parse_ttlval, cfg_print_uint64, cfg_doc_terminal,
- &cfg_rep_uint64, NULL
-};
-
static isc_result_t
parse_maxttl(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
- return (cfg_parse_enum_or_other(pctx, type, &cfg_type_ttlval, ret));
+ return (cfg_parse_enum_or_other(pctx, type, &cfg_type_duration, ret));
}
static void
doc_maxttl(cfg_printer_t *pctx, const cfg_type_t *type) {
- cfg_doc_enum_or_other(pctx, type, &cfg_type_ttlval);
+ cfg_doc_enum_or_other(pctx, type, &cfg_type_duration);
}
/*%
#include <isccfg/grammar.h>
#include <isccfg/log.h>
+#include <dns/ttl.h>
+
/* Shorthand */
#define CAT CFG_LOGCATEGORY_CONFIG
#define MOD CFG_LOGMODULE_PARSER
{ "fixedpoint", free_noop };
LIBISCCFG_EXTERNAL_DATA cfg_rep_t cfg_rep_percentage =
{ "percentage", free_noop };
+LIBISCCFG_EXTERNAL_DATA cfg_rep_t cfg_rep_duration = { "duration", free_noop };
/*
* Configuration type definitions.
&cfg_rep_uint64, NULL
};
+/*
+ * Get the number of digits in a number.
+ */
+static size_t
+numlen(time_t num) {
+ uint32_t period = (uint32_t) num;
+ size_t count = 0;
+
+ if (period == 0) {
+ return 1;
+ }
+ while (period > 0) {
+ count++;
+ period /= 10;
+ }
+ return (count);
+}
+
+/*
+ * duration
+ */
+void
+cfg_print_duration(cfg_printer_t *pctx, const cfg_obj_t *obj) {
+ char buf[CFG_DURATION_MAXLEN];
+ char *str;
+ const char *indicators = "YMWDHMS";
+ int count, i;
+ int durationlen[7];
+ cfg_duration_t duration;
+ /*
+ * D ? The duration has a date part.
+ * T ? The duration has a time part.
+ */
+ bool D = false, T = false;
+
+ REQUIRE(pctx != NULL);
+ REQUIRE(obj != NULL);
+
+ duration = obj->value.duration;
+
+ /* If this is not an ISO 8601 duration, just print it as a number. */
+ if (!duration.iso8601) {
+ return (cfg_print_rawuint(pctx, duration.parts[6]));
+ }
+
+ /* Calculate length of string. */
+ buf[0] = 'P';
+ buf[1] = '\0';
+ str = &buf[1];
+ count = 2;
+ for (i = 0; i < 6; i++) {
+ if (duration.parts[i] > 0) {
+ durationlen[i] = 1 + numlen(duration.parts[i]);
+ if (i < 4) {
+ D = true;
+ } else {
+ T = true;
+ }
+ } else {
+ durationlen[i] = 0;
+ }
+ count += durationlen[i];
+ }
+ /*
+ * Special case for seconds which is not taken into account in the
+ * above for loop: Count the length of the seconds part if it is
+ * non-zero, or if all the other parts are also zero. In the latter
+ * case this function will print "PT0S".
+ */
+ if (duration.parts[6] > 0 ||
+ (!D && !duration.parts[4] && !duration.parts[5])) {
+ durationlen[6] = 1 + numlen(duration.parts[6]);
+ T = true;
+ count += durationlen[6];
+ }
+ /* Add one character for the time indicator. */
+ if (T) {
+ count++;
+ }
+ INSIST(count < CFG_DURATION_MAXLEN);
+
+ /* Now print the duration. */
+ for (i = 0; i < 6; i++) {
+ /*
+ * We don't check here if weeks and other time indicator are
+ * used mutually exclusively.
+ */
+ if (duration.parts[i] > 0) {
+ snprintf(str, durationlen[i]+2, "%u%c",
+ (uint32_t) duration.parts[i], indicators[i]);
+ str += durationlen[i]+1;
+ }
+ if (i == 3 && T) {
+ snprintf(str, 2, "T");
+ str += 1;
+ }
+
+ }
+ /* Special case for seconds. */
+ if (duration.parts[6] > 0 ||
+ (!D && !duration.parts[4] && !duration.parts[3])) {
+ snprintf(str, durationlen[6]+2, "%u%c",
+ (uint32_t) duration.parts[6], indicators[6]);
+ }
+ cfg_print_chars(pctx, buf, strlen(buf));
+}
+
+bool
+cfg_obj_isduration(const cfg_obj_t *obj) {
+ REQUIRE(obj != NULL);
+ return (obj->type->rep == &cfg_rep_duration);
+}
+
+uint32_t
+cfg_obj_asduration(const cfg_obj_t *obj) {
+ REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_duration);
+ uint32_t duration = 0;
+ duration += obj->value.duration.parts[6]; // Seconds
+ duration += obj->value.duration.parts[5]*60; // Minutes
+ duration += obj->value.duration.parts[4]*3600; // Hours
+ duration += obj->value.duration.parts[3]*86400; // Days
+ duration += obj->value.duration.parts[2]*86400*7; // Weaks
+ /*
+ * The below additions are not entirely correct
+ * because days may very per month and per year.
+ */
+ duration += obj->value.duration.parts[1]*86400*31; // Months
+ duration += obj->value.duration.parts[0]*86400*365; // Years
+ return (duration);
+}
+
+/*
+ * duration_fromtext initially taken from OpenDNSSEC code base.
+ * Modified to fit the BIND 9 code.
+ *
+ * Copyright (c) 2009-2018 NLNet Labs.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+static isc_result_t
+duration_fromtext(isc_textregion_t *source, cfg_duration_t *duration) {
+ char buf[CFG_DURATION_MAXLEN];
+ char *P, *X, *T, *W, *str;
+ bool not_weeks = false;
+ int i;
+
+ /*
+ * Copy the buffer as it may not be NULL terminated.
+ * Anyone having a duration longer than 63 characters is crazy.
+ */
+ if (source->length > sizeof(buf) - 1) {
+ return (ISC_R_BADNUMBER);
+ }
+ /* Copy source->length bytes and NULL terminate. */
+ snprintf(buf, sizeof(buf), "%.*s", (int)source->length, source->base);
+ str = buf;
+
+ /* Clear out duration. */
+ for (i = 0; i < 7; i++) {
+ duration->parts[i] = 0;
+ }
+
+ /* Every duration starts with 'P' */
+ P = strchr(str, 'P');
+ if (!P) {
+ return (ISC_R_BADNUMBER);
+ }
+
+ /* Record the time indicator. */
+ T = strchr(str, 'T');
+
+ /* Record years. */
+ X = strchr(str, 'Y');
+ if (X) {
+ duration->parts[0] = atoi(str+1);
+ str = X;
+ not_weeks = true;
+ }
+ /* Record months. */
+ X = strchr(str, 'M');
+ /*
+ * M could be months or minutes. This is months if there is no time
+ * part, or this M indicator is before the time indicator.
+ */
+ if (X && (!T || (size_t) (X-P) < (size_t) (T-P))) {
+ duration->parts[1] = atoi(str+1);
+ str = X;
+ not_weeks = true;
+ }
+ /* Record days. */
+ X = strchr(str, 'D');
+ if (X) {
+ duration->parts[3] = atoi(str+1);
+ str = X;
+ not_weeks = true;
+ }
+
+ /* Time part? */
+ if (T) {
+ str = T;
+ not_weeks = true;
+ }
+
+ /* Record hours. */
+ X = strchr(str, 'H');
+ if (X && T) {
+ duration->parts[4] = atoi(str+1);
+ str = X;
+ not_weeks = true;
+ }
+ /* Record minutes. */
+ X = strrchr(str, 'M');
+ /*
+ * M could be months or minutes. This is minutes if there is a time
+ * part and the M indicator is behind the time indicator.
+ */
+ if (X && T && (size_t) (X-P) > (size_t) (T-P)) {
+ duration->parts[5] = atoi(str+1);
+ str = X;
+ not_weeks = true;
+ }
+ /* Record seconds. */
+ X = strchr(str, 'S');
+ if (X && T) {
+ duration->parts[6] = atoi(str+1);
+ str = X;
+ not_weeks = true;
+ }
+
+ /* Or is the duration configured in weeks? */
+ W = strchr(buf, 'W');
+ if (W) {
+ if (not_weeks) {
+ /* Mix of weeks and other indicators is not allowed */
+ return (ISC_R_BADNUMBER);
+ } else {
+ duration->parts[2] = atoi(str+1);
+ str = W;
+ }
+ }
+
+ /* Deal with trailing garbage. */
+ if (str[1] != '\0') {
+ return (ISC_R_BADNUMBER);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+cfg_parse_duration(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret)
+{
+ isc_result_t result;
+ cfg_obj_t *obj = NULL;
+ cfg_duration_t duration;
+
+ UNUSED(type);
+
+ CHECK(cfg_gettoken(pctx, 0));
+ if (pctx->token.type != isc_tokentype_string) {
+ result = ISC_R_UNEXPECTEDTOKEN;
+ goto cleanup;
+ }
+
+ if (TOKEN_STRING(pctx)[0] == 'P') {
+ result = duration_fromtext(&pctx->token.value.as_textregion,
+ &duration);
+ duration.iso8601 = true;
+ } else {
+ uint32_t ttl;
+ result = dns_ttl_fromtext(&pctx->token.value.as_textregion,
+ &ttl);
+ /*
+ * With dns_ttl_fromtext() the information on optional units.
+ * is lost, and is treated as seconds from now on.
+ */
+ duration.parts[0] = 0;
+ duration.parts[1] = 0;
+ duration.parts[2] = 0;
+ duration.parts[3] = 0;
+ duration.parts[4] = 0;
+ duration.parts[5] = 0;
+ duration.parts[6] = ttl;
+ duration.iso8601 = false;
+ }
+ if (result == ISC_R_RANGE) {
+ cfg_parser_error(pctx, CFG_LOG_NEAR,
+ "duration or TTL out of range");
+ return (result);
+ } else if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
+ CHECK(cfg_create_obj(pctx, &cfg_type_duration, &obj));
+ obj->value.duration = duration;
+ *ret = obj;
+ return (ISC_R_SUCCESS);
+
+cleanup:
+ cfg_parser_error(pctx, CFG_LOG_NEAR,
+ "expected ISO 8601 duration or TTL value");
+ return (result);
+}
+
+/*%
+ * A duration as defined by ISO 8601 (P[n]Y[n]M[n]DT[n]H[n]M[n]S).
+ * - P is the duration indicator ("period") placed at the start.
+ * - Y is the year indicator that follows the value for the number of years.
+ * - M is the month indicator that follows the value for the number of months.
+ * - D is the day indicator that follows the value for the number of days.
+ * - T is the time indicator that precedes the time components.
+ * - H is the hour indicator that follows the value for the number of hours.
+ * - M is the minute indicator that follows the value for the number of
+ * minutes.
+ * - S is the second indicator that follows the value for the number of
+ * seconds.
+ *
+ * A duration can also be a TTL value (number + optional unit).
+ */
+LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_duration = {
+ "duration", cfg_parse_duration, cfg_print_duration, cfg_doc_terminal,
+ &cfg_rep_duration, NULL
+};
+
/*
* qstring (quoted string), ustring (unquoted string), astring
- * (any string)
+ * (any string), sstring (secret string)
*/
/* Create a string object from a null-terminated C string. */
syntax(2)
test_suite('bind9')
+tap_test_program{name='duration_test'}
tap_test_program{name='parser_test'}
LIBS = @LIBS@ @CMOCKA_LIBS@
OBJS =
-SRCS = parser_test.c
+SRCS = duration_test.c parser_test.c
SUBDIRS =
-TARGETS = parser_test@EXEEXT@
+TARGETS = duration_test@EXEEXT@ parser_test@EXEEXT@
@BIND9_MAKE_RULES@
+duration_test@EXEEXT@: duration_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${ISCCFGDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \
+ ${LDFLAGS} -o $@ duration_test.@O@ \
+ ${ISCCFGLIBS} ${DNSLIBS} ${ISCLIBS} ${LIBS}
+
parser_test@EXEEXT@: parser_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} ${ISCCFGDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} \
${LDFLAGS} -o $@ parser_test.@O@ \
--- /dev/null
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+#if HAVE_CMOCKA
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+
+#include <sched.h> /* IWYU pragma: keep */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define UNIT_TESTING
+#include <cmocka.h>
+
+#include <isc/buffer.h>
+#include <isc/lex.h>
+#include <isc/log.h>
+#include <isc/mem.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+#include <isccfg/cfg.h>
+#include <isccfg/grammar.h>
+#include <isccfg/namedconf.h>
+
+#define CHECK(r) \
+ do { \
+ result = (r); \
+ if (result != ISC_R_SUCCESS) \
+ goto cleanup; \
+ } while (0)
+
+isc_mem_t *mctx = NULL;
+isc_log_t *lctx = NULL;
+static isc_logcategory_t categories[] = {
+ { "", 0 },
+ { "client", 0 },
+ { "network", 0 },
+ { "update", 0 },
+ { "queries", 0 },
+ { "unmatched", 0 },
+ { "update-security", 0 },
+ { "query-errors", 0 },
+ { NULL, 0 }
+};
+
+static void
+cleanup() {
+ if (lctx != NULL) {
+ isc_log_destroy(&lctx);
+ }
+ if (mctx != NULL) {
+ isc_mem_destroy(&mctx);
+ }
+}
+
+static isc_result_t
+setup() {
+ isc_result_t result;
+
+ isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
+ isc_mem_create(&mctx);
+
+ isc_logdestination_t destination;
+ isc_logconfig_t *logconfig = NULL;
+
+ CHECK(isc_log_create(mctx, &lctx, &logconfig));
+ isc_log_registercategories(lctx, categories);
+ isc_log_setcontext(lctx);
+
+ destination.file.stream = stderr;
+ destination.file.name = NULL;
+ destination.file.versions = ISC_LOG_ROLLNEVER;
+ destination.file.maximum_size = 0;
+ CHECK(isc_log_createchannel(logconfig, "stderr",
+ ISC_LOG_TOFILEDESC,
+ ISC_LOG_DYNAMIC,
+ &destination, 0));
+ CHECK(isc_log_usechannel(logconfig, "stderr", NULL, NULL));
+
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ cleanup();
+ return (result);
+}
+
+struct duration_conf {
+ const char* string;
+ uint32_t time;
+};
+typedef struct duration_conf duration_conf_t;
+
+/* test cfg_obj_asduration() */
+static void
+cfg_obj_asduration_test(void **state) {
+ isc_result_t result;
+ duration_conf_t durations[] = {
+ { .string = "PT0S", .time = 0 },
+ { .string = "PT42S", .time = 42 },
+ { .string = "PT10M", .time = 600 },
+ { .string = "PT10M4S", .time = 604 },
+ { .string = "PT2H", .time = 7200 },
+ { .string = "PT2H3S", .time = 7203 },
+ { .string = "PT2H1M3S", .time = 7263 },
+ { .string = "P7D", .time = 604800 },
+ { .string = "P7DT2H", .time = 612000 },
+ { .string = "P2W", .time = 1209600 },
+ { .string = "P3M", .time = 8035200 },
+ { .string = "P3MT10M", .time = 8035800 },
+ { .string = "P5Y", .time = 157680000 },
+ { .string = "P5YT2H", .time = 157687200 },
+ { .string = "P1Y1M1DT1H1M1S", .time = 34304461 },
+ { .string = "0", .time = 0 },
+ { .string = "30", .time = 30 },
+ { .string = "42s", .time = 42 },
+ { .string = "10m", .time = 600 },
+ { .string = "2h", .time = 7200 },
+ { .string = "7d", .time = 604800 },
+ { .string = "2w", .time = 1209600 },
+ };
+ int num = 22;
+ isc_buffer_t buf1;
+ cfg_parser_t *p1 = NULL;
+ cfg_obj_t *c1 = NULL;
+
+ UNUSED(state);
+
+ setup();
+
+ for (int i = 0; i < num; i++) {
+ const cfg_listelt_t *element;
+ const cfg_obj_t *kasps = NULL;
+ char conf[64];
+ sprintf(&conf[0],
+ "dnssec-policy \"dp\"\n{\nsignatures-refresh %s;\n};\n",
+ durations[i].string);
+
+ isc_buffer_init(&buf1, conf, strlen(conf) - 1);
+ isc_buffer_add(&buf1, strlen(conf) - 1);
+
+ /* Parse with default line numbering */
+ result = cfg_parser_create(mctx, lctx, &p1);
+ assert_int_equal(result, ISC_R_SUCCESS);
+
+ result = cfg_parse_buffer(p1, &buf1, "text1", 0,
+ &cfg_type_namedconf, 0, &c1);
+ assert_int_equal(result, ISC_R_SUCCESS);
+
+ (void)cfg_map_get(c1, "dnssec-policy", &kasps);
+ assert_non_null(kasps);
+ for (element = cfg_list_first(kasps);
+ element != NULL;
+ element = cfg_list_next(element))
+ {
+ const cfg_obj_t *d1 = NULL;
+ const cfg_obj_t *kopts = NULL;
+ cfg_obj_t *kconf = cfg_listelt_value(element);
+ assert_non_null(kconf);
+
+ kopts = cfg_tuple_get(kconf, "options");
+ result = cfg_map_get(kopts, "signatures-refresh", &d1);
+ assert_int_equal(result, ISC_R_SUCCESS);
+
+ assert_int_equal(durations[i].time,
+ cfg_obj_asduration(d1));
+ }
+
+ cfg_obj_destroy(p1, &c1);
+ cfg_parser_destroy(&p1);
+ }
+
+ cleanup();
+}
+
+int
+main(void) {
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(cfg_obj_asduration_test),
+ };
+
+ return (cmocka_run_group_tests(tests, NULL, NULL));
+}
+
+#else /* HAVE_CMOCKA */
+
+#include <stdio.h>
+
+int
+main(void) {
+ printf("1..0 # Skipped: cmocka not available\n");
+ return (0);
+}
+
+#endif
cfg_map_getname
cfg_map_nextclause
cfg_obj_asboolean
+cfg_obj_asduration
cfg_obj_asfixedpoint
cfg_obj_asnetprefix
cfg_obj_aspercentage
cfg_obj_file
cfg_obj_getdscp
cfg_obj_isboolean
+cfg_obj_isduration
cfg_obj_isfixedpoint
cfg_obj_islist
cfg_obj_ismap
cfg_parse_bracketed_list
cfg_parse_buffer
cfg_parse_dscp
+cfg_parse_duration
cfg_parse_enum
cfg_parse_enum_or_other
cfg_parse_file
cfg_print_chars
cfg_print_clauseflags
cfg_print_cstr
+cfg_print_duration
cfg_print_fixedpoint
cfg_print_grammar
cfg_print_indent
; Exported Data
;cfg_rep_boolean
+;cfg_rep_duration
;cfg_rep_fixedpoint
;cfg_rep_list
;cfg_rep_map
./lib/isccfg/namedconf.c C 2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019
./lib/isccfg/parser.c C 2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019
./lib/isccfg/tests/Kyuafile X 2017,2018,2019
+./lib/isccfg/tests/duration_test.c C 2019
./lib/isccfg/tests/parser_test.c C 2016,2018,2019
./lib/isccfg/version.c C 1998,1999,2000,2001,2004,2005,2007,2016,2018,2019
./lib/isccfg/win32/DLLMain.c C 2001,2004,2007,2016,2018,2019