]>
Commit | Line | Data |
---|---|---|
12c86877 | 1 | /* |
12471842 PL |
2 | * This file is part of PowerDNS or dnsdist. |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * In addition, for the avoidance of any doubt, permission is granted to | |
10 | * link this program with OpenSSL and to (re)distribute the binaries | |
11 | * produced as the result of such linking. | |
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 Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
e8c59f2d | 22 | #pragma once |
12c86877 BH |
23 | #include <vector> |
24 | #include <map> | |
25 | #include <string> | |
26 | #include <algorithm> | |
0ddde5fb RG |
27 | #include <mutex> |
28 | #include <condition_variable> | |
973ad2b5 | 29 | |
6a010475 | 30 | #include <boost/utility.hpp> |
b51bb9a2 | 31 | |
12c86877 BH |
32 | #include "dnspacket.hh" |
33 | #include "dnsbackend.hh" | |
351cdb4c | 34 | #include "lock.hh" |
10f4eea8 | 35 | #include "namespaces.hh" |
12c86877 | 36 | |
12c86877 BH |
37 | /** This is a very magic backend that allows us to load modules dynamically, |
38 | and query them in order. This is persistent over all UeberBackend instantiations | |
5773d258 | 39 | across multiple threads. |
bdc9f8d2 BH |
40 | |
41 | The UeberBackend is transparent for exceptions, which should fall straight through. | |
42 | */ | |
12c86877 | 43 | |
3971cf53 | 44 | class UeberBackend : public boost::noncopyable |
12c86877 BH |
45 | { |
46 | public: | |
5773d258 | 47 | UeberBackend(const string& pname = "default"); |
12c86877 | 48 | ~UeberBackend(); |
12c86877 | 49 | |
d525b58b | 50 | bool autoPrimaryBackend(const string& ip, const DNSName& domain, const vector<DNSResourceRecord>& nsset, string* nameserver, string* account, DNSBackend** dnsBackend); |
12c86877 | 51 | |
d525b58b | 52 | bool autoPrimaryAdd(const AutoPrimary& primary); |
782e9b24 AT |
53 | bool autoPrimaryRemove(const struct AutoPrimary& primary); |
54 | bool autoPrimariesList(std::vector<AutoPrimary>& primaries); | |
3d26f6dc | 55 | |
12c86877 | 56 | /** Tracks all created UeberBackend instances for us. We use this vector to notify |
5773d258 | 57 | existing threads of new modules |
12c86877 | 58 | */ |
5773d258 | 59 | static LockGuarded<vector<UeberBackend*>> d_instances; |
12c86877 | 60 | |
5773d258 | 61 | static bool loadmodule(const string& name); |
d4168b30 | 62 | static bool loadModules(const vector<string>& modules, const string& path); |
12c86877 | 63 | |
346d1042 | 64 | static void go(); |
12c86877 | 65 | |
12c86877 BH |
66 | /** This contains all registered backends. The DynListener modifies this list for us when |
67 | new modules are loaded */ | |
d2868094 | 68 | vector<std::unique_ptr<DNSBackend>> backends; |
12c86877 BH |
69 | |
70 | //! the very magic handle for UeberBackend questions | |
71 | class handle | |
72 | { | |
73 | public: | |
346d1042 | 74 | bool get(DNSZoneRecord& record); |
12c86877 BH |
75 | handle(); |
76 | ~handle(); | |
77 | ||
78 | //! The UeberBackend class where this handle belongs to | |
346d1042 | 79 | UeberBackend* parent{nullptr}; |
12c86877 | 80 | //! The current real backend, which is answering questions |
346d1042 | 81 | DNSBackend* d_hinterBackend{nullptr}; |
12c86877 | 82 | |
12c86877 | 83 | //! DNSPacket who asked this question |
346d1042 | 84 | DNSPacket* pkt_p{nullptr}; |
675fa24c | 85 | DNSName qname; |
5b098284 PL |
86 | |
87 | //! Index of the current backend within the backends vector | |
346d1042 | 88 | unsigned int i{0}; |
12c86877 | 89 | QType qtype; |
346d1042 | 90 | int zoneId{-1}; |
5b098284 | 91 | |
12c86877 | 92 | private: |
16f7d28d | 93 | static AtomicCounter instances; |
12c86877 BH |
94 | }; |
95 | ||
01f43bae | 96 | void lookup(const QType& qtype, const DNSName& qname, int zoneId, DNSPacket* pkt_p = nullptr); |
12c86877 | 97 | |
cec52de6 | 98 | /** Determines if we are authoritative for a zone, and at what level */ |
212a3555 | 99 | bool getAuth(const DNSName& target, const QType& qtype, SOAData* soaData, bool cachedOk = true); |
76e1255a | 100 | /** Load SOA info from backends, ignoring the cache.*/ |
988be9b3 | 101 | bool getSOAUncached(const DNSName& domain, SOAData& soaData); |
346d1042 | 102 | bool get(DNSZoneRecord& resourceRecord); |
39dafc3b | 103 | void getAllDomains(vector<DomainInfo>* domains, bool getSerial, bool include_disabled); |
12c86877 | 104 | |
c02c999b | 105 | void getUnfreshSecondaryInfos(vector<DomainInfo>* domains); |
d525b58b | 106 | void getUpdatedPrimaries(vector<DomainInfo>& domains, std::unordered_set<DNSName>& catalogs, CatalogHashMap& catalogHashes); |
e255cb4b | 107 | bool getDomainInfo(const DNSName& domain, DomainInfo& domainInfo, bool getSerial = true); |
d525b58b | 108 | bool createDomain(const DNSName& domain, DomainInfo::DomainKind kind, const vector<ComboAddress>& primaries, const string& account); |
5773d258 | 109 | |
7fa35c07 | 110 | bool doesDNSSEC(); |
346d1042 | 111 | bool addDomainKey(const DNSName& name, const DNSBackend::KeyData& key, int64_t& keyID); |
9c1c5d49 | 112 | bool getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys); |
5773d258 | 113 | bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string>>& meta); |
675fa24c | 114 | bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta); |
ddeea7a6 | 115 | bool getDomainMetadata(const DNSName& name, const std::string& kind, std::string& meta); |
675fa24c | 116 | bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta); |
ddeea7a6 | 117 | bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::string& meta); |
675fa24c | 118 | |
346d1042 FM |
119 | bool removeDomainKey(const DNSName& name, unsigned int keyID); |
120 | bool activateDomainKey(const DNSName& name, unsigned int keyID); | |
121 | bool deactivateDomainKey(const DNSName& name, unsigned int keyID); | |
122 | bool publishDomainKey(const DNSName& name, unsigned int keyID); | |
123 | bool unpublishDomainKey(const DNSName& name, unsigned int keyID); | |
675fa24c | 124 | |
5773d258 | 125 | void alsoNotifies(const DNSName& domain, set<string>* ips); |
346d1042 | 126 | void rediscover(string* status = nullptr); |
12c86877 | 127 | void reload(); |
40361bf2 KM |
128 | |
129 | bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content); | |
130 | bool getTSIGKey(const DNSName& name, DNSName& algorithm, string& content); | |
131 | bool getTSIGKeys(std::vector<struct TSIGKey>& keys); | |
132 | bool deleteTSIGKey(const DNSName& name); | |
133 | ||
fd9af6ec FM |
134 | bool searchRecords(const string& pattern, vector<DNSResourceRecord>::size_type maxResults, vector<DNSResourceRecord>& result); |
135 | bool searchComments(const string& pattern, size_t maxResults, vector<Comment>& result); | |
9c56d755 | 136 | |
1f0fb39a | 137 | void updateZoneCache(); |
d5385b35 | 138 | |
9c56d755 | 139 | bool inTransaction(); |
40361bf2 | 140 | |
12c86877 | 141 | private: |
12c86877 | 142 | handle d_handle; |
90ba52e0 | 143 | vector<DNSZoneRecord> d_answers; |
144 | vector<DNSZoneRecord>::const_iterator d_cachehandleiter; | |
c899e9e7 | 145 | |
0ddde5fb RG |
146 | static std::mutex d_mut; |
147 | static std::condition_variable d_cond; | |
c899e9e7 | 148 | |
12c86877 BH |
149 | struct Question |
150 | { | |
675fa24c | 151 | DNSName qname; |
12c86877 | 152 | int zoneId; |
c899e9e7 | 153 | QType qtype; |
5773d258 | 154 | } d_question; |
c899e9e7 PL |
155 | |
156 | unsigned int d_cache_ttl, d_negcache_ttl; | |
346d1042 | 157 | uint16_t d_qtype{0}; |
c899e9e7 | 158 | |
346d1042 FM |
159 | bool d_negcached{false}; |
160 | bool d_cached{false}; | |
d04143d5 | 161 | static AtomicCounter* s_backendQueries; |
c899e9e7 | 162 | static bool d_go; |
346d1042 | 163 | bool d_stale{false}; |
bd8df5bc | 164 | static bool s_doANYLookupsOnly; |
12c86877 | 165 | |
6e9d4b0d FM |
166 | enum CacheResult |
167 | { | |
168 | Miss = -1, | |
169 | NegativeMatch = 0, | |
170 | Hit = 1, | |
171 | }; | |
172 | ||
173 | CacheResult cacheHas(const Question& question, vector<DNSZoneRecord>& resourceRecords) const; | |
346d1042 FM |
174 | void addNegCache(const Question& question) const; |
175 | void addCache(const Question& question, vector<DNSZoneRecord>&& rrs) const; | |
591e66f4 FM |
176 | |
177 | bool fillSOAFromZoneRecord(DNSName& shorter, int zoneId, SOAData* soaData); | |
c6a2025d | 178 | CacheResult fillSOAFromCache(SOAData* soaData, DNSName& shorter); |
12c86877 | 179 | }; |