]>
Commit | Line | Data |
---|---|---|
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 | |
63347c6c | 30 | uint32_t localtime_format_YYYYMMDDSS(time_t t, uint32_t seq) |
6ca3fa73 SB |
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 | ||
13f9e280 | 41 | uint32_t calculateEditSOA(uint32_t old_serial, const string& kind, const DNSName& zonename) |
92c90b44 | 42 | { |
f81291fd | 43 | if(pdns_iequals(kind,"INCEPTION-INCREMENT")) { |
5ba9719b RA |
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 | ||
13f9e280 | 48 | if(old_serial < inception_serial - 1) { /* less than <inceptionday>00 */ |
83609e21 | 49 | return inception_serial; /* return <inceptionday>01 (skipping <inceptionday>00 as possible value) */ |
13f9e280 CH |
50 | } else if(old_serial <= dont_increment_after) { /* >= <inceptionday>00 but <= <inceptionday+2>99 */ |
51 | return (old_serial + 2); /* "<inceptionday>00" and "<inceptionday>01" are reserved for inception increasing, so increment sd.serial by two */ | |
83609e21 | 52 | } |
5ba9719b | 53 | } |
5ba9719b RA |
54 | else if(pdns_iequals(kind,"INCREMENT-WEEKS")) { |
55 | time_t inception = getStartOfWeek(); | |
13f9e280 | 56 | return (old_serial + (inception / (7*86400))); |
5ba9719b RA |
57 | } |
58 | else if(pdns_iequals(kind,"EPOCH")) { | |
59 | return time(0); | |
60 | } | |
61 | else if(pdns_iequals(kind,"INCEPTION-EPOCH")) { | |
eee11292 | 62 | uint32_t inception = getStartOfWeek(); |
13f9e280 | 63 | if (old_serial < inception) |
5ba9719b | 64 | return inception; |
5e95e601 | 65 | } else if(!kind.empty()) { |
13f9e280 | 66 | L<<Logger::Warning<<"SOA-EDIT type '"<<kind<<"' for zone "<<zonename<<" is unknown."<<endl; |
5ba9719b | 67 | } |
13f9e280 | 68 | return old_serial; |
90ba52e0 | 69 | } |
70 | ||
13f9e280 CH |
71 | uint32_t calculateEditSOA(uint32_t old_serial, DNSSECKeeper& dk, const DNSName& zonename) { |
72 | string kind; | |
73 | dk.getSoaEdit(zonename, kind); | |
74 | if(kind.empty()) | |
75 | return old_serial; | |
76 | return calculateEditSOA(old_serial, kind, zonename); | |
5ba9719b | 77 | } |
a6448d95 | 78 | |
13f9e280 CH |
79 | /** Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API. */ |
80 | static uint32_t calculateIncreaseSOA(uint32_t old_serial, const string& increaseKind, const string& editKind, const DNSName& zonename) { | |
636301b9 CH |
81 | if (pdns_iequals(increaseKind, "SOA-EDIT-INCREASE")) { |
82 | uint32_t new_serial = old_serial; | |
83 | if (!editKind.empty()) { | |
84 | new_serial = calculateEditSOA(old_serial, editKind, zonename); | |
a6448d95 | 85 | } |
636301b9 CH |
86 | if (new_serial <= old_serial) { |
87 | new_serial = old_serial + 1; | |
a6448d95 | 88 | } |
636301b9 | 89 | return new_serial; |
a6448d95 | 90 | } |
636301b9 CH |
91 | else if (pdns_iequals(increaseKind, "SOA-EDIT")) { |
92 | return calculateEditSOA(old_serial, editKind, zonename); | |
93 | } | |
94 | else if (pdns_iequals(increaseKind, "INCREASE")) { | |
13f9e280 | 95 | return old_serial + 1; |
a6448d95 CH |
96 | } |
97 | else if (pdns_iequals(increaseKind, "EPOCH")) { | |
98 | return time(0); | |
99 | } | |
636301b9 CH |
100 | else if (pdns_iequals(increaseKind, "DEFAULT")) { |
101 | time_t now = time(0); | |
102 | uint32_t new_serial = localtime_format_YYYYMMDDSS(now, 1); | |
103 | if (new_serial <= old_serial) { | |
104 | new_serial = old_serial + 1; | |
105 | } | |
106 | return new_serial; | |
107 | } else if(!increaseKind.empty()) { | |
108 | L<<Logger::Warning<<"SOA-EDIT-API/DNSUPDATE type '"<<increaseKind<<"' for zone "<<zonename<<" is unknown."<<endl; | |
a6448d95 | 109 | } |
636301b9 | 110 | return old_serial; |
a6448d95 CH |
111 | } |
112 | ||
13f9e280 CH |
113 | /** Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API. |
114 | * Good if you already *have* a DNSResourceRecord. | |
115 | * Content in rr is suitable for writing into a backend. | |
116 | * | |
117 | * @return true if changes may have been made | |
118 | */ | |
a6448d95 CH |
119 | bool increaseSOARecord(DNSResourceRecord& rr, const string& increaseKind, const string& editKind) { |
120 | if (increaseKind.empty()) | |
121 | return false; | |
122 | ||
123 | SOAData sd; | |
124 | fillSOAData(rr.content, sd); | |
13f9e280 CH |
125 | |
126 | sd.serial = calculateIncreaseSOA(sd.serial, increaseKind, editKind, rr.qname); | |
127 | rr.content = makeSOAContent(sd)->getZoneRepresentation(true); | |
128 | return true; | |
129 | } | |
130 | ||
131 | /** Used for SOA-EDIT-DNSUPDATE and SOA-EDIT-API. | |
132 | * Makes a mostly reset DNSResourceRecord for you in @param rrout. | |
133 | * Content in rrout is suitable for writing into a backend. | |
134 | * | |
135 | * @return true if rrout is now valid | |
136 | */ | |
137 | bool makeIncreasedSOARecord(SOAData& sd, const string& increaseKind, const string& editKind, DNSResourceRecord& rrout) { | |
138 | if (increaseKind.empty()) | |
139 | return false; | |
140 | ||
141 | sd.serial = calculateIncreaseSOA(sd.serial, increaseKind, editKind, sd.qname); | |
142 | rrout.qname = sd.qname; | |
143 | rrout.content = makeSOAContent(sd)->getZoneRepresentation(true); | |
144 | rrout.qtype = QType::SOA; | |
145 | rrout.domain_id = sd.domain_id; | |
146 | rrout.auth = 1; | |
147 | rrout.ttl = sd.ttl; | |
148 | ||
a6448d95 CH |
149 | return true; |
150 | } |