]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/serialtweaker.cc
auth 4.1 build: Switch to devtoolset 7 for el6
[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-INCREMENT")) {
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
71 if(src->d_st.serial < inception_serial - 1) { /* less than <inceptionday>00 */
72 return inception_serial; /* return <inceptionday>01 (skipping <inceptionday>00 as possible value) */
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 */
75 }
76 }
77 else if(pdns_iequals(kind,"INCREMENT-WEEKS")) {
78 time_t inception = getStartOfWeek();
79 return (src->d_st.serial + (inception / (7*86400)));
80 }
81 else if(pdns_iequals(kind,"EPOCH")) {
82 return time(0);
83 }
84 else if(pdns_iequals(kind,"INCEPTION-EPOCH")) {
85 uint32_t inception = getStartOfWeek();
86 if (src->d_st.serial < inception)
87 return inception;
88 } else if(!kind.empty()) {
89 L<<Logger::Warning<<"SOA-EDIT type '"<<kind<<"' for zone "<<rr.dr.d_name<<" is unknown."<<endl;
90 }
91 return src->d_st.serial;
92 }
93
94 uint32_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);
102 }
103
104 // Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
105 uint32_t calculateIncreaseSOA(DNSZoneRecord& dzr, const string& increaseKind, const string& editKind) {
106 auto src = getRR<SOARecordContent>(dzr.dr);
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")) {
110 uint32_t new_serial = calculateEditSOA(dzr, editKind);
111 if (new_serial <= src->d_st.serial) {
112 new_serial = src->d_st.serial + 1;
113 }
114 return new_serial;
115 }
116 else if (pdns_iequals(increaseKind, "SOA-EDIT")) {
117 return calculateEditSOA(dzr, editKind);
118 }
119 }
120
121 if (pdns_iequals(increaseKind, "INCREASE")) {
122 return src->d_st.serial + 1;
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();
134 uint32_t new_serial = pdns_stou(newdate);
135 if (new_serial <= src->d_st.serial) {
136 new_serial = src->d_st.serial + 1;
137 }
138 return new_serial;
139 }
140
141 // Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API.
142 uint32_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
153 bool 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 }