]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/serialtweaker.cc
Merge pull request #5632 from rgacogne/dnsdist-1.2.0-changelog
[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
31 uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq)
32 {
33 struct tm tm;
34 localtime_r(&t, &tm);
35 return
36 (uint32_t)(tm.tm_year+1900) * 1000000u
37 + (uint32_t)(tm.tm_mon + 1) * 10000u
38 + (uint32_t)tm.tm_mday * 100u
39 + seq;
40 }
41
42 bool editSOA(DNSSECKeeper& dk, const DNSName& qname, DNSPacket* dp)
43 {
44 for(auto& rr : dp->getRRS()) {
45 if(rr.dr.d_type == QType::SOA && rr.dr.d_name == qname) {
46 string kind;
47 dk.getSoaEdit(qname, kind);
48 return editSOARecord(rr, kind);
49 }
50 }
51 return false;
52 }
53
54 bool editSOARecord(DNSZoneRecord& rr, const string& kind) {
55 if(kind.empty())
56 return false;
57 auto src = getRR<SOARecordContent>(rr.dr);
58 src->d_st.serial=calculateEditSOA(rr, kind);
59
60 return true;
61 }
62
63 uint32_t calculateEditSOA(const DNSZoneRecord& rr, const string& kind)
64 {
65 auto src = getRR<SOARecordContent>(rr.dr);
66 if(pdns_iequals(kind,"INCEPTION")) {
67 L<<Logger::Warning<<"Deprecation warning: The 'INCEPTION' soa-edit value will be removed in PowerDNS 4.1"<<endl;
68 time_t inception = getStartOfWeek();
69 return localtime_format_YYYYMMDDSS(inception, 1);
70 }
71 else if(pdns_iequals(kind,"INCEPTION-INCREMENT")) {
72 time_t inception = getStartOfWeek();
73 uint32_t inception_serial = localtime_format_YYYYMMDDSS(inception, 1);
74 uint32_t dont_increment_after = localtime_format_YYYYMMDDSS(inception + 2*86400, 99);
75
76 if(src->d_st.serial < inception_serial - 1) { /* less than <inceptionday>00 */
77 return inception_serial; /* return <inceptionday>01 (skipping <inceptionday>00 as possible value) */
78 } else if(src->d_st.serial <= dont_increment_after) { /* >= <inceptionday>00 but <= <inceptionday+2>99 */
79 return (src->d_st.serial + 2); /* "<inceptionday>00" and "<inceptionday>01" are reserved for inception increasing, so increment sd.serial by two */
80 }
81 }
82 else if(pdns_iequals(kind,"INCEPTION-WEEK")) {
83 L<<Logger::Warning<<"Deprecation warning: The 'INCEPTION-WEEK' soa-edit value will be removed in PowerDNS 4.1"<<endl;
84 time_t inception = getStartOfWeek();
85 return ( inception / (7*86400) );
86 }
87 else if(pdns_iequals(kind,"INCREMENT-WEEKS")) {
88 time_t inception = getStartOfWeek();
89 return (src->d_st.serial + (inception / (7*86400)));
90 }
91 else if(pdns_iequals(kind,"EPOCH")) {
92 L<<Logger::Warning<<"Deprecation warning: The 'EPOCH' soa-edit value will be removed in PowerDNS 4.1"<<endl;
93 return time(0);
94 }
95 else if(pdns_iequals(kind,"INCEPTION-EPOCH")) {
96 uint32_t inception = getStartOfWeek();
97 if (src->d_st.serial < inception)
98 return inception;
99 } else if(!kind.empty()) {
100 L<<Logger::Warning<<"SOA-EDIT type '"<<kind<<"' for zone "<<rr.dr.d_name<<" is unknown."<<endl;
101 }
102 return src->d_st.serial;
103 }
104
105 uint32_t calculateEditSOA(const SOAData& sd, const string& kind)
106 {
107 DNSZoneRecord dzr;
108 dzr.dr.d_name=sd.qname;
109 struct soatimes st;
110 st.serial = sd.serial;
111 dzr.dr.d_content = std::make_shared<SOARecordContent>(sd.nameserver, sd.hostmaster, st);
112 return calculateEditSOA(dzr, kind);
113 }
114
115 // Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
116 uint32_t calculateIncreaseSOA(DNSZoneRecord& dzr, const string& increaseKind, const string& editKind) {
117 auto src = getRR<SOARecordContent>(dzr.dr);
118 // These only work when SOA-EDIT is set, otherwise fall back to default.
119 if (!editKind.empty()) {
120 if (pdns_iequals(increaseKind, "SOA-EDIT-INCREASE")) {
121 uint32_t new_serial = calculateEditSOA(dzr, editKind);
122 if (new_serial <= src->d_st.serial) {
123 new_serial = src->d_st.serial + 1;
124 }
125 return new_serial;
126 }
127 else if (pdns_iequals(increaseKind, "SOA-EDIT")) {
128 return calculateEditSOA(dzr, editKind);
129 }
130 }
131
132 if (pdns_iequals(increaseKind, "INCREASE")) {
133 return src->d_st.serial + 1;
134 }
135 else if (pdns_iequals(increaseKind, "EPOCH")) {
136 return time(0);
137 }
138
139 // DEFAULT case
140 time_t now = time(0);
141 struct tm tm;
142 localtime_r(&now, &tm);
143 boost::format fmt("%04d%02d%02d%02d");
144 string newdate = (fmt % (tm.tm_year + 1900) % (tm.tm_mon + 1) % tm.tm_mday % 1).str();
145 uint32_t new_serial = pdns_stou(newdate);
146 if (new_serial <= src->d_st.serial) {
147 new_serial = src->d_st.serial + 1;
148 }
149 return new_serial;
150 }
151
152 // Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
153 uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const string& editKind) {
154 DNSZoneRecord dzr;
155 dzr.dr.d_name=sd.qname;
156 struct soatimes st;
157 st.serial = sd.serial;
158 dzr.dr.d_content = std::make_shared<SOARecordContent>(sd.nameserver, sd.hostmaster, st);
159 return calculateIncreaseSOA(dzr, increaseKind, editKind);
160 }
161
162
163
164 bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind) {
165 if (increaseKind.empty())
166 return false;
167
168 SOAData sd;
169 fillSOAData(rr.content, sd);
170 sd.serial = calculateIncreaseSOA(sd, increaseKind, editKind);
171 rr.content = serializeSOAData(sd);
172 return true;
173 }