#include <sstream>
#include <boost/algorithm/string.hpp>
#include <system_error>
+#include <unordered_map>
+#include <unordered_set>
#include "pdns/dnsseckeeper.hh"
#include "pdns/dnssecinfra.hh"
di.notified_serial=i->d_lastnotified;
di.backend=this;
di.kind=DomainInfo::Master;
- consider.push_back(di);
+ consider.push_back(std::move(di));
}
}
}
if(di.notified_serial) { // don't do notification storm on startup
di.serial=soadata.serial;
- changedDomains->push_back(di);
+ changedDomains->push_back(std::move(di));
}
}
}
// prevent deadlock by using getSOA() later on
{
ReadLock rl(&s_state_lock);
+ domains->reserve(s_state.size());
for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) {
DomainInfo di;
di.kind=i->d_kind;
di.masters=i->d_masters;
di.backend=this;
- domains->push_back(di);
+ domains->push_back(std::move(di));
};
}
vector<DomainInfo> domains;
{
ReadLock rl(&s_state_lock);
+ domains.reserve(s_state.size());
for(state_t::const_iterator i = s_state.begin(); i != s_state.end() ; ++i) {
if(i->d_kind != DomainInfo::Slave)
continue;
sd.last_check=i->d_lastcheck;
sd.backend=this;
sd.kind=DomainInfo::Slave;
- domains.push_back(sd);
+ domains.push_back(std::move(sd));
}
}
+ unfreshDomains->reserve(domains.size());
for(DomainInfo &sd : domains) {
SOAData soadata;
catch(...){}
sd.serial=soadata.serial;
if(sd.last_check+soadata.refresh < (unsigned int)time(0))
- unfreshDomains->push_back(sd);
+ unfreshDomains->push_back(std::move(sd));
}
}
if(zoneName.empty())
;
else if(bdr.qname.isPartOf(zoneName))
- bdr.qname = bdr.qname.makeRelative(zoneName);
+ bdr.qname.makeUsRelative(zoneName);
else {
string msg = "Trying to insert non-zone data, name='"+bdr.qname.toLogString()+"', qtype="+qtype.getName()+", zone='"+zoneName.toLogString()+"'";
if(s_ignore_broken_records) {
bdr.auth=true;
bdr.ttl=ttl;
- records->insert(bdr);
+ records->insert(std::move(bdr));
}
string Bind2Backend::DLReloadNowHandler(const vector<string>&parts, Utility::pid_t ppid)
{
bool auth;
DNSName shorter;
- set<DNSName> qnames;
- map<DNSName, bool> nonterm;
+ std::unordered_set<DNSName> qnames;
+ std::unordered_map<DNSName, bool> nonterm;
uint32_t maxent = ::arg().asNum("max-ent-entries");
}
if (!nonterm.count(shorter)) {
- nonterm.insert(pair<DNSName, bool>(shorter, auth));
+ nonterm.emplace(shorter, auth);
--maxent;
} else if (auth)
nonterm[shorter] = true;
sort(domains.begin(), domains.end()); // put stuff in inode order
for(vector<BindDomainInfo>::const_iterator i=domains.begin();
i!=domains.end();
- ++i)
+ ++i)
{
if (!(i->hadFileDirective)) {
g_log<<Logger::Warning<<d_logprefix<<" Zone '"<<i->name<<"' has no 'file' directive set in "<<getArg("config")<<endl;
if (zoneId >= 0) {
if ((found = (safeGetBBDomainInfo(zoneId, &bbd) && qname.isPartOf(bbd.d_name)))) {
- domain = bbd.d_name;
+ domain = std::move(bbd.d_name);
}
} else {
domain = qname;
d_handle.id=bbd.d_id;
d_handle.qname=qname.makeRelative(domain); // strip domain name
d_handle.qtype=qtype;
- d_handle.domain=domain;
+ d_handle.domain=std::move(domain);
if(!bbd.d_loaded) {
d_handle.reset();
- throw DBException("Zone for '"+bbd.d_name.toLogString()+"' in '"+bbd.d_filename+"' temporarily not available (file missing, or master dead)"); // fsck
+ throw DBException("Zone for '"+d_handle.domain.toLogString()+"' in '"+bbd.d_filename+"' temporarily not available (file missing, or master dead)"); // fsck
}
if(!bbd.current()) {
- g_log<<Logger::Warning<<"Zone '"<<bbd.d_name<<"' ("<<bbd.d_filename<<") needs reloading"<<endl;
+ g_log<<Logger::Warning<<"Zone '"<<d_handle.domain<<"' ("<<bbd.d_filename<<") needs reloading"<<endl;
queueReloadAndStore(bbd.d_id);
- if (!safeGetBBDomainInfo(domain, &bbd))
+ if (!safeGetBBDomainInfo(d_handle.domain, &bbd))
throw DBException("Zone '"+bbd.d_name.toLogString()+"' ("+bbd.d_filename+") gone after reload"); // if we don't throw here, we crash for some reason
}
r.qtype=ri->qtype;
r.ttl=ri->ttl;
r.auth = ri->auth;
- result.push_back(r);
+ result.push_back(std::move(r));
}
}
}
g_log<<Logger::Warning<<"Result field at row " << d_residx << " column " << i << " has been truncated, we allocated " << d_res_bind[i].buffer_length << " bytes but at least " << *d_res_bind[i].length << " was needed" << endl;
}
if (*d_res_bind[i].is_null) {
- row.push_back("");
+ row.emplace_back("");
continue;
} else {
- row.push_back(string((char*)d_res_bind[i].buffer, std::min(d_res_bind[i].buffer_length, *d_res_bind[i].length)));
+ row.emplace_back((char*)d_res_bind[i].buffer, std::min(d_res_bind[i].buffer_length, *d_res_bind[i].length));
}
}
while(hasNextRow()) {
nextRow(row);
- result.push_back(row);
+ result.push_back(std::move(row));
}
return this;
row.reserve(PQnfields(d_res));
for(i=0;i<PQnfields(d_res);i++) {
if (PQgetisnull(d_res, d_residx, i)) {
- row.push_back("");
+ row.emplace_back("");
} else if (PQftype(d_res, i) == 16) { // BOOLEAN
char *val = PQgetvalue(d_res, d_residx, i);
- row.push_back(val[0] == 't' ? "1" : "0");
+ row.emplace_back(val[0] == 't' ? "1" : "0");
} else {
- row.push_back(string(PQgetvalue(d_res, d_residx, i)));
+ row.emplace_back(PQgetvalue(d_res, d_residx, i));
}
}
d_residx++;
if (d_res == NULL) return this;
result.reserve(d_resnum);
row_t row;
- while(hasNextRow()) { nextRow(row); result.push_back(row); }
+ while(hasNextRow()) { nextRow(row); result.push_back(std::move(row)); }
return this;
}
}
/* no existing entry found to refresh */
- mc.d_map.insert(entry);
+ mc.d_map.insert(std::move(entry));
if (*d_statnumentries >= d_maxEntries) {
/* remove the least recently inserted or replaced entry */
sidx.pop_front();
}
else {
- (*d_statnumentries)++;
+ ++(*d_statnumentries);
}
}
}
}
}
-void AuthQueryCache::insert(const DNSName &qname, const QType& qtype, const vector<DNSZoneRecord>& value, uint32_t ttl, int zoneID)
+void AuthQueryCache::insert(const DNSName &qname, const QType& qtype, vector<DNSZoneRecord>&& value, uint32_t ttl, int zoneID)
{
cleanupIfNeeded();
val.ttd = now + ttl;
val.qname = qname;
val.qtype = qtype.getCode();
- val.drs = value;
+ val.drs = std::move(value);
val.zoneID = zoneID;
auto& mc = getMap(val.qname);
tie(place, inserted) = mc.d_map.insert(val);
if (!inserted) {
- mc.d_map.replace(place, val);
+ mc.d_map.replace(place, std::move(val));
moveCacheItemToBack<SequencedTag>(mc.d_map, place);
}
else {
AuthQueryCache(size_t mapsCount=1024);
~AuthQueryCache();
- void insert(const DNSName &qname, const QType& qtype, const vector<DNSZoneRecord>& content, uint32_t ttl, int zoneID);
+ void insert(const DNSName &qname, const QType& qtype, vector<DNSZoneRecord>&& content, uint32_t ttl, int zoneID);
bool getEntry(const DNSName &qname, const QType& qtype, vector<DNSZoneRecord>& entry, int zoneID);
return false;
}
-void GSQLBackend::extractRecord(const SSqlStatement::row_t& row, DNSResourceRecord& r)
+void GSQLBackend::extractRecord(SSqlStatement::row_t& row, DNSResourceRecord& r)
{
+ static const int defaultTTL = ::arg().asNum( "default-ttl" );
+
if (row[1].empty())
- r.ttl = ::arg().asNum( "default-ttl" );
+ r.ttl = defaultTTL;
else
r.ttl=pdns_stou(row[1]);
+
if(!d_qname.empty())
r.qname=d_qname;
else
r.qtype=row[3];
- if (r.qtype==QType::MX || r.qtype==QType::SRV)
+ if (r.qtype==QType::MX || r.qtype==QType::SRV) {
+ r.content.reserve(row[2].size() + row[0].size() + 1);
r.content=row[2]+" "+row[0];
- else
- r.content=row[0];
+ }
+ else {
+ r.content=std::move(row[0]);
+ }
r.last_modified=0;
r.domain_id=pdns_stou(row[4]);
}
-void GSQLBackend::extractComment(const SSqlStatement::row_t& row, Comment& comment)
+void GSQLBackend::extractComment(SSqlStatement::row_t& row, Comment& comment)
{
comment.domain_id = pdns_stou(row[0]);
comment.qname = DNSName(row[1]);
comment.qtype = row[2];
comment.modified_at = pdns_stou(row[3]);
- comment.account = row[4];
- comment.content = row[5];
+ comment.account = std::move(row[4]);
+ comment.content = std::move(row[5]);
}
SSqlStatement::~SSqlStatement() {
protected:
bool createDomain(const DNSName &domain, const string &type, const string &masters, const string &account);
string pattern2SQLPattern(const string& pattern);
- void extractRecord(const SSqlStatement::row_t& row, DNSResourceRecord& rr);
- void extractComment(const SSqlStatement::row_t& row, Comment& c);
+ void extractRecord(SSqlStatement::row_t& row, DNSResourceRecord& rr);
+ void extractComment(SSqlStatement::row_t& row, Comment& c);
bool isConnectionUsable() {
if (d_db) {
return d_db->isConnectionUsable();
}
if (ttl > 0) {
- ReadLock l(&s_metacachelock);
-
+ ReadLock l(&s_metacachelock);
+
metacache_t::const_iterator iter = s_metacache.find(tie(zname, key));
if(iter != s_metacache.end() && iter->d_ttd > now) {
value = iter->d_value;
vector<string> meta;
d_keymetadb->getDomainMetadata(zname, key, meta);
if(!meta.empty()) {
- value=*meta.begin();
+ value=std::move(*meta.begin());
isset = true;
}
if(iter != s_keycache.end() && iter->d_ttd > now) {
keyset_t ret;
+ ret.reserve(iter->d_keys.size());
for(const keyset_t::value_type& value : iter->d_keys)
ret.push_back(value);
return ret;
}
}
set_intersection(algoSEP.begin(), algoSEP.end(), algoNoSEP.begin(), algoNoSEP.end(), std::back_inserter(algoHasSeparateKSK));
+ retkeyset.reserve(dbkeyset.size());
for(DNSBackend::KeyData& kd : dbkeyset)
{
// fill out data with some plausible defaults:
// 10800 3600 604800 3600
vector<string>parts;
+ parts.reserve(7);
stringtok(parts,content);
int pleft=parts.size();
}
if (vars->count("keyLogFile")) {
+#ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
config.d_keyLogFile = boost::get<const string>((*vars)["keyLogFile"]);
+#else
+ errlog("TLS Key logging has been enabled using the 'keyLogFile' parameter to %s(), but this version of OpenSSL does not support it", context);
+ g_outputBuffer = "TLS Key logging has been enabled using the 'keyLogFile' parameter to " + context + "(), but this version of OpenSSL does not support it";
+#endif
}
}
});
g_lua.writeFunction("addDOHLocal", [client](const std::string& addr, boost::optional<boost::variant<std::string, std::vector<std::pair<int,std::string>>>> certFiles, boost::optional<boost::variant<std::string, std::vector<std::pair<int,std::string>>>> keyFiles, boost::optional<boost::variant<std::string, vector<pair<int, std::string> > > > urls, boost::optional<localbind_t> vars) {
-#ifdef HAVE_DNS_OVER_HTTPS
if (client) {
return;
}
+#ifdef HAVE_DNS_OVER_HTTPS
setLuaSideEffect();
if (g_configurationDone) {
g_outputBuffer="addDOHLocal cannot be used at runtime!\n";
}
}
else {
- frontend->d_urls = {"/"};
+ frontend->d_urls = {"/dns-query"};
}
bool reusePort = false;
});
g_lua.writeFunction("addTLSLocal", [client](const std::string& addr, boost::variant<std::string, std::vector<std::pair<int,std::string>>> certFiles, boost::variant<std::string, std::vector<std::pair<int,std::string>>> keyFiles, boost::optional<localbind_t> vars) {
-#ifdef HAVE_DNS_OVER_TLS
- if (client)
+ if (client) {
return;
+ }
+#ifdef HAVE_DNS_OVER_TLS
setLuaSideEffect();
if (g_configurationDone) {
g_outputBuffer="addTLSLocal cannot be used at runtime!\n";
.. versionchanged:: 1.5.0
``sendCacheControlHeaders``, ``sessionTimeout`` options added.
+ ``url`` now defaults to ``/dns-query`` instead of ``/``
Listen on the specified address and TCP port for incoming DNS over HTTPS connections, presenting the specified X.509 certificate.
If no certificate (or key) files are specified, listen for incoming DNS over HTTP connections instead.
The default port is 443.
:param str certFile(s): The path to a X.509 certificate file in PEM format, or a list of paths to such files.
:param str keyFile(s): The path to the private key file corresponding to the certificate, or a list of paths to such files, whose order should match the certFile(s) ones.
- :param str-or-list urls: A base URL, or a list of base URLs, to accept queries on. Any query with a path under one of these will be treated as a DoH query. The default is /.
+ :param str-or-list urls: A base URL, or a list of base URLs, to accept queries on. Any query with a path under one of these will be treated as a DoH query. The default is /dns-query.
:param table options: A table with key: value pairs with listen options.
Options:
* ``sessionTickets``: bool - Whether session resumption via session tickets is enabled. Default is true, meaning tickets are enabled.
* ``numberOfStoredSessions``: int - The maximum number of sessions kept in memory at the same time. Default is 20480. Setting this value to 0 disables stored session entirely.
* ``preferServerCiphers``: bool - Whether to prefer the order of ciphers set by the server instead of the one set by the client. Default is true, meaning that the order of the server is used.
- * ``keyLogFile``: str - Write the TLS keys in the specified file so that an external program can decrypt TLS exchanges, in the format described in https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
+ * ``keyLogFile``: str - Write the TLS keys in the specified file so that an external program can decrypt TLS exchanges, in the format described in https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. Note that this feature requires OpenSSL >= 1.1.1.
* ``sendCacheControlHeaders``: bool - Whether to parse the response to find the lowest TTL and set a HTTP Cache-Control header accordingly. Default is true.
.. function:: addTLSLocal(address, certFile(s), keyFile(s) [, options])
* ``ocspResponses``: list - List of files containing OCSP responses, in the same order than the certificates and keys, that will be used to provide OCSP stapling responses.
* ``minTLSVersion``: str - Minimum version of the TLS protocol to support. Possible values are 'tls1.0', 'tls1.1', 'tls1.2' and 'tls1.3'. Default is to require at least TLS 1.0. Note that this value is ignored when the GnuTLS provider is in use, and the ``ciphers`` option should be set accordingly instead. For example, 'NORMAL:!VERS-TLS1.0:!VERS-TLS1.1' will disable TLS 1.0 and 1.1.
* ``preferServerCiphers``: bool - Whether to prefer the order of ciphers set by the server instead of the one set by the client. Default is true, meaning that the order of the server is used.
- * ``keyLogFile``: str - Write the TLS keys in the specified file so that an external program can decrypt TLS exchanges, in the format described in https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
+ * ``keyLogFile``: str - Write the TLS keys in the specified file so that an external program can decrypt TLS exchanges, in the format described in https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. Note that this feature requires OpenSSL >= 1.1.1.
.. function:: setLocal(address[, options])
config
constants
comboaddress
+ netmask
netmaskgroup
dnsname
dnsnameset
.. method:: Netmask:getMaskedNetwork() -> ComboAddress
- Return a :class:`ComboAddress` object representing the base network of this netmask object after masking any additional bits if necessary (for example ``192.0.2.0`` if the netmask was constructed with ``newNetmask('192.0.2.1/24')).
+ Return a :class:`ComboAddress` object representing the base network of this netmask object after masking any additional bits if necessary (for example ``192.0.2.0`` if the netmask was constructed with ``newNetmask('192.0.2.1/24')``).
.. method:: Netmask:empty() -> bool
.. versionadded:: 1.5.0
Forge a response with the specified raw bytes as record data.
- For example, for a TXT record of "aaa" "bbbb": SpoofRawAction("\003aaa\004bbbb")
+
+ .. code-block:: Lua
+
+ -- select queries for the 'raw.powerdns.com.' name and TXT type, and answer with a "aaa" "bbb" TXT record:
+ addAction(AndRule({QNameRule('raw.powerdns.com.'), QTypeRule(DNSQType.TXT)}), SpoofRawAction("\003aaa\004bbbb"))
+ -- select queries for the 'raw-srv.powerdns.com.' name and SRV type, and answer with a '0 0 65535 srv.powerdns.com.' SRV record, setting the AA bit to 1 and the TTL to 3600s
+ addAction(AndRule({QNameRule('raw-srv.powerdns.com.'), QTypeRule(DNSQType.SRV)}), SpoofRawAction("\000\000\000\000\255\255\003srv\008powerdns\003com\000", { aa=true, ttl=3600 }))
+ -- select reverse queries for '127.0.0.1' and answer with 'localhost'
+ addAction(AndRule({QNameRule('1.0.0.127.in-addr.arpa.'), QTypeRule(DNSQType.PTR)}), SpoofRawAction("\009localhost\000"))
:param string rawAnswer: The raw record data
:param table options: A table with key: value pairs with options.
1.4.0 to 1.5.x
--------------
-DOH endpoints specified in the fourth parameter of :func:`addDOHLocal` are now specified as exact URLs instead of path prefixes```
+DOH endpoints specified in the fourth parameter of :func:`addDOHLocal` are now specified as exact URLs instead of path prefixes. The default endpoint also switched from ``/`` to ``/dns-query``.
For example, ``addDOHLocal('2001:db8:1:f00::1', '/etc/ssl/certs/example.com.pem', '/etc/ssl/private/example.com.key', { "/dns-query" })`` will now only accept queries for ``/dns-query`` and no longer for ``/dns-query/foo/bar``.
The systemd service-file that is installed no longer uses the ``root`` user to start. It uses the user and group set with the ``--with-service-user`` and ``--with-service-group`` switches during
++pos;
}
}
+
+bool DNSName::has8bitBytes() const
+{
+ const auto& s = d_storage;
+ string::size_type pos = 0;
+ uint8_t length = s.at(pos);
+ while (length > 0) {
+ for (size_t idx = 0; idx < length; idx++) {
+ ++pos;
+ char c = s.at(pos);
+ if(!((c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z') ||
+ (c >= '0' && c <= '9') ||
+ c =='-' || c == '_' || c=='*' || c=='.' || c=='/' || c=='@' || c==' ' || c=='\\' || c==':'))
+ return true;
+ }
+ ++pos;
+ length = s.at(pos);
+ }
+
+ return false;
+}
const string_t& getStorage() const {
return d_storage;
}
+
+ bool has8bitBytes() const; /* returns true if at least one byte of the labels forming the name is not included in [A-Za-z0-9_*./@ \\:-] */
+
private:
string_t d_storage;
d_dedup.clear();
}
-void DNSPacket::addRecord(const DNSZoneRecord &rr)
+void DNSPacket::addRecord(DNSZoneRecord&& rr)
{
// this removes duplicates from the packet.
// in case we are not compressing for AXFR, no such checking is performed!
d_dedup.insert(hash);
}
- d_rrs.push_back(rr);
+ d_rrs.push_back(std::move(rr));
}
vector<DNSZoneRecord*> DNSPacket::getAPRecords()
/** Add a DNSZoneRecord to this packet. A DNSPacket (as does a DNS Packet) has 4 kinds of resource records. Questions,
Answers, Authority and Additional. See RFC 1034 and 1035 for details. You can specify where a record needs to go in the
DNSZoneRecord d_place field */
- void addRecord(const DNSZoneRecord &); // adds to 'rrs'
+ void addRecord(DNSZoneRecord&&); // adds to 'rrs'
void setQuestion(int op, const DNSName &qdomain, int qtype); // wipes 'd', sets a random id, creates start of packet (domain, type, class etc)
for (auto &ip : ips)
{
ip.dr.d_name = aname;
- r->addRecord(ip);
+ r->addRecord(std::move(ip));
}
}
dzr.dr.d_ttl=j->first.d_ttl;
dzr.dr.d_place= j->first.d_place;
dzr.dr.d_content=j->first.d_content;
- i->second.complete->addRecord(dzr);
+ i->second.complete->addRecord(std::move(dzr));
}
}
}
string field(d_data.c_str() + pos, len);
pos+=len;
- options.push_back(make_pair(code, field));
+ options.push_back(make_pair(code, std::move(field)));
}
}
dnsheader.opcode=opcode;
const uint8_t* ptr=(const uint8_t*)&dnsheader;
- uint32_t len=d_content.size();
- d_content.resize(len + sizeof(dnsheader));
- uint8_t* dptr=(&*d_content.begin()) + len;
+ d_content.reserve(sizeof(dnsheader) + qname.wirelength() + sizeof(qtype) + sizeof(qclass));
+ d_content.resize(sizeof(dnsheader));
+ uint8_t* dptr=(&*d_content.begin());
memcpy(dptr, ptr, sizeof(dnsheader));
d_namepositions.reserve(16);
uint32_t getSerialFromRecords(const records_t& records, DNSRecord& soaret)
{
- DNSName root(".");
uint16_t t=QType::SOA;
- auto found = records.equal_range(tie(root, t));
+ auto found = records.equal_range(tie(g_rootdnsname, t));
for(auto iter = found.first; iter != found.second; ++iter) {
auto soa = std::dynamic_pointer_cast<SOARecordContent>(iter->d_content);
d_lw->registerFunction<DNSPacket, void(unsigned int)>("setOpCode", [](DNSPacket &p, unsigned int opcode) { return p.setOpcode(static_cast<uint16_t>(opcode)); });
d_lw->registerFunction<DNSPacket, void(int)>("setRcode", [](DNSPacket &p, int rcode) { return p.setRcode(rcode); });
d_lw->registerFunction<DNSPacket, void()>("clearRecords",[](DNSPacket &p){p.clearRecords();});
- d_lw->registerFunction<DNSPacket, void(DNSRecord&, bool)>("addRecord", [](DNSPacket &p, DNSRecord &dr, bool auth) { DNSZoneRecord dzr; dzr.dr = dr; dzr.auth = auth; p.addRecord(dzr); });
- d_lw->registerFunction<DNSPacket, void(const vector<pair<unsigned int, DNSRecord> >&)>("addRecords", [](DNSPacket &p, const vector<pair<unsigned int, DNSRecord> >& records){ for(const auto &dr: records){ DNSZoneRecord dzr; dzr.dr = std::get<1>(dr); dzr.auth = true; p.addRecord(dzr); }});
+ d_lw->registerFunction<DNSPacket, void(DNSRecord&, bool)>("addRecord", [](DNSPacket &p, DNSRecord &dr, bool auth) { DNSZoneRecord dzr; dzr.dr = dr; dzr.auth = auth; p.addRecord(std::move(dzr)); });
+ d_lw->registerFunction<DNSPacket, void(const vector<pair<unsigned int, DNSRecord> >&)>("addRecords", [](DNSPacket &p, const vector<pair<unsigned int, DNSRecord> >& records){ for(const auto &dr: records){ DNSZoneRecord dzr; dzr.dr = std::get<1>(dr); dzr.auth = true; p.addRecord(std::move(dzr)); }});
d_lw->registerFunction<DNSPacket, void(unsigned int, const DNSName&, const std::string&)>("setQuestion", [](DNSPacket &p, unsigned int opcode, const DNSName &name, const string &type){ QType qtype; qtype = type; p.setQuestion(static_cast<int>(opcode), name, static_cast<int>(qtype.getCode())); });
d_lw->registerFunction<DNSPacket, bool()>("isEmpty", [](DNSPacket &p){return p.isEmpty();});
d_lw->registerFunction<DNSPacket, std::shared_ptr<DNSPacket>()>("replyPacket",[](DNSPacket& p){ return p.replyPacket();});
void UDPNameserver::send(DNSPacket& p)
{
- string buffer=p.getString();
+ const string& buffer=p.getString();
g_rs.submitResponse(p, true);
struct msghdr msgh;
rr.dr.d_name=p.qdomain;
rr.dr.d_content=std::make_shared<DNSKEYRecordContent>(value.first.getDNSKEY());
rr.auth=true;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
haveOne=true;
}
while(B.get(rr)) {
rr.dr.d_ttl=sd.minimum;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
haveOne=true;
}
}
rr.dr.d_name=p.qdomain;
rr.dr.d_content=std::make_shared<DNSKEYRecordContent>(value.first.getDNSKEY());
rr.auth=true;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
haveOne=true;
}
while(B.get(rr)) {
rr.dr.d_ttl=sd.minimum;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
haveOne=true;
}
}
}
for(auto const &digestAlgo : digestAlgos){
rr.dr.d_content=std::make_shared<DSRecordContent>(makeDSFromDNSKey(p.qdomain, value.first.getDNSKEY(), pdns_stou(digestAlgo)));
- r->addRecord(rr);
+ r->addRecord(DNSZoneRecord(rr));
haveOne=true;
}
}
while(B.get(rr)) {
rr.dr.d_ttl=sd.minimum;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
haveOne=true;
}
}
ns3prc.d_flags = 0; // the NSEC3PARAM 'flag' is defined to always be zero in RFC5155.
rr.dr.d_content=std::make_shared<NSEC3PARAMRecordContent>(ns3prc);
rr.auth = true;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
return true;
}
return false;
rr.dr.d_name=target;
rr.dr.d_type=QType::TXT;
rr.dr.d_class=QClass::CHAOS;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
return 1;
}
toAdd.push_back(rr);
}
}
- for(const auto& rec : toAdd)
- r->addRecord(rec);
+
+ for(auto& rec : toAdd) {
+ r->addRecord(std::move(rec));
+ }
//records.insert(records.end(), toAdd.cbegin(), toAdd.cend()); // would be faster, but no dedup
}
rr.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
rr.auth = true;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
}
void PacketHandler::emitNSEC3(std::unique_ptr<DNSPacket>& r, const SOAData& sd, const NSEC3PARAMRecordContent& ns3prc, const DNSName& name, const string& namehash, const string& nexthash, int mode)
rr.dr.d_place = (mode == 5 ) ? DNSResourceRecord::ANSWER: DNSResourceRecord::AUTHORITY;
rr.auth = true;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
}
/*
return 0;
}
-static bool validDNSName(const DNSName &name)
+static bool validDNSName(const DNSName& name)
{
if (!g_8bitDNS) {
- string::size_type pos, length;
- char c;
- for(const auto& s : name.getRawLabels()) {
- length=s.length();
- for(pos=0; pos < length; ++pos) {
- c=s[pos];
- if(!((c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9') ||
- c =='-' || c == '_' || c=='*' || c=='.' || c=='/' || c=='@' || c==' ' || c=='\\' || c==':'))
- return false;
- }
- }
+ return name.has8bitBytes() == false;
}
return true;
}
DNSZoneRecord rr;
rr=makeEditedDNSZRFromSOAData(d_dk, sd, DNSResourceRecord::AUTHORITY);
rr.dr.d_ttl=sd.getNegativeTTL();
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
if(d_dnssec) {
addNSECX(p, r, target, wildcard, sd.qname, 4);
DNSZoneRecord rr;
rr=makeEditedDNSZRFromSOAData(d_dk, sd, DNSResourceRecord::AUTHORITY);
rr.dr.d_ttl=sd.getNegativeTTL();
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
if(d_dnssec) {
addNSECX(p, r, target, wildcard, sd.qname, mode);
while(B.get(rr)) {
gotOne=true;
rr.dr.d_place = DNSResourceRecord::AUTHORITY;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
}
return gotOne;
}
vector<DNSZoneRecord> rrset = getBestReferralNS(p, sd, target);
if(rrset.empty())
return false;
-
+
+ DNSName name = rrset.begin()->dr.d_name;
for(auto& rr: rrset) {
rr.dr.d_place=DNSResourceRecord::AUTHORITY;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
}
if(!retargeted)
r->setA(false);
- if(d_dk.isSecuredZone(sd.qname) && !addDSforNS(p, r, sd, rrset.begin()->dr.d_name) && d_dnssec) {
- addNSECX(p, r, rrset.begin()->dr.d_name, DNSName(), sd.qname, 1);
+ if(d_dk.isSecuredZone(sd.qname) && !addDSforNS(p, r, sd, name) && d_dnssec) {
+ addNSECX(p, r, name, DNSName(), sd.qname, 1);
}
return true;
if(!rrset.empty()) {
for(auto& rr: rrset) {
rr.dr.d_place = DNSResourceRecord::ANSWER;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
}
return true;
}
}
rr.dr.d_place=DNSResourceRecord::ANSWER;
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
}
}
if(d_dnssec && !nodata) {
if(p.qtype.getCode() == QType::SOA && sd.qname==p.qdomain) {
rr=makeEditedDNSZRFromSOAData(d_dk, sd);
- r->addRecord(rr);
+ r->addRecord(std::move(rr));
goto sendit;
}
if(weRedirected) {
for(auto& loopRR: rrset) {
if(loopRR.dr.d_type == QType::CNAME) {
- r->addRecord(loopRR);
+ r->addRecord(DNSZoneRecord(loopRR));
target = getRR<CNAMERecordContent>(loopRR.dr)->getTarget();
retargetcount++;
goto retargeted;
continue;
#endif
if((p.qtype.getCode() == QType::ANY || loopRR.dr.d_type == p.qtype.getCode()) && loopRR.dr.d_type && loopRR.dr.d_type != QType::ALIAS && loopRR.auth) {
- r->addRecord(loopRR);
+ r->addRecord(DNSZoneRecord(loopRR));
haveRecords = true;
}
}
if (xpfcode) {
ComboAddress src(xpfsrc), dst(xpfdst);
- pw.startRecord(DNSName("."), xpfcode, 0, QClass::IN, DNSResourceRecord::ADDITIONAL);
+ pw.startRecord(g_rootdnsname, xpfcode, 0, QClass::IN, DNSResourceRecord::ADDITIONAL);
// xpf->toPacket(pw);
pw.xfr8BitInt(xpfversion);
pw.xfr8BitInt(xpfproto);
dzr.domain_id = sd.domain_id;
dzr.signttl = sd.ttl;
dzr.auth = true;
- dzr.dr = soa;
+ dzr.dr = std::move(soa);
return dzr;
}
{
Lock l(&d_lock);
set<DomainInfo> requeue;
+ rdomains.reserve(d_tocheck.size());
for(const auto& di: d_tocheck) {
if(d_inprogress.count(di.zone)) {
g_log<<Logger::Debug<<"Got NOTIFY for "<<di.zone<<" while AXFR in progress, requeueing SOA check"<<endl;
if(rdomains.empty()) { // if we have priority domains, check them first
B->getUnfreshSlaveInfos(&rdomains);
}
+ sdomains.reserve(rdomains.size());
DNSSECKeeper dk(B); // NOW HEAR THIS! This DK uses our B backend, so no interleaved access!
{
Lock l(&d_lock);
dni.localaddr.sin4.sin_family = 0;
}
- sdomains.push_back(dni);
+ sdomains.push_back(std::move(dni));
}
}
if(sdomains.empty())
for ( int i=0; i<numCols; i++)
{
if (sqlite3_column_type(d_stmt,i) == SQLITE_NULL) {
- row.push_back("");
+ row.emplace_back("");
} else {
const char *pData = (const char*) sqlite3_column_text(d_stmt, i);
- row.push_back(string(pData, sqlite3_column_bytes(d_stmt, i)));
+ row.emplace_back(pData, sqlite3_column_bytes(d_stmt, i));
}
}
d_rc = sqlite3_step(d_stmt);
while(hasNextRow()) {
row_t row;
nextRow(row);
- result.push_back(row);
+ result.push_back(std::move(row));
}
return this;
}
// SOA *must* go out first, our signing pipe might reorder
DLOG(g_log<<"Sending out SOA"<<endl);
DNSZoneRecord soa = makeEditedDNSZRFromSOAData(dk, sd);
- outpacket->addRecord(soa);
+ outpacket->addRecord(DNSZoneRecord(soa));
if(securedZone && !presignedZone) {
set<DNSName> authSet;
authSet.insert(target);
DLOG(g_log<<"Done writing out records"<<endl);
/* and terminate with yet again the SOA record */
outpacket=getFreshAXFRPacket(q);
- outpacket->addRecord(soa);
+ outpacket->addRecord(std::move(soa));
if(haveTSIGDetails && !tsigkeyname.empty())
outpacket->setTSIGDetails(trc, tsigkeyname, tsigsecret, trc.d_mac, true);
// SOA *must* go out first, our signing pipe might reorder
DLOG(g_log<<"Sending out SOA"<<endl);
DNSZoneRecord soa = makeEditedDNSZRFromSOAData(dk, sd);
- outpacket->addRecord(soa);
+ outpacket->addRecord(std::move(soa));
if(securedZone && outpacket->d_dnssecOk) {
set<DNSName> authSet;
authSet.insert(target);
vector<DNSZoneRecord> records;
BOOST_CHECK_EQUAL(QC.size(), 0U);
- QC.insert(DNSName("hello"), QType(QType::A), records, 3600, 1);
+ QC.insert(DNSName("hello"), QType(QType::A), vector<DNSZoneRecord>(records), 3600, 1);
BOOST_CHECK_EQUAL(QC.size(), 1U);
BOOST_CHECK_EQUAL(QC.purge(), 1U);
BOOST_CHECK_EQUAL(QC.size(), 0U);
DNSName a=DNSName("hello ")+DNSName(std::to_string(counter));
BOOST_CHECK_EQUAL(DNSName(a.toString()), a);
- QC.insert(a, QType(QType::A), records, 3600, 1);
+ QC.insert(a, QType(QType::A), vector<DNSZoneRecord>(records), 3600, 1);
if(!QC.purge(a.toString()))
BOOST_FAIL("Could not remove entry we just added to the query cache!");
- QC.insert(a, QType(QType::A), records, 3600, 1);
+ QC.insert(a, QType(QType::A), vector<DNSZoneRecord>(records), 3600, 1);
}
BOOST_CHECK_EQUAL(QC.size(), counter);
vector<DNSZoneRecord> records;
unsigned int offset=(unsigned int)(unsigned long)a;
for(unsigned int counter=0; counter < 100000; ++counter)
- g_QC->insert(DNSName("hello ")+DNSName(std::to_string(counter+offset)), QType(QType::A), records, 3600, 1);
+ g_QC->insert(DNSName("hello ")+DNSName(std::to_string(counter+offset)), QType(QType::A), vector<DNSZoneRecord>(records), 3600, 1);
return 0;
}
catch(PDNSException& e) {
vector<DNSZoneRecord> records;
for(unsigned int counter = 0; counter < 1000000; ++counter) {
- QC.insert(DNSName("hello ")+DNSName(std::to_string(counter)), QType(QType::A), records, 1, 1);
+ QC.insert(DNSName("hello ")+DNSName(std::to_string(counter)), QType(QType::A), vector<DNSZoneRecord>(records), 1, 1);
}
sleep(1);
zrr.dr.d_class = QClass::ANY;
zrr.dr.d_content = tkey_out;
zrr.dr.d_place = DNSResourceRecord::ANSWER;
- r->addRecord(zrr);
+ r->addRecord(std::move(zrr));
if (sign)
{
QC.insert(q.qname, q.qtype, vector<DNSZoneRecord>(), d_negcache_ttl, q.zoneId);
}
-void UeberBackend::addCache(const Question &q, const vector<DNSZoneRecord> &rrs)
+void UeberBackend::addCache(const Question &q, vector<DNSZoneRecord> &&rrs)
{
extern AuthQueryCache QC;
return;
}
- QC.insert(q.qname, q.qtype, rrs, store_ttl, q.zoneId);
+ QC.insert(q.qname, q.qtype, std::move(rrs), store_ttl, q.zoneId);
}
void UeberBackend::alsoNotifies(const DNSName &domain, set<string> *ips)
}
else {
// cout<<"adding query cache"<<endl;
- addCache(d_question, d_answers);
+ addCache(d_question, std::move(d_answers));
}
d_answers.clear();
return false;
int cacheHas(const Question &q, vector<DNSZoneRecord> &rrs);
void addNegCache(const Question &q);
- void addCache(const Question &q, const vector<DNSZoneRecord> &rrs);
+ void addCache(const Question &q, vector<DNSZoneRecord>&& rrs);
};
static Json::object getZoneInfo(const DomainInfo& di, DNSSECKeeper* dk) {
string zoneId = apiZoneNameToId(di.zone);
vector<string> masters;
- for(const auto& m : di.masters)
+ masters.reserve(di.masters.size());
+ for(const auto& m : di.masters) {
masters.push_back(m.toStringWithPortExcept(53));
+ }
auto obj = Json::object {
// id is the canonical lookup key, which doesn't actually match the name (in some cases)
{ "name", di.zone.toString() },
{ "kind", di.getKindString() },
{ "account", di.account },
- { "masters", masters },
+ { "masters", std::move(masters) },
{ "serial", (double)di.serial },
{ "notified_serial", (double)di.notified_serial },
{ "last_check", (double)di.last_check }
}
Json::array doc;
+ doc.reserve(domains.size());
for(const DomainInfo& di : domains) {
doc.push_back(getZoneInfo(di, with_dnssec ? &dk : nullptr));
}
comment->clear();
if(comment && d_line.find(';') != string::npos)
*comment = d_line.substr(d_line.find(';'));
- parts_t parts;
- vstringtok(parts, d_line);
- if(parts.empty())
+ d_parts.clear();
+ vstringtok(d_parts, d_line);
+
+ if(d_parts.empty())
goto retry;
- if(parts[0].first != parts[0].second && d_line[parts[0].first]==';') // line consisting of nothing but comments
+ if(d_parts[0].first != d_parts[0].second && d_line[d_parts[0].first]==';') // line consisting of nothing but comments
goto retry;
if(d_line[0]=='$') {
- string command=makeString(d_line, parts[0]);
- if(pdns_iequals(command,"$TTL") && parts.size() > 1) {
- d_defaultttl=makeTTLFromZone(trim_right_copy_if(makeString(d_line, parts[1]), is_any_of(";")));
+ string command=makeString(d_line, d_parts[0]);
+ if(pdns_iequals(command,"$TTL") && d_parts.size() > 1) {
+ d_defaultttl=makeTTLFromZone(trim_right_copy_if(makeString(d_line, d_parts[1]), is_any_of(";")));
d_havedollarttl=true;
}
- else if(pdns_iequals(command,"$INCLUDE") && parts.size() > 1 && d_fromfile) {
- string fname=unquotify(makeString(d_line, parts[1]));
+ else if(pdns_iequals(command,"$INCLUDE") && d_parts.size() > 1 && d_fromfile) {
+ string fname=unquotify(makeString(d_line, d_parts[1]));
if(!fname.empty() && fname[0]!='/' && !d_reldir.empty())
fname=d_reldir+"/"+fname;
stackFile(fname);
}
- else if(pdns_iequals(command, "$ORIGIN") && parts.size() > 1) {
- d_zonename = DNSName(makeString(d_line, parts[1]));
+ else if(pdns_iequals(command, "$ORIGIN") && d_parts.size() > 1) {
+ d_zonename = DNSName(makeString(d_line, d_parts[1]));
}
- else if(pdns_iequals(command, "$GENERATE") && parts.size() > 2) {
+ else if(pdns_iequals(command, "$GENERATE") && d_parts.size() > 2) {
if (!d_generateEnabled) {
throw exception("$GENERATE is not allowed in this zone");
}
// $GENERATE 1-127 $ CNAME $.0
- string range=makeString(d_line, parts[1]);
+ string range=makeString(d_line, d_parts[1]);
d_templatestep=1;
d_templatestop=0;
sscanf(range.c_str(),"%u-%u/%u", &d_templatecounter, &d_templatestop, &d_templatestep);
}
}
d_templateline=d_line;
- parts.pop_front();
- parts.pop_front();
+ d_parts.pop_front();
+ d_parts.pop_front();
- d_templateparts=parts;
+ d_templateparts=d_parts;
goto retry;
}
else
}
bool prevqname=false;
- string qname = makeString(d_line, parts[0]); // Don't use DNSName here!
+ string qname = makeString(d_line, d_parts[0]); // Don't use DNSName here!
if(dns_isspace(d_line[0])) {
rr.qname=d_prevqname;
prevqname=true;
}else {
rr.qname=DNSName(qname);
- parts.pop_front();
+ d_parts.pop_front();
if(qname.empty() || qname[0]==';')
goto retry;
}
rr.qname += d_zonename;
d_prevqname=rr.qname;
- if(parts.empty())
+ if(d_parts.empty())
throw exception("Line with too little parts "+getLineOfFile());
string nextpart;
bool haveTTL=0, haveQTYPE=0;
pair<string::size_type, string::size_type> range;
- while(!parts.empty()) {
- range=parts.front();
- parts.pop_front();
+ while(!d_parts.empty()) {
+ range=d_parts.front();
+ d_parts.pop_front();
nextpart=makeString(d_line, range);
if(nextpart.empty())
break;
class ZoneParserTNG
{
public:
- ZoneParserTNG(const string& fname, const DNSName& zname=DNSName("."), const string& reldir="");
+ ZoneParserTNG(const string& fname, const DNSName& zname=g_rootdnsname, const string& reldir="");
ZoneParserTNG(const vector<string> zonedata, const DNSName& zname);
~ZoneParserTNG();
int d_lineno;
};
+ parts_t d_parts;
string d_reldir;
string d_line;
DNSName d_prevqname;
_dohServerPort = 8480
_serverName = 'tls.tests.dnsdist.org'
- _dohBaseURL = ("http://%s:%d/" % (_serverName, _dohServerPort))
+ _dohBaseURL = ("http://%s:%d/dns-query" % (_serverName, _dohServerPort))
_config_template = """
newServer{address="127.0.0.1:%s"}
addDOHLocal("127.0.0.1:%s")
_serverName = 'tls.tests.dnsdist.org'
_caCert = 'ca.pem'
_dohServerPort = 8443
- _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort))
+ _dohBaseURL = ("https://%s:%d/dns-query" % (_serverName, _dohServerPort))
_config_template = """
newServer{address="127.0.0.1:%s"}