]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/serialtweaker.cc
Merge pull request #6422 from rgacogne/dnsdist-doc-fixes
[thirdparty/pdns.git] / pdns / serialtweaker.cc
1 /*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002-2011 PowerDNS.COM BV
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation
8
9 Additionally, the license of this program contains a special
10 exception which allows to distribute the program in binary form when
11 it is linked against OpenSSL.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 #include "dnsseckeeper.hh"
27 #include "dnspacket.hh"
28 #include "namespaces.hh"
29
30 uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq)
31 {
32 struct tm tm;
33 localtime_r(&t, &tm);
34 return
35 (uint32_t)(tm.tm_year+1900) * 1000000u
36 + (uint32_t)(tm.tm_mon + 1) * 10000u
37 + (uint32_t)tm.tm_mday * 100u
38 + seq;
39 }
40
41 uint32_t calculateEditSOA(uint32_t old_serial, const string& kind, const DNSName& zonename)
42 {
43 if(pdns_iequals(kind,"INCEPTION-INCREMENT")) {
44 time_t inception = getStartOfWeek();
45 uint32_t inception_serial = localtime_format_YYYYMMDDSS(inception, 1);
46 uint32_t dont_increment_after = localtime_format_YYYYMMDDSS(inception + 2*86400, 99);
47
48 if(old_serial < inception_serial - 1) { /* less than <inceptionday>00 */
49 return inception_serial; /* return <inceptionday>01 (skipping <inceptionday>00 as possible value) */
50 } else if (old_serial < inception_serial+1) {
51 /* "<inceptionday>00" and "<inceptionday>01" are reserved for inception increasing, so jump to "<inceptionday>02" */
52 return inception_serial+1;
53 } else if(old_serial <= dont_increment_after) { /* >= <inceptionday>00 but <= <inceptionday+2>99 */
54 return old_serial + 1;
55 }
56 }
57 else if(pdns_iequals(kind,"INCREMENT-WEEKS")) {
58 time_t inception = getStartOfWeek();
59 return (old_serial + (inception / (7*86400)));
60 }
61 else if(pdns_iequals(kind,"EPOCH")) {
62 return time(0);
63 }
64 else if(pdns_iequals(kind,"INCEPTION-EPOCH")) {
65 uint32_t inception = getStartOfWeek();
66 if (old_serial < inception)
67 return inception;
68 } else if(!kind.empty()) {
69 g_log<<Logger::Warning<<"SOA-EDIT type '"<<kind<<"' for zone "<<zonename<<" is unknown."<<endl;
70 }
71 return old_serial;
72 }
73
74 uint32_t calculateEditSOA(uint32_t old_serial, DNSSECKeeper& dk, const DNSName& zonename) {
75 string kind;
76 dk.getSoaEdit(zonename, kind);
77 if(kind.empty())
78 return old_serial;
79 return calculateEditSOA(old_serial, kind, zonename);
80 }
81
82 /** Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API. */
83 static uint32_t calculateIncreaseSOA(uint32_t old_serial, const string& increaseKind, const string& editKind, const DNSName& zonename) {
84 if (pdns_iequals(increaseKind, "SOA-EDIT-INCREASE")) {
85 uint32_t new_serial = old_serial;
86 if (!editKind.empty()) {
87 new_serial = calculateEditSOA(old_serial, editKind, zonename);
88 }
89 if (new_serial <= old_serial) {
90 new_serial = old_serial + 1;
91 }
92 return new_serial;
93 }
94 else if (pdns_iequals(increaseKind, "SOA-EDIT")) {
95 return calculateEditSOA(old_serial, editKind, zonename);
96 }
97 else if (pdns_iequals(increaseKind, "INCREASE")) {
98 return old_serial + 1;
99 }
100 else if (pdns_iequals(increaseKind, "EPOCH")) {
101 return time(0);
102 }
103 else if (pdns_iequals(increaseKind, "DEFAULT")) {
104 time_t now = time(0);
105 uint32_t new_serial = localtime_format_YYYYMMDDSS(now, 1);
106 if (new_serial <= old_serial) {
107 new_serial = old_serial + 1;
108 }
109 return new_serial;
110 } else if(!increaseKind.empty()) {
111 g_log<<Logger::Warning<<"SOA-EDIT-API/DNSUPDATE type '"<<increaseKind<<"' for zone "<<zonename<<" is unknown."<<endl;
112 }
113 return old_serial;
114 }
115
116 /** Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
117 * Good if you already *have* a DNSResourceRecord.
118 * Content in rr is suitable for writing into a backend.
119 *
120 * @return true if changes may have been made
121 */
122 bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind) {
123 if (increaseKind.empty())
124 return false;
125
126 SOAData sd;
127 fillSOAData(rr.content, sd);
128
129 sd.serial = calculateIncreaseSOA(sd.serial, increaseKind, editKind, rr.qname);
130 rr.content = makeSOAContent(sd)->getZoneRepresentation(true);
131 return true;
132 }
133
134 /** Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
135 * Makes a mostly reset DNSResourceRecord for you in @param rrout.
136 * Content in rrout is suitable for writing into a backend.
137 *
138 * @return true if rrout is now valid
139 */
140 bool makeIncreasedSOARecord(SOAData& sd, const string& increaseKind, const string& editKind, DNSResourceRecord& rrout) {
141 if (increaseKind.empty())
142 return false;
143
144 sd.serial = calculateIncreaseSOA(sd.serial, increaseKind, editKind, sd.qname);
145 rrout.qname = sd.qname;
146 rrout.content = makeSOAContent(sd)->getZoneRepresentation(true);
147 rrout.qtype = QType::SOA;
148 rrout.domain_id = sd.domain_id;
149 rrout.auth = 1;
150 rrout.ttl = sd.ttl;
151
152 return true;
153 }