]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/serialtweaker.cc
auth 4.1 build: Switch to devtoolset 7 for el6
[thirdparty/pdns.git] / pdns / serialtweaker.cc
CommitLineData
92c90b44
BH
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
6ca3fa73 6 it under the terms of the GNU General Public License version 2 as
92c90b44
BH
7 published by the Free Software Foundation
8
f782fe38
MH
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
92c90b44
BH
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
870a0fe4
AT
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
92c90b44
BH
26#include "dnsseckeeper.hh"
27#include "dnspacket.hh"
28#include "namespaces.hh"
fa8fd4d2 29
92c90b44 30
63347c6c 31uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq)
6ca3fa73
SB
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
7abbc40f 42bool editSOA(DNSSECKeeper& dk, const DNSName& qname, DNSPacket* dp)
92c90b44 43{
90ba52e0 44 for(auto& rr : dp->getRRS()) {
45 if(rr.dr.d_type == QType::SOA && rr.dr.d_name == qname) {
92c90b44 46 string kind;
4192773a 47 dk.getSoaEdit(qname, kind);
aaf95c8a 48 return editSOARecord(rr, kind);
92c90b44
BH
49 }
50 }
51 return false;
52}
5ba9719b 53
aaf95c8a 54bool editSOARecord(DNSZoneRecord& rr, const string& kind) {
d29d5db7
CH
55 if(kind.empty())
56 return false;
90ba52e0 57 auto src = getRR<SOARecordContent>(rr.dr);
58 src->d_st.serial=calculateEditSOA(rr, kind);
d29d5db7 59
d29d5db7
CH
60 return true;
61}
5ba9719b 62
90ba52e0 63uint32_t calculateEditSOA(const DNSZoneRecord& rr, const string& kind)
64{
65 auto src = getRR<SOARecordContent>(rr.dr);
f81291fd 66 if(pdns_iequals(kind,"INCEPTION-INCREMENT")) {
5ba9719b
RA
67 time_t inception = getStartOfWeek();
68 uint32_t inception_serial = localtime_format_YYYYMMDDSS(inception, 1);
69 uint32_t dont_increment_after = localtime_format_YYYYMMDDSS(inception + 2*86400, 99);
70
90ba52e0 71 if(src->d_st.serial < inception_serial - 1) { /* less than <inceptionday>00 */
83609e21 72 return inception_serial; /* return <inceptionday>01 (skipping <inceptionday>00 as possible value) */
90ba52e0 73 } else if(src->d_st.serial <= dont_increment_after) { /* >= <inceptionday>00 but <= <inceptionday+2>99 */
74 return (src->d_st.serial + 2); /* "<inceptionday>00" and "<inceptionday>01" are reserved for inception increasing, so increment sd.serial by two */
83609e21 75 }
5ba9719b 76 }
5ba9719b
RA
77 else if(pdns_iequals(kind,"INCREMENT-WEEKS")) {
78 time_t inception = getStartOfWeek();
90ba52e0 79 return (src->d_st.serial + (inception / (7*86400)));
5ba9719b
RA
80 }
81 else if(pdns_iequals(kind,"EPOCH")) {
82 return time(0);
83 }
84 else if(pdns_iequals(kind,"INCEPTION-EPOCH")) {
eee11292 85 uint32_t inception = getStartOfWeek();
90ba52e0 86 if (src->d_st.serial < inception)
5ba9719b 87 return inception;
5e95e601 88 } else if(!kind.empty()) {
90ba52e0 89 L<<Logger::Warning<<"SOA-EDIT type '"<<kind<<"' for zone "<<rr.dr.d_name<<" is unknown."<<endl;
5ba9719b 90 }
90ba52e0 91 return src->d_st.serial;
92}
93
94uint32_t calculateEditSOA(const SOAData& sd, const string& kind)
95{
96 DNSZoneRecord dzr;
97 dzr.dr.d_name=sd.qname;
98 struct soatimes st;
99 st.serial = sd.serial;
100 dzr.dr.d_content = std::make_shared<SOARecordContent>(sd.nameserver, sd.hostmaster, st);
101 return calculateEditSOA(dzr, kind);
5ba9719b 102}
a6448d95
CH
103
104// Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
90ba52e0 105uint32_t calculateIncreaseSOA(DNSZoneRecord& dzr, const string& increaseKind, const string& editKind) {
106 auto src = getRR<SOARecordContent>(dzr.dr);
a6448d95
CH
107 // These only work when SOA-EDIT is set, otherwise fall back to default.
108 if (!editKind.empty()) {
109 if (pdns_iequals(increaseKind, "SOA-EDIT-INCREASE")) {
90ba52e0 110 uint32_t new_serial = calculateEditSOA(dzr, editKind);
111 if (new_serial <= src->d_st.serial) {
112 new_serial = src->d_st.serial + 1;
a6448d95
CH
113 }
114 return new_serial;
115 }
116 else if (pdns_iequals(increaseKind, "SOA-EDIT")) {
90ba52e0 117 return calculateEditSOA(dzr, editKind);
a6448d95
CH
118 }
119 }
120
121 if (pdns_iequals(increaseKind, "INCREASE")) {
90ba52e0 122 return src->d_st.serial + 1;
a6448d95
CH
123 }
124 else if (pdns_iequals(increaseKind, "EPOCH")) {
125 return time(0);
126 }
127
128 // DEFAULT case
129 time_t now = time(0);
130 struct tm tm;
131 localtime_r(&now, &tm);
132 boost::format fmt("%04d%02d%02d%02d");
133 string newdate = (fmt % (tm.tm_year + 1900) % (tm.tm_mon + 1) % tm.tm_mday % 1).str();
335da0ba 134 uint32_t new_serial = pdns_stou(newdate);
90ba52e0 135 if (new_serial <= src->d_st.serial) {
136 new_serial = src->d_st.serial + 1;
a6448d95
CH
137 }
138 return new_serial;
139}
140
90ba52e0 141// Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
142uint32_t calculateIncreaseSOA(SOAData sd, const string& increaseKind, const string& editKind) {
143 DNSZoneRecord dzr;
144 dzr.dr.d_name=sd.qname;
145 struct soatimes st;
146 st.serial = sd.serial;
147 dzr.dr.d_content = std::make_shared<SOARecordContent>(sd.nameserver, sd.hostmaster, st);
148 return calculateIncreaseSOA(dzr, increaseKind, editKind);
149}
150
151
152
a6448d95
CH
153bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind) {
154 if (increaseKind.empty())
155 return false;
156
157 SOAData sd;
158 fillSOAData(rr.content, sd);
159 sd.serial = calculateIncreaseSOA(sd, increaseKind, editKind);
160 rr.content = serializeSOAData(sd);
161 return true;
162}