1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
/*
* This file is part of PowerDNS or dnsdist.
* Copyright -- PowerDNS.COM B.V. and its contributors
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* In addition, for the avoidance of any doubt, permission is granted to
* link this program with OpenSSL and to (re)distribute the binaries
* produced as the result of such linking.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef UEBERBACKEND_HH
#define UEBERBACKEND_HH
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <boost/utility.hpp>
#include "dnspacket.hh"
#include "dnsbackend.hh"
#include "namespaces.hh"
/** This is a very magic backend that allows us to load modules dynamically,
and query them in order. This is persistent over all UeberBackend instantiations
across multiple threads.
The UeberBackend is transparent for exceptions, which should fall straight through.
*/
class UeberBackend : public boost::noncopyable
{
public:
UeberBackend(const string &pname="default");
~UeberBackend();
bool superMasterBackend(const string &ip, const DNSName &domain, const vector<DNSResourceRecord>&nsset, string *nameserver, string *account, DNSBackend **db);
/** Tracks all created UeberBackend instances for us. We use this vector to notify
existing threads of new modules
*/
static vector<UeberBackend *>instances;
static pthread_mutex_t instances_lock;
static bool loadmodule(const string &name);
static void go(void);
/** This contains all registered backends. The DynListener modifies this list for us when
new modules are loaded */
vector<DNSBackend*> backends;
void cleanup();
//! the very magic handle for UeberBackend questions
class handle
{
public:
bool get(DNSZoneRecord &dr);
handle();
~handle();
//! The UeberBackend class where this handle belongs to
UeberBackend *parent;
//! The current real backend, which is answering questions
DNSBackend *d_hinterBackend;
//! DNSPacket who asked this question
DNSPacket *pkt_p;
DNSName qname;
//! Index of the current backend within the backends vector
unsigned int i;
QType qtype;
private:
static AtomicCounter instances;
};
void lookup(const QType &, const DNSName &qdomain, DNSPacket *pkt_p=0, int zoneId=-1);
/** Determines if we are authoritative for a zone, and at what level */
bool getAuth(const DNSName &target, const QType &qtype, SOAData* sd, bool cachedOk=true);
bool getSOA(const DNSName &domain, SOAData &sd);
bool getSOAUncached(const DNSName &domain, SOAData &sd); // same, but ignores cache
bool get(DNSZoneRecord &r);
void getAllDomains(vector<DomainInfo> *domains, bool include_disabled=false);
void getUnfreshSlaveInfos(vector<DomainInfo>* domains);
void getUpdatedMasters(vector<DomainInfo>* domains);
bool getDomainInfo(const DNSName &domain, DomainInfo &di);
bool createDomain(const DNSName &domain);
bool doesDNSSEC();
bool addDomainKey(const DNSName& name, const DNSBackend::KeyData& key, int64_t& id);
bool getDomainKeys(const DNSName& name, std::vector<DNSBackend::KeyData>& keys);
bool getAllDomainMetadata(const DNSName& name, std::map<std::string, std::vector<std::string> >& meta);
bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector<std::string>& meta);
bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector<std::string>& meta);
bool removeDomainKey(const DNSName& name, unsigned int id);
bool activateDomainKey(const DNSName& name, unsigned int id);
bool deactivateDomainKey(const DNSName& name, unsigned int id);
bool getTSIGKey(const DNSName& name, DNSName* algorithm, string* content);
bool setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content);
bool deleteTSIGKey(const DNSName& name);
bool getTSIGKeys(std::vector< struct TSIGKey > &keys);
void alsoNotifies(const DNSName &domain, set<string> *ips);
void rediscover(string* status=0);
void reload();
bool searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result);
bool searchComments(const string &pattern, int maxResults, vector<Comment>& result);
private:
pthread_t d_tid;
handle d_handle;
vector<DNSZoneRecord> d_answers;
vector<DNSZoneRecord>::const_iterator d_cachehandleiter;
static pthread_mutex_t d_mut;
static pthread_cond_t d_cond;
struct Question
{
DNSName qname;
int zoneId;
QType qtype;
}d_question;
unsigned int d_cache_ttl, d_negcache_ttl;
int d_domain_id;
int d_ancount;
bool d_negcached;
bool d_cached;
static bool d_go;
bool d_stale;
int cacheHas(const Question &q, vector<DNSZoneRecord> &rrs);
void addNegCache(const Question &q);
void addCache(const Question &q, const vector<DNSZoneRecord> &rrs);
};
#endif
|