Commit b7c5bfb2 authored by Matthijs Mekking's avatar Matthijs Mekking 🏡

Extend ttlval to accept ISO 8601 durations

The ttlval configuration types are replaced by duration configuration
types. The duration is an ISO 8601 duration that is going to be used
for DNSSEC key timings such as key lifetimes, signature resign
intervals and refresh periods, etc. But it is also still allowed to
use the BIND ttlval ways of configuring intervals (number plus
optional unit).

A duration is stored as an array of 7 different time parts.
A duration can either be expressed in weeks, or in a combination of
the other datetime indicators.

Add several unit tests to ensure the correct value is parsed given
different string values.
parent c67379fb
......@@ -421,7 +421,7 @@ configure_zone(const char *vclass, const char *view,
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;
}
......
......@@ -208,7 +208,7 @@ options {
[ 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 );
......@@ -290,18 +290,18 @@ options {
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>; ... };
......@@ -315,28 +315,28 @@ options {
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>;
......@@ -353,8 +353,8 @@ options {
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>;
......@@ -401,13 +401,13 @@ options {
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> ] [
......@@ -421,7 +421,7 @@ options {
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>;
......@@ -432,7 +432,7 @@ options {
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>;
......@@ -564,7 +564,7 @@ view <replaceable>string</replaceable> [ <replaceable>class</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 );
......@@ -642,7 +642,7 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
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
......@@ -655,25 +655,25 @@ view <replaceable>string</replaceable> [ <replaceable>class</replaceable> ] {
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>;
......@@ -689,8 +689,8 @@ view <replaceable>string</replaceable> [ <replaceable>class</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> } ];
......@@ -732,13 +732,13 @@ view <replaceable>string</replaceable> [ <replaceable>class</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> ] [
......@@ -783,14 +783,14 @@ view <replaceable>string</replaceable> [ <replaceable>class</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> | * ) ] [
......@@ -867,7 +867,7 @@ view <replaceable>string</replaceable> [ <replaceable>class</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>;
......@@ -967,7 +967,7 @@ zone <replaceable>string</replaceable> [ <replaceable>class</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>;
......
......@@ -2039,7 +2039,13 @@ conf_dnsrps_num(const cfg_obj_t *obj, const char *name,
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));
}
}
/*
......@@ -2221,15 +2227,15 @@ configure_rpz_zone(dns_view_t *view, const cfg_listelt_t *element,
}
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;
}
......@@ -2448,14 +2454,14 @@ configure_rpz(dns_view_t *view, const cfg_obj_t **maps,
}
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;
......@@ -2992,8 +2998,8 @@ configure_catz_zone(dns_view_t *view, const cfg_obj_t *config,
}
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)
......@@ -3641,7 +3647,7 @@ configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) {
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);
}
......@@ -4217,22 +4223,22 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
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);
......@@ -4242,7 +4248,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
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);
......@@ -4392,7 +4398,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
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.
......@@ -4512,7 +4518,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
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);
......@@ -5216,12 +5222,12 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
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);
......@@ -5464,7 +5470,7 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist,
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);
......@@ -8560,7 +8566,7 @@ load_configuration(const char *filename, named_server_t *server,
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,
......
......@@ -1045,8 +1045,8 @@ named_zone_configure(const cfg_obj_t *config, const cfg_obj_t *vconfig,
} 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);
......
......@@ -51,7 +51,7 @@
<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> ];
......
......@@ -45,7 +45,7 @@
[ 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 );
......@@ -127,18 +127,18 @@
<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>; ... };
......@@ -152,28 +152,28 @@
<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>;
......@@ -190,8 +190,8 @@
<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>;
......@@ -238,13 +238,13 @@
<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> ] [
......@@ -258,7 +258,7 @@
<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>;
......@@ -269,7 +269,7 @@
<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>;
......
......@@ -21,7 +21,7 @@
<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>
......@@ -929,7 +929,11 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
(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)",
......@@ -1176,7 +1180,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
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");
......@@ -1193,7 +1197,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
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");
......@@ -1271,7 +1275,11 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
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)
......
......@@ -27,6 +27,7 @@
#include <inttypes.h>
#include <stdbool.h>
#include <time.h>
#include <isc/formatcheck.h>
#include <isc/lang.h>
......@@ -331,6 +332,24 @@ cfg_obj_aspercentage(const cfg_obj_t *obj);
* \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);
/*%<
......
......@@ -82,6 +82,9 @@ typedef struct cfg_printer cfg_printer_t;
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
......@@ -154,6 +157,24 @@ struct cfg_netprefix {
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.
*/
......@@ -183,6 +204,7 @@ struct cfg_obj {
isc_dscp_t dscp;
} sockaddrdscp;
cfg_netprefix_t netprefix;
cfg_duration_t duration;
} value;
isc_refcount_t references; /*%< reference counter */
const char * file;
......@@ -290,6 +312,7 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix;
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;
/*@}*/
/*@{*/
......@@ -320,6 +343,7 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token;
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
......@@ -504,6 +528,13 @@ cfg_parse_percentage(cfg_parser_t *pctx, const cfg_type_t *type,
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);
......
......@@ -121,7 +121,6 @@ static cfg_type_t cfg_type_sizeval;
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;
......@@ -1054,7 +1053,7 @@ options_clauses[] = {
{ "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 },