diff --git a/.gitignore b/.gitignore index c6a75824dc1f0213aa1997455218819519512747..b511cc5d57b650832e1c48497ce064f4041b3240 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,8 @@ version.h # Vagrant .vagrant + +# eclipse +/.project +/.cproject +/.settings/ \ No newline at end of file diff --git a/NEWS b/NEWS index 5db4e419d99481af5afa0afc4949e47a82ca82fe..aebb7be810b347cf97bfe88ba5d498dbc52d7909 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +Knot DNS 2.7.0 (2018-xx-xx) +=========================== + +Features: +--------- + - New zone serial policy DATESERIAL: yyyyMMDDvv (Thanks to Wolfgang Jung) + + Knot DNS 2.6.0 (2017-09-29) =========================== diff --git a/doc/man/knot.conf.5in b/doc/man/knot.conf.5in index 5003cc4ac57c9514dd7a94de0850f6cf74712cc4..70fe7054742f4ec354438f61a86ed20c3f824ae1 100644 --- a/doc/man/knot.conf.5in +++ b/doc/man/knot.conf.5in @@ -983,7 +983,7 @@ zone: dnssec\-signing: BOOL dnssec\-policy: STR request\-edns\-option: INT:[HEXSTR] - serial\-policy: increment | unixtime + serial\-policy: increment | unixtime | dateserial min\-refresh\-interval: TIME max\-refresh\-interval: TIME module: STR/STR ... @@ -1219,6 +1219,12 @@ Possible values: \fBincrement\fP – The serial is incremented according to serial number arithmetic .IP \(bu 2 \fBunixtime\fP – The serial is set to the current unix time +.IP \(bu 2 +.INDENT 2.0 +.TP +\fBdateserial\fP – The 10\-digit serial (YYYYMMDDnn) is incremented, the first +8 digits match the current iso\-date +.UNINDENT .UNINDENT .sp \fBNOTE:\fP @@ -1228,6 +1234,8 @@ If your serial was in other than unix time format, be careful with the transition to unix time. It may happen that the new serial will be \(aqlower\(aq than the old one. If this is the case, the transition should be done by hand (\fI\%RFC 1982\fP). +.sp +Use dateserial only if you expect less than 100 updates per day per zone. .UNINDENT .UNINDENT .sp diff --git a/doc/reference.rst b/doc/reference.rst index 1a4980c3da58a0b202172f2912728993d6e96b2f..590869c038289a96d7c45a96983406d95e233233 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -1110,7 +1110,7 @@ Definition of zones served by the server. dnssec-signing: BOOL dnssec-policy: STR request-edns-option: INT:[HEXSTR] - serial-policy: increment | unixtime + serial-policy: increment | unixtime | dateserial min-refresh-interval: TIME max-refresh-interval: TIME module: STR/STR ... @@ -1382,6 +1382,8 @@ Possible values: - ``increment`` – The serial is incremented according to serial number arithmetic - ``unixtime`` – The serial is set to the current unix time +- ``dateserial`` – The 10-digit serial (YYYYMMDDnn) is incremented, the first + 8 digits match the current iso-date .. NOTE:: If your serial was in other than unix time format, be careful @@ -1389,6 +1391,8 @@ Possible values: be \'lower\' than the old one. If this is the case, the transition should be done by hand (:rfc:`1982`). + Use dateserial only if you expect less than 100 updates per day per zone. + *Default:* increment .. _zone_min-refresh-interval: diff --git a/src/knot/conf/schema.c b/src/knot/conf/schema.c index 971856885aa2d77d56678bf4a902e8bc8b641e60..6f5a8f00c7488d73fe93691d845eaece5ded61c1 100644 --- a/src/knot/conf/schema.c +++ b/src/knot/conf/schema.c @@ -87,8 +87,9 @@ const knot_lookup_t acl_actions[] = { }; static const knot_lookup_t serial_policies[] = { - { SERIAL_POLICY_INCREMENT, "increment" }, - { SERIAL_POLICY_UNIXTIME, "unixtime" }, + { SERIAL_POLICY_INCREMENT, "increment" }, + { SERIAL_POLICY_UNIXTIME, "unixtime" }, + { SERIAL_POLICY_DATESERIAL, "dateserial" }, { 0, NULL } }; diff --git a/src/knot/conf/schema.h b/src/knot/conf/schema.h index d0a08d05a04904dee259ae1191c6ef346f1be6ac..3c14c6c4d33cabf44b4435b821f13ed538408ee3 100644 --- a/src/knot/conf/schema.h +++ b/src/knot/conf/schema.h @@ -129,8 +129,9 @@ enum { }; enum { - SERIAL_POLICY_INCREMENT = 1, - SERIAL_POLICY_UNIXTIME = 2, + SERIAL_POLICY_INCREMENT = 1, + SERIAL_POLICY_UNIXTIME = 2, + SERIAL_POLICY_DATESERIAL = 3, }; enum { diff --git a/src/knot/zone/serial.c b/src/knot/zone/serial.c index 569877b03b0684342a739752cdec551492eecb31..2c1b928d404a7e02d3d5c7d213095cb09dc26da4 100644 --- a/src/knot/zone/serial.c +++ b/src/knot/zone/serial.c @@ -35,6 +35,28 @@ serial_cmp_result_t serial_compare(uint32_t s1, uint32_t s2) return diffbrief2result[diffbrief]; } +static uint32_t serial_next_date(uint32_t current) +{ + uint32_t next = current + 1; + + struct tm now; + time_t current_time = time(NULL); + struct tm *gmtime_result = gmtime_r(¤t_time, &now); + if (gmtime_result == NULL) { + return next; + } + + uint32_t yyyyMMdd00 = (1900 + now.tm_year) * 1000000 + + ( 1 + now.tm_mon ) * 10000 + + ( now.tm_mday) * 100; + + if (next < yyyyMMdd00) { + next = yyyyMMdd00; + } + + return next; +} + uint32_t serial_next(uint32_t current, int policy) { switch (policy) { @@ -42,6 +64,8 @@ uint32_t serial_next(uint32_t current, int policy) return current + 1; case SERIAL_POLICY_UNIXTIME: return time(NULL); + case SERIAL_POLICY_DATESERIAL: + return serial_next_date(current); default: assert(0); return 0; diff --git a/src/knot/zone/serial.h b/src/knot/zone/serial.h index fd3f4c4a9a43bff953d97c02fb8de39683b1e439..3453de80adc11b1bb6eefd779b4daa321d107f49 100644 --- a/src/knot/zone/serial.h +++ b/src/knot/zone/serial.h @@ -47,7 +47,8 @@ inline static bool serial_equal(uint32_t a, uint32_t b) * \brief Get next serial for given serial update policy. * * \param current Current SOA serial. - * \param policy SERIAL_POLICY_INCREMENT or SERIAL_POLICY_UNIXTIME. + * \param policy SERIAL_POLICY_INCREMENT, SERIAL_POLICY_UNIXTIME or + * SERIAL_POLICY_DATESERIAL. * * \return New serial. */ diff --git a/tests/knot/test_zone_serial.c b/tests/knot/test_zone_serial.c index 20a0739d5f391b5d998ccc367ebeb823f58481cb..a3ce31d8d51b9f8cfb39824cd30c4538f8209d5f 100644 --- a/tests/knot/test_zone_serial.c +++ b/tests/knot/test_zone_serial.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -14,10 +14,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <assert.h> #include <tap/basic.h> #include <stdlib.h> +#include <time.h> #include "knot/zone/serial.h" +#include "knot/conf/schema.h" +#include "contrib/strtonum.h" enum serials { S_LOWEST = 0, // lowest value @@ -38,9 +42,36 @@ static uint32_t random_serial(void) return s; } +static void check_dateserial(uint32_t current, uint32_t expected, const char *msg) +{ + uint32_t next = serial_next(current, SERIAL_POLICY_DATESERIAL); + ok(next == expected, "dateserial: %s", msg); +} + +static void test_dateserial(void) +{ + time_t now = time(NULL); + + struct tm *gm_ret = gmtime(&now); + assert(gm_ret); + + char str[32]; + int ret = strftime(str, sizeof(str), "%Y%m%d00", gm_ret); + assert(ret > 0); + + uint32_t serial0; + ret = str_to_u32(str, &serial0); + assert(ret == KNOT_EOK); + + check_dateserial(2000010100, serial0, "from old date"); + check_dateserial(serial0, serial0 + 1, "today's first increment"); + check_dateserial(serial0 + 98, serial0 + 99, "today's last increment"); + check_dateserial(2100010100, 2100010101, "from future date"); +} + int main(int argc, char *argv[]) { - plan(20); + plan_lazy(); /* Serial compare test. */ ok(serial_compare(S_LOWEST, S_BELOW_MIDDLE) == SERIAL_LOWER, @@ -98,5 +129,7 @@ int main(int argc, char *argv[]) ok(serial_compare(s2, s1) == SERIAL_INCOMPARABLE, "serial compare: random opposites (s2 < s1)"); + test_dateserial(); + return 0; }