./pdns/dnscrypt.cc
./pdns/dnscrypt.hh
./pdns/dnsdemog.cc
-./pdns/dnsdist-cache.cc
-./pdns/dnsdist-cache.hh
-./pdns/dnsdist-console.cc
-./pdns/dnsdist-console.hh
-./pdns/dnsdist-dynbpf.cc
-./pdns/dnsdist-dynbpf.hh
-./pdns/dnsdist-ecs.cc
-./pdns/dnsdist-ecs.hh
-./pdns/dnsdist-lbpolicies.hh
-./pdns/dnsdist-lua-bindings-dnsquestion.cc
-./pdns/dnsdist-lua-bindings.cc
-./pdns/dnsdist-lua-inspection.cc
-./pdns/dnsdist-lua-rules.cc
-./pdns/dnsdist-lua-vars.cc
-./pdns/dnsdist-lua.hh
-./pdns/dnsdist-rings.cc
-./pdns/dnsdist-rings.hh
-./pdns/dnsdist-snmp.cc
-./pdns/dnsdist-snmp.hh
-./pdns/dnsdist-tcp.cc
-./pdns/dnsdist-web.cc
-./pdns/dnsdist-xpf.cc
-./pdns/dnsdist-xpf.hh
-./pdns/dnsdist.cc
-./pdns/dnsdist.hh
./pdns/dnsdistdist/connection-management.hh
./pdns/dnsdistdist/dnsdist-backend.cc
./pdns/dnsdistdist/dnsdist-kvs.cc
./pdns/test-common.hh
./pdns/test-distributor_hh.cc
./pdns/test-dnscrypt_cc.cc
-./pdns/test-dnsdist_cc.cc
-./pdns/test-dnsdistpacketcache_cc.cc
./pdns/test-dnsname_cc.cc
./pdns/test-dnsparser_cc.cc
./pdns/test-dnsparser_hh.cc
#include "ednssubnet.hh"
#include "packetcache.hh"
-DNSDistPacketCache::DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL, uint32_t minTTL, uint32_t tempFailureTTL, uint32_t maxNegativeTTL, uint32_t staleTTL, bool dontAge, uint32_t shards, bool deferrableInsertLock, bool parseECS): d_maxEntries(maxEntries), d_shardCount(shards), d_maxTTL(maxTTL), d_tempFailureTTL(tempFailureTTL), d_maxNegativeTTL(maxNegativeTTL), d_minTTL(minTTL), d_staleTTL(staleTTL), d_dontAge(dontAge), d_deferrableInsertLock(deferrableInsertLock), d_parseECS(parseECS)
+DNSDistPacketCache::DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL, uint32_t minTTL, uint32_t tempFailureTTL, uint32_t maxNegativeTTL, uint32_t staleTTL, bool dontAge, uint32_t shards, bool deferrableInsertLock, bool parseECS) :
+ d_maxEntries(maxEntries), d_shardCount(shards), d_maxTTL(maxTTL), d_tempFailureTTL(tempFailureTTL), d_maxNegativeTTL(maxNegativeTTL), d_minTTL(minTTL), d_staleTTL(staleTTL), d_dontAge(dontAge), d_deferrableInsertLock(deferrableInsertLock), d_parseECS(parseECS)
{
if (d_maxEntries == 0) {
throw std::runtime_error("Trying to create a 0-sized packet-cache");
return true;
}
-void DNSDistPacketCache::insertLocked(CacheShard& shard, std::unordered_map<uint32_t,CacheValue>& map, uint32_t key, CacheValue& newValue)
+void DNSDistPacketCache::insertLocked(CacheShard& shard, std::unordered_map<uint32_t, CacheValue>& map, uint32_t key, CacheValue& newValue)
{
/* check again now that we hold the lock to prevent a race */
if (map.size() >= (d_maxEntries / d_shardCount)) {
return;
}
- std::unordered_map<uint32_t,CacheValue>::iterator it;
+ std::unordered_map<uint32_t, CacheValue>::iterator it;
bool result;
std::tie(it, result) = map.insert({key, newValue});
return false;
}
- std::unordered_map<uint32_t,CacheValue>::const_iterator it = map->find(key);
+ std::unordered_map<uint32_t, CacheValue>::const_iterator it = map->find(key);
if (it == map->end()) {
if (recordMiss) {
++d_misses;
if (!stale) {
// coverity[store_truncates_time_t]
dnsheader_aligned dh_aligned(response.data());
- ageDNSPacket(reinterpret_cast<char *>(&response[0]), response.size(), age, dh_aligned);
+ ageDNSPacket(reinterpret_cast<char*>(&response[0]), response.size(), age, dh_aligned);
}
else {
editDNSPacketTTL(reinterpret_cast<char*>(&response[0]), response.size(),
size_t toRemove = map->size() - maxPerShard;
- for (auto it = map->begin(); toRemove > 0 && it != map->end(); ) {
+ for (auto it = map->begin(); toRemove > 0 && it != map->end();) {
const CacheValue& value = it->second;
if (value.validity <= now) {
--toRemove;
--shard.d_entriesCount;
++removed;
- } else {
+ }
+ else {
++it;
}
}
for (auto& shard : d_shards) {
auto map = shard.d_map.write_lock();
- for(auto it = map->begin(); it != map->end(); ) {
+ for (auto it = map->begin(); it != map->end();) {
const CacheValue& value = it->second;
if ((value.qname == name || (suffixMatch && value.qname.isPartOf(name))) && (qtype == QType::ANY || qtype == value.qtype)) {
it = map->erase(it);
--shard.d_entriesCount;
++removed;
- } else {
+ }
+ else {
++it;
}
}
bool DNSDistPacketCache::isFull()
{
- return (getSize() >= d_maxEntries);
+ return (getSize() >= d_maxEntries);
}
uint64_t DNSDistPacketCache::getSize()
uint32_t result = 0;
/* skip the query ID */
if (packet.size() < sizeof(dnsheader)) {
- throw std::range_error("Computing packet cache key for an invalid packet size (" + std::to_string(packet.size()) +")");
+ throw std::range_error("Computing packet cache key for an invalid packet size (" + std::to_string(packet.size()) + ")");
}
result = burtle(&packet.at(2), sizeof(dnsheader) - 2, result);
- result = burtleCI((const unsigned char*) qname.c_str(), qname.length(), result);
+ result = burtleCI((const unsigned char*)qname.c_str(), qname.length(), result);
if (packet.size() < sizeof(dnsheader) + qnameWireLength) {
throw std::range_error("Computing packet cache key for an invalid packet (" + std::to_string(packet.size()) + " < " + std::to_string(sizeof(dnsheader) + qnameWireLength) + ")");
}
result = burtle(&packet.at(sizeof(dnsheader) + qnameWireLength), packet.size() - (sizeof(dnsheader) + qnameWireLength), result);
}
}
- result = burtle((const unsigned char*) &receivedOverUDP, sizeof(receivedOverUDP), result);
+ result = burtle((const unsigned char*)&receivedOverUDP, sizeof(receivedOverUDP), result);
return result;
}
uint64_t DNSDistPacketCache::dump(int fd)
{
- auto fp = std::unique_ptr<FILE, int(*)(FILE*)>(fdopen(dup(fd), "w"), fclose);
+ auto fp = std::unique_ptr<FILE, int (*)(FILE*)>(fdopen(dup(fd), "w"), fclose);
if (fp == nullptr) {
return 0;
}
fprintf(fp.get(), "%s %" PRId64 " %s ; rcode %" PRIu8 ", key %" PRIu32 ", length %" PRIu16 ", received over UDP %d, added %" PRId64 "\n", value.qname.toString().c_str(), static_cast<int64_t>(value.validity - now), QType(value.qtype).toString().c_str(), rcode, entry.first, value.len, value.receivedOverUDP, static_cast<int64_t>(value.added));
}
- catch(...) {
+ catch (...) {
fprintf(fp.get(), "; error printing '%s'\n", value.qname.empty() ? "EMPTY" : value.qname.toString().c_str());
}
}
class DNSDistPacketCache : boost::noncopyable
{
public:
- DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL=86400, uint32_t minTTL=0, uint32_t tempFailureTTL=60, uint32_t maxNegativeTTL=3600, uint32_t staleTTL=60, bool dontAge=false, uint32_t shards=1, bool deferrableInsertLock=true, bool parseECS=false);
+ DNSDistPacketCache(size_t maxEntries, uint32_t maxTTL = 86400, uint32_t minTTL = 0, uint32_t tempFailureTTL = 60, uint32_t maxNegativeTTL = 3600, uint32_t staleTTL = 60, bool dontAge = false, uint32_t shards = 1, bool deferrableInsertLock = true, bool parseECS = false);
void insert(uint32_t key, const boost::optional<Netmask>& subnet, uint16_t queryFlags, bool dnssecOK, const DNSName& qname, uint16_t qtype, uint16_t qclass, const PacketBuffer& response, bool receivedOverUDP, uint8_t rcode, boost::optional<uint32_t> tempFailureTTL);
bool get(DNSQuestion& dq, uint16_t queryId, uint32_t* keyOut, boost::optional<Netmask>& subnet, bool dnssecOK, bool receivedOverUDP, uint32_t allowExpired = 0, bool skipAging = false, bool truncatedOK = true, bool recordMiss = true);
size_t purgeExpired(size_t upTo, const time_t now);
- size_t expunge(size_t upTo=0);
- size_t expungeByName(const DNSName& name, uint16_t qtype=QType::ANY, bool suffixMatch=false);
+ size_t expunge(size_t upTo = 0);
+ size_t expungeByName(const DNSName& name, uint16_t qtype = QType::ANY, bool suffixMatch = false);
bool isFull();
string toString();
uint64_t getSize();
static bool getClientSubnet(const PacketBuffer& packet, size_t qnameWireLength, boost::optional<Netmask>& subnet);
private:
-
struct CacheValue
{
time_t getTTD() const { return validity; }
d_map.write_lock()->reserve(maxSize);
}
- SharedLockGuarded<std::unordered_map<uint32_t,CacheValue>> d_map;
+ SharedLockGuarded<std::unordered_map<uint32_t, CacheValue>> d_map;
std::atomic<uint64_t> d_entriesCount{0};
};
bool cachedValueMatches(const CacheValue& cachedValue, uint16_t queryFlags, const DNSName& qname, uint16_t qtype, uint16_t qclass, bool receivedOverUDP, bool dnssecOK, const boost::optional<Netmask>& subnet) const;
uint32_t getShardIndex(uint32_t key) const;
- void insertLocked(CacheShard& shard, std::unordered_map<uint32_t,CacheValue>& map, uint32_t key, CacheValue& newValue);
+ void insertLocked(CacheShard& shard, std::unordered_map<uint32_t, CacheValue>& map, uint32_t key, CacheValue& newValue);
std::vector<CacheShard> d_shards;
std::unordered_set<uint16_t> d_optionsToSkip{EDNSOptionCode::COOKIE};
#include <thread>
#ifdef HAVE_LIBEDIT
-#if defined (__OpenBSD__) || defined(__NetBSD__)
+#if defined(__OpenBSD__) || defined(__NetBSD__)
// If this is not undeffed, __attribute__ wil be redefined by /usr/include/readline/rlstdc.h
#undef __STRICT_ANSI__
#include <readline/readline.h>
#include "threadname.hh"
GlobalStateHolder<NetmaskGroup> g_consoleACL;
-vector<pair<struct timeval, string> > g_confDelta;
+vector<pair<struct timeval, string>> g_confDelta;
std::string g_consoleKey;
bool g_logConsoleConnections{true};
bool g_consoleEnabled{false};
class ConsoleConnection
{
public:
- ConsoleConnection(const ComboAddress& client, FDWrapper&& fileDesc): d_client(client), d_fileDesc(std::move(fileDesc))
+ ConsoleConnection(const ComboAddress& client, FDWrapper&& fileDesc) :
+ d_client(client), d_fileDesc(std::move(fileDesc))
{
if (!s_connManager.registerConnection()) {
throw std::runtime_error("Too many concurrent console connections");
}
}
- ConsoleConnection(ConsoleConnection&& rhs) noexcept: d_client(rhs.d_client), d_fileDesc(std::move(rhs.d_fileDesc))
+ ConsoleConnection(ConsoleConnection&& rhs) noexcept :
+ d_client(rhs.d_client), d_fileDesc(std::move(rhs.d_fileDesc))
{
}
}
#ifdef HAVE_LIBEDIT
-static string historyFile(const bool &ignoreHOME = false)
+static string historyFile(const bool& ignoreHOME = false)
{
string ret;
passwd pwd{};
- passwd *result{nullptr};
+ passwd* result{nullptr};
std::array<char, 16384> buf{};
getpwuid_r(geteuid(), &pwd, buf.data(), buf.size(), &result);
// NOLINTNEXTLINE(concurrency-mt-unsafe): we are not modifying the environment
- const char *homedir = getenv("HOME");
+ const char* homedir = getenv("HOME");
if (result != nullptr) {
ret = string(pwd.pw_dir);
}
}
#endif /* HAVE_LIBEDIT */
-enum class ConsoleCommandResult : uint8_t {
+enum class ConsoleCommandResult : uint8_t
+{
Valid = 0,
ConnectionClosed,
TooLarge
static bool putMsgLen32(int fileDesc, uint32_t len)
{
- try
- {
+ try {
uint32_t raw = htonl(len);
size_t ret = writen2(fileDesc, &raw, sizeof raw);
return ret == sizeof raw;
}
- catch(...) {
+ catch (...) {
return false;
}
}
string msg = dnsdist::crypto::authenticated::encryptSym(line, g_consoleKey, writingNonce);
const auto msgLen = msg.length();
if (msgLen > std::numeric_limits<uint32_t>::max()) {
- cerr << "Encrypted message is too long to be sent to the server, "<< std::to_string(msgLen) << " > " << std::numeric_limits<uint32_t>::max() << endl;
+ cerr << "Encrypted message is too long to be sent to the server, " << std::to_string(msgLen) << " > " << std::numeric_limits<uint32_t>::max() << endl;
return ConsoleCommandResult::TooLarge;
}
}
if (g_verbose) {
- cout<<"Connecting to "<<server.toStringWithPort()<<endl;
+ cout << "Connecting to " << server.toStringWithPort() << endl;
}
auto fileDesc = FDWrapper(socket(server.sin4.sin_family, SOCK_STREAM, 0));
if (fileDesc.getHandle() < 0) {
- cerr<<"Unable to connect to "<<server.toStringWithPort()<<endl;
+ cerr << "Unable to connect to " << server.toStringWithPort() << endl;
return;
}
SConnect(fileDesc.getHandle(), server);
having a key mismatch issue. */
auto commandResult = sendMessageToServer(fileDesc.getHandle(), "", readingNonce, writingNonce, false);
if (commandResult == ConsoleCommandResult::ConnectionClosed) {
- cerr<<"The server closed the connection right away, likely indicating a key mismatch. Please check your setKey() directive."<<endl;
+ cerr << "The server closed the connection right away, likely indicating a key mismatch. Please check your setKey() directive." << endl;
return;
}
if (commandResult == ConsoleCommandResult::TooLarge) {
string lastline;
for (;;) {
char* sline = readline("> ");
- rl_bind_key('\t',rl_complete);
+ rl_bind_key('\t', rl_complete);
if (sline == nullptr) {
break;
}
string line(sline);
if (!line.empty() && line != lastline) {
add_history(sline);
- history << sline <<endl;
+ history << sline << endl;
history.flush();
}
lastline = line;
string line(sline);
if (!line.empty() && line != lastline) {
add_history(sline);
- history << sline <<endl;
+ history << sline << endl;
history.flush();
}
string,
shared_ptr<DownstreamState>,
ClientState*,
- std::unordered_map<string, double>
- >
- >
- >(withReturn ? ("return "+*line) : *line);
+ std::unordered_map<string, double>>>>(withReturn ? ("return " + *line) : *line);
if (ret) {
if (const auto* dsValue = boost::get<shared_ptr<DownstreamState>>(&*ret)) {
if (*dsValue) {
- cout<<(*dsValue)->getName()<<endl;
+ cout << (*dsValue)->getName() << endl;
}
}
else if (const auto* csValue = boost::get<ClientState*>(&*ret)) {
if (*csValue != nullptr) {
- cout<<(*csValue)->local.toStringWithPort()<<endl;
+ cout << (*csValue)->local.toStringWithPort() << endl;
}
}
else if (const auto* strValue = boost::get<string>(&*ret)) {
- cout<<*strValue<<endl;
+ cout << *strValue << endl;
}
- else if (const auto* mapValue = boost::get<std::unordered_map<string, double> >(&*ret)) {
+ else if (const auto* mapValue = boost::get<std::unordered_map<string, double>>(&*ret)) {
using namespace json11;
Json::object obj;
for (const auto& value : *mapValue) {
obj[value.first] = value.second;
}
Json out = obj;
- cout<<out.dump()<<endl;
+ cout << out.dump() << endl;
}
}
else {
}
}
catch (const LuaContext::WrongTypeException& e) {
- std::cerr<<"Command returned an object we can't print: "<<std::string(e.what())<<std::endl;
+ std::cerr << "Command returned an object we can't print: " << std::string(e.what()) << std::endl;
// tried to return something we don't understand
}
catch (const LuaContext::ExecutionErrorException& e) {
if (strcmp(e.what(), "invalid key to 'next'") == 0) {
- std::cerr<<"Error parsing parameters, did you forget parameter name?";
+ std::cerr << "Error parsing parameters, did you forget parameter name?";
}
else {
std::cerr << e.what();
std::rethrow_if_nested(e);
std::cerr << std::endl;
- } catch (const std::exception& ne) {
+ }
+ catch (const std::exception& ne) {
// ne is the exception that was thrown from inside the lambda
std::cerr << ": " << ne.what() << std::endl;
}
#ifndef DISABLE_COMPLETION
/**** CARGO CULT CODE AHEAD ****/
-const std::vector<ConsoleKeyword> g_consoleKeywords{
+const std::vector<ConsoleKeyword> g_consoleKeywords
+{
/* keyword, function, parameters, description */
- { "addACL", true, "netmask", "add to the ACL set who can use this server" },
- { "addAction", true, R"(DNS rule, DNS action [, {uuid="UUID", name="name"}])", "add a rule" },
- { "addBPFFilterDynBlocks", true, "addresses, dynbpf[[, seconds=10], msg]", "This is the eBPF equivalent of addDynBlocks(), blocking a set of addresses for (optionally) a number of seconds, using an eBPF dynamic filter" },
- { "addCapabilitiesToRetain", true, "capability or list of capabilities", "Linux capabilities to retain after startup, like CAP_BPF" },
- { "addConsoleACL", true, "netmask", "add a netmask to the console ACL" },
- { "addDNSCryptBind", true, R"('127.0.0.1:8443", "provider name", "/path/to/resolver.cert", "/path/to/resolver.key", {reusePort=false, tcpFastOpenQueueSize=0, interface="", cpus={}})", "listen to incoming DNSCrypt queries on 127.0.0.1 port 8443, with a provider name of `provider name`, using a resolver certificate and associated key stored respectively in the `resolver.cert` and `resolver.key` files. The fifth optional parameter is a table of parameters" },
- { "addDOHLocal", true, "addr, certFile, keyFile [, urls [, vars]]", "listen to incoming DNS over HTTPS queries on the specified address using the specified certificate and key. The last two parameters are tables" },
- { "addDOH3Local", true, "addr, certFile, keyFile [, vars]", "listen to incoming DNS over HTTP/3 queries on the specified address using the specified certificate and key. The last parameter is a table" },
- { "addDOQLocal", true, "addr, certFile, keyFile [, vars]", "listen to incoming DNS over QUIC queries on the specified address using the specified certificate and key. The last parameter is a table" },
- { "addDynamicBlock", true, "address, message[, action [, seconds [, clientIPMask [, clientIPPortMask]]]]", "block the supplied address with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)" },
- { "addDynBlocks", true, "addresses, message[, seconds[, action]]", "block the set of addresses with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)" },
- { "addDynBlockSMT", true, "names, message[, seconds [, action]]", "block the set of names with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)" },
- { "addLocal", true, R"(addr [, {doTCP=true, reusePort=false, tcpFastOpenQueueSize=0, interface="", cpus={}}])", "add `addr` to the list of addresses we listen on" },
- { "addCacheHitResponseAction", true, R"(DNS rule, DNS response action [, {uuid="UUID", name="name"}}])", "add a cache hit response rule" },
- { "addCacheInsertedResponseAction", true, R"(DNS rule, DNS response action [, {uuid="UUID", name="name"}}])", "add a cache inserted response rule" },
- { "addMaintenanceCallback", true, "callback", "register a function to be called as part of the maintenance hook, every second" },
- { "addResponseAction", true, R"(DNS rule, DNS response action [, {uuid="UUID", name="name"}}])", "add a response rule" },
- { "addSelfAnsweredResponseAction", true, R"(DNS rule, DNS response action [, {uuid="UUID", name="name"}}])", "add a self-answered response rule" },
- { "addTLSLocal", true, "addr, certFile(s), keyFile(s) [,params]", "listen to incoming DNS over TLS queries on the specified address using the specified certificate (or list of) and key (or list of). The last parameter is a table" },
- { "AllowAction", true, "", "let these packets go through" },
- { "AllowResponseAction", true, "", "let these packets go through" },
- { "AllRule", true, "", "matches all traffic" },
- { "AndRule", true, "list of DNS rules", "matches if all sub-rules matches" },
- { "benchRule", true, "DNS Rule [, iterations [, suffix]]", "bench the specified DNS rule" },
- { "carbonServer", true, "serverIP, [ourname], [interval]", "report statistics to serverIP using our hostname, or 'ourname' if provided, every 'interval' seconds" },
- { "clearConsoleHistory", true, "", "clear the internal (in-memory) history of console commands" },
- { "clearDynBlocks", true, "", "clear all dynamic blocks" },
- { "clearQueryCounters", true, "", "clears the query counter buffer" },
- { "clearRules", true, "", "remove all current rules" },
- { "controlSocket", true, "addr", "open a control socket on this address / connect to this address in client mode" },
- { "ContinueAction", true, "action", "execute the specified action and continue the processing of the remaining rules, regardless of the return of the action" },
- { "declareMetric", true, "name, type, description [, prometheusName]", "Declare a custom metric" },
- { "decMetric", true, "name", "Decrement a custom metric" },
- { "DelayAction", true, "milliseconds", "delay the response by the specified amount of milliseconds (UDP-only)" },
- { "DelayResponseAction", true, "milliseconds", "delay the response by the specified amount of milliseconds (UDP-only)" },
- { "delta", true, "", "shows all commands entered that changed the configuration" },
- { "DNSSECRule", true, "", "matches queries with the DO bit set" },
- { "DnstapLogAction", true, "identity, FrameStreamLogger [, alterFunction]", "send the contents of this query to a FrameStreamLogger or RemoteLogger as dnstap. `alterFunction` is a callback, receiving a DNSQuestion and a DnstapMessage, that can be used to modify the dnstap message" },
- { "DnstapLogResponseAction", true, "identity, FrameStreamLogger [, alterFunction]", "send the contents of this response to a remote or FrameStreamLogger or RemoteLogger as dnstap. `alterFunction` is a callback, receiving a DNSResponse and a DnstapMessage, that can be used to modify the dnstap message" },
- { "DropAction", true, "", "drop these packets" },
- { "DropResponseAction", true, "", "drop these packets" },
- { "DSTPortRule", true, "port", "matches questions received to the destination port specified" },
- { "dumpStats", true, "", "print all statistics we gather" },
- { "dynBlockRulesGroup", true, "", "return a new DynBlockRulesGroup object" },
- { "EDNSVersionRule", true, "version", "matches queries with the specified EDNS version" },
- { "EDNSOptionRule", true, "optcode", "matches queries with the specified EDNS0 option present" },
- { "ERCodeAction", true, "ercode", "Reply immediately by turning the query into a response with the specified EDNS extended rcode" },
- { "ERCodeRule", true, "rcode", "matches responses with the specified extended rcode (EDNS0)" },
- { "exceedNXDOMAINs", true, "rate, seconds", "get set of addresses that exceed `rate` NXDOMAIN/s over `seconds` seconds" },
- { "exceedQRate", true, "rate, seconds", "get set of address that exceed `rate` queries/s over `seconds` seconds" },
- { "exceedQTypeRate", true, "type, rate, seconds", "get set of address that exceed `rate` queries/s for queries of type `type` over `seconds` seconds" },
- { "exceedRespByterate", true, "rate, seconds", "get set of addresses that exceeded `rate` bytes/s answers over `seconds` seconds" },
- { "exceedServFails", true, "rate, seconds", "get set of addresses that exceed `rate` servfails/s over `seconds` seconds" },
- { "firstAvailable", false, "", "picks the server with the lowest `order` that has not exceeded its QPS limit" },
- { "fixupCase", true, "bool", "if set (default to no), rewrite the first qname of the question part of the answer to match the one from the query. It is only useful when you have a downstream server that messes up the case of the question qname in the answer" },
- { "generateDNSCryptCertificate", true, R"("/path/to/providerPrivate.key", "/path/to/resolver.cert", "/path/to/resolver.key", serial, validFrom, validUntil)", "generate a new resolver private key and related certificate, valid from the `validFrom` timestamp until the `validUntil` one, signed with the provider private key" },
- { "generateDNSCryptProviderKeys", true, R"("/path/to/providerPublic.key", "/path/to/providerPrivate.key")", "generate a new provider keypair" },
- { "getAction", true, "n", "Returns the Action associated with rule n" },
- { "getBind", true, "n", "returns the listener at index n" },
- { "getBindCount", true, "", "returns the number of listeners all kinds" },
- { "getCacheHitResponseRule", true, "selector", "Return the cache-hit response rule corresponding to the selector, if any" },
- { "getCacheInsertedResponseRule", true, "selector", "Return the cache-inserted response rule corresponding to the selector, if any" },
- { "getCurrentTime", true, "", "returns the current time" },
- { "getDynamicBlocks", true, "", "returns a table of the current network-based dynamic blocks" },
- { "getDynamicBlocksSMT", true, "", "returns a table of the current suffix-based dynamic blocks" },
- { "getDNSCryptBind", true, "n", "return the `DNSCryptContext` object corresponding to the bind `n`" },
- { "getDNSCryptBindCount", true, "", "returns the number of DNSCrypt listeners" },
- { "getDOHFrontend", true, "n", "returns the DoH frontend with index n" },
- { "getDOHFrontendCount", true, "", "returns the number of DoH listeners" },
- { "getDOH3Frontend", true, "n", "returns the DoH3 frontend with index n" },
- { "getDOH3FrontendCount", true, "", "returns the number of DoH3 listeners" },
- { "getDOQFrontend", true, "n", "returns the DoQ frontend with index n" },
- { "getDOQFrontendCount", true, "", "returns the number of DoQ listeners" },
- { "getListOfAddressesOfNetworkInterface", true, "itf", "returns the list of addresses configured on a given network interface, as strings" },
- { "getListOfNetworkInterfaces", true, "", "returns the list of network interfaces present on the system, as strings" },
- { "getListOfRangesOfNetworkInterface", true, "itf", "returns the list of network ranges configured on a given network interface, as strings" },
- { "getMACAddress", true, "IP addr", "return the link-level address (MAC) corresponding to the supplied neighbour IP address, if known by the kernel" },
- { "getMetric", true, "name", "Get the value of a custom metric" },
- { "getOutgoingTLSSessionCacheSize", true, "", "returns the number of TLS sessions (for outgoing connections) currently cached" },
- { "getPool", true, "name", "return the pool named `name`, or \"\" for the default pool" },
- { "getPoolServers", true, "pool", "return servers part of this pool" },
- { "getPoolNames", true, "", "returns a table with all the pool names" },
- { "getQueryCounters", true, "[max=10]", "show current buffer of query counters, limited by 'max' if provided" },
- { "getResponseRing", true, "", "return the current content of the response ring" },
- { "getResponseRule", true, "selector", "Return the response rule corresponding to the selector, if any" },
- { "getRespRing", true, "", "return the qname/rcode content of the response ring" },
- { "getRule", true, "selector", "Return the rule corresponding to the selector, if any" },
- { "getSelfAnsweredResponseRule", true, "selector", "Return the self-answered response rule corresponding to the selector, if any" },
- { "getServer", true, "id", "returns server with index 'n' or whose uuid matches if 'id' is an UUID string" },
- { "getServers", true, "", "returns a table with all defined servers" },
- { "getStatisticsCounters", true, "", "returns a map of statistic counters" },
- { "getTopCacheHitResponseRules", true, "[top]", "return the `top` cache-hit response rules" },
- { "getTopCacheInsertedResponseRules", true, "[top]", "return the `top` cache-inserted response rules" },
- { "getTopResponseRules", true, "[top]", "return the `top` response rules" },
- { "getTopRules", true, "[top]", "return the `top` rules" },
- { "getTopSelfAnsweredResponseRules", true, "[top]", "return the `top` self-answered response rules" },
- { "getTLSContext", true, "n", "returns the TLS context with index n" },
- { "getTLSFrontend", true, "n", "returns the TLS frontend with index n" },
- { "getTLSFrontendCount", true, "", "returns the number of DoT listeners" },
- { "getVerbose", true, "", "get whether log messages at the verbose level will be logged" },
- { "grepq", true, R"(Netmask|DNS Name|100ms|{"::1", "powerdns.com", "100ms"} [, n] [,options])", "shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms" },
- { "hashPassword", true, "password [, workFactor]", "Returns a hashed and salted version of the supplied password, usable with 'setWebserverConfig()'"},
- { "HTTPHeaderRule", true, "name, regex", "matches DoH queries with a HTTP header 'name' whose content matches the regular expression 'regex'"},
- { "HTTPPathRegexRule", true, "regex", "matches DoH queries whose HTTP path matches 'regex'"},
- { "HTTPPathRule", true, "path", "matches DoH queries whose HTTP path is an exact match to 'path'"},
- { "HTTPStatusAction", true, "status, reason, body", "return an HTTP response"},
- { "inClientStartup", true, "", "returns true during console client parsing of configuration" },
- { "includeDirectory", true, "path", "include configuration files from `path`" },
- { "incMetric", true, "name", "Increment a custom metric" },
- { "KeyValueLookupKeyQName", true, "[wireFormat]", "Return a new KeyValueLookupKey object that, when passed to KeyValueStoreLookupAction or KeyValueStoreLookupRule, will return the qname of the query, either in wire format (default) or in plain text if 'wireFormat' is false" },
- { "KeyValueLookupKeySourceIP", true, "[v4Mask [, v6Mask [, includePort]]]", "Return a new KeyValueLookupKey object that, when passed to KeyValueStoreLookupAction or KeyValueStoreLookupRule, will return the (possibly bitmasked) source IP of the client in network byte-order." },
- { "KeyValueLookupKeySuffix", true, "[minLabels [,wireFormat]]", "Return a new KeyValueLookupKey object that, when passed to KeyValueStoreLookupAction or KeyValueStoreLookupRule, will return a vector of keys based on the labels of the qname in DNS wire format or plain text" },
- { "KeyValueLookupKeyTag", true, "tag", "Return a new KeyValueLookupKey object that, when passed to KeyValueStoreLookupAction or KeyValueStoreLookupRule, will return the value of the corresponding tag for this query, if it exists" },
- { "KeyValueStoreLookupAction", true, "kvs, lookupKey, destinationTag", "does a lookup into the key value store referenced by 'kvs' using the key returned by 'lookupKey', and storing the result if any into the tag named 'destinationTag'" },
- { "KeyValueStoreRangeLookupAction", true, "kvs, lookupKey, destinationTag", "does a range-based lookup into the key value store referenced by 'kvs' using the key returned by 'lookupKey', and storing the result if any into the tag named 'destinationTag'" },
- { "KeyValueStoreLookupRule", true, "kvs, lookupKey", "matches queries if the key is found in the specified Key Value store" },
- { "KeyValueStoreRangeLookupRule", true, "kvs, lookupKey", "matches queries if the key is found in the specified Key Value store" },
- { "leastOutstanding", false, "", "Send traffic to downstream server with least outstanding queries, with the lowest 'order', and within that the lowest recent latency"},
+ {"addACL", true, "netmask", "add to the ACL set who can use this server"},
+ {"addAction", true, R"(DNS rule, DNS action [, {uuid="UUID", name="name"}])", "add a rule"},
+ {"addBPFFilterDynBlocks", true, "addresses, dynbpf[[, seconds=10], msg]", "This is the eBPF equivalent of addDynBlocks(), blocking a set of addresses for (optionally) a number of seconds, using an eBPF dynamic filter"},
+ {"addCapabilitiesToRetain", true, "capability or list of capabilities", "Linux capabilities to retain after startup, like CAP_BPF"},
+ {"addConsoleACL", true, "netmask", "add a netmask to the console ACL"},
+ {"addDNSCryptBind", true, R"('127.0.0.1:8443", "provider name", "/path/to/resolver.cert", "/path/to/resolver.key", {reusePort=false, tcpFastOpenQueueSize=0, interface="", cpus={}})", "listen to incoming DNSCrypt queries on 127.0.0.1 port 8443, with a provider name of `provider name`, using a resolver certificate and associated key stored respectively in the `resolver.cert` and `resolver.key` files. The fifth optional parameter is a table of parameters"},
+ {"addDOHLocal", true, "addr, certFile, keyFile [, urls [, vars]]", "listen to incoming DNS over HTTPS queries on the specified address using the specified certificate and key. The last two parameters are tables"},
+ {"addDOH3Local", true, "addr, certFile, keyFile [, vars]", "listen to incoming DNS over HTTP/3 queries on the specified address using the specified certificate and key. The last parameter is a table"},
+ {"addDOQLocal", true, "addr, certFile, keyFile [, vars]", "listen to incoming DNS over QUIC queries on the specified address using the specified certificate and key. The last parameter is a table"},
+ {"addDynamicBlock", true, "address, message[, action [, seconds [, clientIPMask [, clientIPPortMask]]]]", "block the supplied address with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)"},
+ {"addDynBlocks", true, "addresses, message[, seconds[, action]]", "block the set of addresses with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)"},
+ {"addDynBlockSMT", true, "names, message[, seconds [, action]]", "block the set of names with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)"},
+ {"addLocal", true, R"(addr [, {doTCP=true, reusePort=false, tcpFastOpenQueueSize=0, interface="", cpus={}}])", "add `addr` to the list of addresses we listen on"},
+ {"addCacheHitResponseAction", true, R"(DNS rule, DNS response action [, {uuid="UUID", name="name"}}])", "add a cache hit response rule"},
+ {"addCacheInsertedResponseAction", true, R"(DNS rule, DNS response action [, {uuid="UUID", name="name"}}])", "add a cache inserted response rule"},
+ {"addMaintenanceCallback", true, "callback", "register a function to be called as part of the maintenance hook, every second"},
+ {"addResponseAction", true, R"(DNS rule, DNS response action [, {uuid="UUID", name="name"}}])", "add a response rule"},
+ {"addSelfAnsweredResponseAction", true, R"(DNS rule, DNS response action [, {uuid="UUID", name="name"}}])", "add a self-answered response rule"},
+ {"addTLSLocal", true, "addr, certFile(s), keyFile(s) [,params]", "listen to incoming DNS over TLS queries on the specified address using the specified certificate (or list of) and key (or list of). The last parameter is a table"},
+ {"AllowAction", true, "", "let these packets go through"},
+ {"AllowResponseAction", true, "", "let these packets go through"},
+ {"AllRule", true, "", "matches all traffic"},
+ {"AndRule", true, "list of DNS rules", "matches if all sub-rules matches"},
+ {"benchRule", true, "DNS Rule [, iterations [, suffix]]", "bench the specified DNS rule"},
+ {"carbonServer", true, "serverIP, [ourname], [interval]", "report statistics to serverIP using our hostname, or 'ourname' if provided, every 'interval' seconds"},
+ {"clearConsoleHistory", true, "", "clear the internal (in-memory) history of console commands"},
+ {"clearDynBlocks", true, "", "clear all dynamic blocks"},
+ {"clearQueryCounters", true, "", "clears the query counter buffer"},
+ {"clearRules", true, "", "remove all current rules"},
+ {"controlSocket", true, "addr", "open a control socket on this address / connect to this address in client mode"},
+ {"ContinueAction", true, "action", "execute the specified action and continue the processing of the remaining rules, regardless of the return of the action"},
+ {"declareMetric", true, "name, type, description [, prometheusName]", "Declare a custom metric"},
+ {"decMetric", true, "name", "Decrement a custom metric"},
+ {"DelayAction", true, "milliseconds", "delay the response by the specified amount of milliseconds (UDP-only)"},
+ {"DelayResponseAction", true, "milliseconds", "delay the response by the specified amount of milliseconds (UDP-only)"},
+ {"delta", true, "", "shows all commands entered that changed the configuration"},
+ {"DNSSECRule", true, "", "matches queries with the DO bit set"},
+ {"DnstapLogAction", true, "identity, FrameStreamLogger [, alterFunction]", "send the contents of this query to a FrameStreamLogger or RemoteLogger as dnstap. `alterFunction` is a callback, receiving a DNSQuestion and a DnstapMessage, that can be used to modify the dnstap message"},
+ {"DnstapLogResponseAction", true, "identity, FrameStreamLogger [, alterFunction]", "send the contents of this response to a remote or FrameStreamLogger or RemoteLogger as dnstap. `alterFunction` is a callback, receiving a DNSResponse and a DnstapMessage, that can be used to modify the dnstap message"},
+ {"DropAction", true, "", "drop these packets"},
+ {"DropResponseAction", true, "", "drop these packets"},
+ {"DSTPortRule", true, "port", "matches questions received to the destination port specified"},
+ {"dumpStats", true, "", "print all statistics we gather"},
+ {"dynBlockRulesGroup", true, "", "return a new DynBlockRulesGroup object"},
+ {"EDNSVersionRule", true, "version", "matches queries with the specified EDNS version"},
+ {"EDNSOptionRule", true, "optcode", "matches queries with the specified EDNS0 option present"},
+ {"ERCodeAction", true, "ercode", "Reply immediately by turning the query into a response with the specified EDNS extended rcode"},
+ {"ERCodeRule", true, "rcode", "matches responses with the specified extended rcode (EDNS0)"},
+ {"exceedNXDOMAINs", true, "rate, seconds", "get set of addresses that exceed `rate` NXDOMAIN/s over `seconds` seconds"},
+ {"exceedQRate", true, "rate, seconds", "get set of address that exceed `rate` queries/s over `seconds` seconds"},
+ {"exceedQTypeRate", true, "type, rate, seconds", "get set of address that exceed `rate` queries/s for queries of type `type` over `seconds` seconds"},
+ {"exceedRespByterate", true, "rate, seconds", "get set of addresses that exceeded `rate` bytes/s answers over `seconds` seconds"},
+ {"exceedServFails", true, "rate, seconds", "get set of addresses that exceed `rate` servfails/s over `seconds` seconds"},
+ {"firstAvailable", false, "", "picks the server with the lowest `order` that has not exceeded its QPS limit"},
+ {"fixupCase", true, "bool", "if set (default to no), rewrite the first qname of the question part of the answer to match the one from the query. It is only useful when you have a downstream server that messes up the case of the question qname in the answer"},
+ {"generateDNSCryptCertificate", true, R"("/path/to/providerPrivate.key", "/path/to/resolver.cert", "/path/to/resolver.key", serial, validFrom, validUntil)", "generate a new resolver private key and related certificate, valid from the `validFrom` timestamp until the `validUntil` one, signed with the provider private key"},
+ {"generateDNSCryptProviderKeys", true, R"("/path/to/providerPublic.key", "/path/to/providerPrivate.key")", "generate a new provider keypair"},
+ {"getAction", true, "n", "Returns the Action associated with rule n"},
+ {"getBind", true, "n", "returns the listener at index n"},
+ {"getBindCount", true, "", "returns the number of listeners all kinds"},
+ {"getCacheHitResponseRule", true, "selector", "Return the cache-hit response rule corresponding to the selector, if any"},
+ {"getCacheInsertedResponseRule", true, "selector", "Return the cache-inserted response rule corresponding to the selector, if any"},
+ {"getCurrentTime", true, "", "returns the current time"},
+ {"getDynamicBlocks", true, "", "returns a table of the current network-based dynamic blocks"},
+ {"getDynamicBlocksSMT", true, "", "returns a table of the current suffix-based dynamic blocks"},
+ {"getDNSCryptBind", true, "n", "return the `DNSCryptContext` object corresponding to the bind `n`"},
+ {"getDNSCryptBindCount", true, "", "returns the number of DNSCrypt listeners"},
+ {"getDOHFrontend", true, "n", "returns the DoH frontend with index n"},
+ {"getDOHFrontendCount", true, "", "returns the number of DoH listeners"},
+ {"getDOH3Frontend", true, "n", "returns the DoH3 frontend with index n"},
+ {"getDOH3FrontendCount", true, "", "returns the number of DoH3 listeners"},
+ {"getDOQFrontend", true, "n", "returns the DoQ frontend with index n"},
+ {"getDOQFrontendCount", true, "", "returns the number of DoQ listeners"},
+ {"getListOfAddressesOfNetworkInterface", true, "itf", "returns the list of addresses configured on a given network interface, as strings"},
+ {"getListOfNetworkInterfaces", true, "", "returns the list of network interfaces present on the system, as strings"},
+ {"getListOfRangesOfNetworkInterface", true, "itf", "returns the list of network ranges configured on a given network interface, as strings"},
+ {"getMACAddress", true, "IP addr", "return the link-level address (MAC) corresponding to the supplied neighbour IP address, if known by the kernel"},
+ {"getMetric", true, "name", "Get the value of a custom metric"},
+ {"getOutgoingTLSSessionCacheSize", true, "", "returns the number of TLS sessions (for outgoing connections) currently cached"},
+ {"getPool", true, "name", "return the pool named `name`, or \"\" for the default pool"},
+ {"getPoolServers", true, "pool", "return servers part of this pool"},
+ {"getPoolNames", true, "", "returns a table with all the pool names"},
+ {"getQueryCounters", true, "[max=10]", "show current buffer of query counters, limited by 'max' if provided"},
+ {"getResponseRing", true, "", "return the current content of the response ring"},
+ {"getResponseRule", true, "selector", "Return the response rule corresponding to the selector, if any"},
+ {"getRespRing", true, "", "return the qname/rcode content of the response ring"},
+ {"getRule", true, "selector", "Return the rule corresponding to the selector, if any"},
+ {"getSelfAnsweredResponseRule", true, "selector", "Return the self-answered response rule corresponding to the selector, if any"},
+ {"getServer", true, "id", "returns server with index 'n' or whose uuid matches if 'id' is an UUID string"},
+ {"getServers", true, "", "returns a table with all defined servers"},
+ {"getStatisticsCounters", true, "", "returns a map of statistic counters"},
+ {"getTopCacheHitResponseRules", true, "[top]", "return the `top` cache-hit response rules"},
+ {"getTopCacheInsertedResponseRules", true, "[top]", "return the `top` cache-inserted response rules"},
+ {"getTopResponseRules", true, "[top]", "return the `top` response rules"},
+ {"getTopRules", true, "[top]", "return the `top` rules"},
+ {"getTopSelfAnsweredResponseRules", true, "[top]", "return the `top` self-answered response rules"},
+ {"getTLSContext", true, "n", "returns the TLS context with index n"},
+ {"getTLSFrontend", true, "n", "returns the TLS frontend with index n"},
+ {"getTLSFrontendCount", true, "", "returns the number of DoT listeners"},
+ {"getVerbose", true, "", "get whether log messages at the verbose level will be logged"},
+ {"grepq", true, R"(Netmask|DNS Name|100ms|{"::1", "powerdns.com", "100ms"} [, n] [,options])", "shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms"},
+ {"hashPassword", true, "password [, workFactor]", "Returns a hashed and salted version of the supplied password, usable with 'setWebserverConfig()'"},
+ {"HTTPHeaderRule", true, "name, regex", "matches DoH queries with a HTTP header 'name' whose content matches the regular expression 'regex'"},
+ {"HTTPPathRegexRule", true, "regex", "matches DoH queries whose HTTP path matches 'regex'"},
+ {"HTTPPathRule", true, "path", "matches DoH queries whose HTTP path is an exact match to 'path'"},
+ {"HTTPStatusAction", true, "status, reason, body", "return an HTTP response"},
+ {"inClientStartup", true, "", "returns true during console client parsing of configuration"},
+ {"includeDirectory", true, "path", "include configuration files from `path`"},
+ {"incMetric", true, "name", "Increment a custom metric"},
+ {"KeyValueLookupKeyQName", true, "[wireFormat]", "Return a new KeyValueLookupKey object that, when passed to KeyValueStoreLookupAction or KeyValueStoreLookupRule, will return the qname of the query, either in wire format (default) or in plain text if 'wireFormat' is false"},
+ {"KeyValueLookupKeySourceIP", true, "[v4Mask [, v6Mask [, includePort]]]", "Return a new KeyValueLookupKey object that, when passed to KeyValueStoreLookupAction or KeyValueStoreLookupRule, will return the (possibly bitmasked) source IP of the client in network byte-order."},
+ {"KeyValueLookupKeySuffix", true, "[minLabels [,wireFormat]]", "Return a new KeyValueLookupKey object that, when passed to KeyValueStoreLookupAction or KeyValueStoreLookupRule, will return a vector of keys based on the labels of the qname in DNS wire format or plain text"},
+ {"KeyValueLookupKeyTag", true, "tag", "Return a new KeyValueLookupKey object that, when passed to KeyValueStoreLookupAction or KeyValueStoreLookupRule, will return the value of the corresponding tag for this query, if it exists"},
+ {"KeyValueStoreLookupAction", true, "kvs, lookupKey, destinationTag", "does a lookup into the key value store referenced by 'kvs' using the key returned by 'lookupKey', and storing the result if any into the tag named 'destinationTag'"},
+ {"KeyValueStoreRangeLookupAction", true, "kvs, lookupKey, destinationTag", "does a range-based lookup into the key value store referenced by 'kvs' using the key returned by 'lookupKey', and storing the result if any into the tag named 'destinationTag'"},
+ {"KeyValueStoreLookupRule", true, "kvs, lookupKey", "matches queries if the key is found in the specified Key Value store"},
+ {"KeyValueStoreRangeLookupRule", true, "kvs, lookupKey", "matches queries if the key is found in the specified Key Value store"},
+ {"leastOutstanding", false, "", "Send traffic to downstream server with least outstanding queries, with the lowest 'order', and within that the lowest recent latency"},
#if defined(HAVE_LIBSSL) && !defined(HAVE_TLS_PROVIDERS)
- { "loadTLSEngine", true, "engineName [, defaultString]", "Load the OpenSSL engine named 'engineName', setting the engine default string to 'defaultString' if supplied"},
+ {"loadTLSEngine", true, "engineName [, defaultString]", "Load the OpenSSL engine named 'engineName', setting the engine default string to 'defaultString' if supplied"},
#endif
#if defined(HAVE_LIBSSL) && OPENSSL_VERSION_MAJOR >= 3 && defined(HAVE_TLS_PROVIDERS)
- { "loadTLSProvider", true, "providerName", "Load the OpenSSL provider named 'providerName'"},
+ {"loadTLSProvider", true, "providerName", "Load the OpenSSL provider named 'providerName'"},
#endif
- { "LogAction", true, "[filename], [binary], [append], [buffered]", "Log a line for each query, to the specified file if any, to the console (require verbose) otherwise. When logging to a file, the `binary` optional parameter specifies whether we log in binary form (default) or in textual form, the `append` optional parameter specifies whether we open the file for appending or truncate each time (default), and the `buffered` optional parameter specifies whether writes to the file are buffered (default) or not." },
- { "LogResponseAction", true, "[filename], [append], [buffered]", "Log a line for each response, to the specified file if any, to the console (require verbose) otherwise. The `append` optional parameter specifies whether we open the file for appending or truncate each time (default), and the `buffered` optional parameter specifies whether writes to the file are buffered (default) or not." },
- { "LuaAction", true, "function", "Invoke a Lua function that accepts a DNSQuestion" },
- { "LuaFFIAction", true, "function", "Invoke a Lua FFI function that accepts a DNSQuestion" },
- { "LuaFFIPerThreadAction", true, "function", "Invoke a Lua FFI function that accepts a DNSQuestion, with a per-thread Lua context" },
- { "LuaFFIPerThreadResponseAction", true, "function", "Invoke a Lua FFI function that accepts a DNSResponse, with a per-thread Lua context" },
- { "LuaFFIResponseAction", true, "function", "Invoke a Lua FFI function that accepts a DNSResponse" },
- { "LuaFFIRule", true, "function", "Invoke a Lua FFI function that filters DNS questions" },
- { "LuaResponseAction", true, "function", "Invoke a Lua function that accepts a DNSResponse" },
- { "LuaRule", true, "function", "Invoke a Lua function that filters DNS questions" },
+ {"LogAction", true, "[filename], [binary], [append], [buffered]", "Log a line for each query, to the specified file if any, to the console (require verbose) otherwise. When logging to a file, the `binary` optional parameter specifies whether we log in binary form (default) or in textual form, the `append` optional parameter specifies whether we open the file for appending or truncate each time (default), and the `buffered` optional parameter specifies whether writes to the file are buffered (default) or not."},
+ {"LogResponseAction", true, "[filename], [append], [buffered]", "Log a line for each response, to the specified file if any, to the console (require verbose) otherwise. The `append` optional parameter specifies whether we open the file for appending or truncate each time (default), and the `buffered` optional parameter specifies whether writes to the file are buffered (default) or not."},
+ {"LuaAction", true, "function", "Invoke a Lua function that accepts a DNSQuestion"},
+ {"LuaFFIAction", true, "function", "Invoke a Lua FFI function that accepts a DNSQuestion"},
+ {"LuaFFIPerThreadAction", true, "function", "Invoke a Lua FFI function that accepts a DNSQuestion, with a per-thread Lua context"},
+ {"LuaFFIPerThreadResponseAction", true, "function", "Invoke a Lua FFI function that accepts a DNSResponse, with a per-thread Lua context"},
+ {"LuaFFIResponseAction", true, "function", "Invoke a Lua FFI function that accepts a DNSResponse"},
+ {"LuaFFIRule", true, "function", "Invoke a Lua FFI function that filters DNS questions"},
+ {"LuaResponseAction", true, "function", "Invoke a Lua function that accepts a DNSResponse"},
+ {"LuaRule", true, "function", "Invoke a Lua function that filters DNS questions"},
#ifdef HAVE_IPCIPHER
- { "makeIPCipherKey", true, "password", "generates a 16-byte key that can be used to pseudonymize IP addresses with IP cipher" },
+ {"makeIPCipherKey", true, "password", "generates a 16-byte key that can be used to pseudonymize IP addresses with IP cipher"},
#endif /* HAVE_IPCIPHER */
- { "makeKey", true, "", "generate a new server access key, emit configuration line ready for pasting" },
- { "makeRule", true, "rule", "Make a NetmaskGroupRule() or a SuffixMatchNodeRule(), depending on how it is called" } ,
- { "MaxQPSIPRule", true, "qps, [v4Mask=32 [, v6Mask=64 [, burst=qps [, expiration=300 [, cleanupDelay=60 [, scanFraction=10 [, shards=10]]]]]]]", "matches traffic exceeding the qps limit per subnet" },
- { "MaxQPSRule", true, "qps", "matches traffic **not** exceeding this qps limit" },
- { "mvCacheHitResponseRule", true, "from, to", "move cache hit response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" },
- { "mvCacheHitResponseRuleToTop", true, "", "move the last cache hit response rule to the first position" },
- { "mvCacheInsertedResponseRule", true, "from, to", "move cache inserted response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" },
- { "mvCacheInsertedResponseRuleToTop", true, "", "move the last cache inserted response rule to the first position" },
- { "mvResponseRule", true, "from, to", "move response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" },
- { "mvResponseRuleToTop", true, "", "move the last response rule to the first position" },
- { "mvRule", true, "from, to", "move rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule, in which case the rule will be moved to the last position" },
- { "mvRuleToTop", true, "", "move the last rule to the first position" },
- { "mvSelfAnsweredResponseRule", true, "from, to", "move self-answered response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" },
- { "mvSelfAnsweredResponseRuleToTop", true, "", "move the last self-answered response rule to the first position" },
- { "NetmaskGroupRule", true, "nmg[, src]", "Matches traffic from/to the network range specified in nmg. Set the src parameter to false to match nmg against destination address instead of source address. This can be used to differentiate between clients" },
- { "newBPFFilter", true, "{ipv4MaxItems=int, ipv4PinnedPath=string, ipv6MaxItems=int, ipv6PinnedPath=string, cidr4MaxItems=int, cidr4PinnedPath=string, cidr6MaxItems=int, cidr6PinnedPath=string, qnamesMaxItems=int, qnamesPinnedPath=string, external=bool}", "Return a new eBPF socket filter with specified options." },
- { "newCA", true, "address", "Returns a ComboAddress based on `address`" },
+ {"makeKey", true, "", "generate a new server access key, emit configuration line ready for pasting"},
+ {"makeRule", true, "rule", "Make a NetmaskGroupRule() or a SuffixMatchNodeRule(), depending on how it is called"},
+ {"MaxQPSIPRule", true, "qps, [v4Mask=32 [, v6Mask=64 [, burst=qps [, expiration=300 [, cleanupDelay=60 [, scanFraction=10 [, shards=10]]]]]]]", "matches traffic exceeding the qps limit per subnet"},
+ {"MaxQPSRule", true, "qps", "matches traffic **not** exceeding this qps limit"},
+ {"mvCacheHitResponseRule", true, "from, to", "move cache hit response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule"},
+ {"mvCacheHitResponseRuleToTop", true, "", "move the last cache hit response rule to the first position"},
+ {"mvCacheInsertedResponseRule", true, "from, to", "move cache inserted response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule"},
+ {"mvCacheInsertedResponseRuleToTop", true, "", "move the last cache inserted response rule to the first position"},
+ {"mvResponseRule", true, "from, to", "move response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule"},
+ {"mvResponseRuleToTop", true, "", "move the last response rule to the first position"},
+ {"mvRule", true, "from, to", "move rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule, in which case the rule will be moved to the last position"},
+ {"mvRuleToTop", true, "", "move the last rule to the first position"},
+ {"mvSelfAnsweredResponseRule", true, "from, to", "move self-answered response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule"},
+ {"mvSelfAnsweredResponseRuleToTop", true, "", "move the last self-answered response rule to the first position"},
+ {"NetmaskGroupRule", true, "nmg[, src]", "Matches traffic from/to the network range specified in nmg. Set the src parameter to false to match nmg against destination address instead of source address. This can be used to differentiate between clients"},
+ {"newBPFFilter", true, "{ipv4MaxItems=int, ipv4PinnedPath=string, ipv6MaxItems=int, ipv6PinnedPath=string, cidr4MaxItems=int, cidr4PinnedPath=string, cidr6MaxItems=int, cidr6PinnedPath=string, qnamesMaxItems=int, qnamesPinnedPath=string, external=bool}", "Return a new eBPF socket filter with specified options."},
+ {"newCA", true, "address", "Returns a ComboAddress based on `address`"},
#ifdef HAVE_CDB
- { "newCDBKVStore", true, "fname, refreshDelay", "Return a new KeyValueStore object associated to the corresponding CDB database" },
+ {"newCDBKVStore", true, "fname, refreshDelay", "Return a new KeyValueStore object associated to the corresponding CDB database"},
#endif
- { "newDNSName", true, "name", "make a DNSName based on this .-terminated name" },
- { "newDNSNameSet", true, "", "returns a new DNSNameSet" },
- { "newDynBPFFilter", true, "bpf", "Return a new dynamic eBPF filter associated to a given BPF Filter" },
- { "newFrameStreamTcpLogger", true, "addr [, options]", "create a FrameStream logger object writing to a TCP address (addr should be ip:port), to use with `DnstapLogAction()` and `DnstapLogResponseAction()`" },
- { "newFrameStreamUnixLogger", true, "socket [, options]", "create a FrameStream logger object writing to a local unix socket, to use with `DnstapLogAction()` and `DnstapLogResponseAction()`" },
+ {"newDNSName", true, "name", "make a DNSName based on this .-terminated name"},
+ {"newDNSNameSet", true, "", "returns a new DNSNameSet"},
+ {"newDynBPFFilter", true, "bpf", "Return a new dynamic eBPF filter associated to a given BPF Filter"},
+ {"newFrameStreamTcpLogger", true, "addr [, options]", "create a FrameStream logger object writing to a TCP address (addr should be ip:port), to use with `DnstapLogAction()` and `DnstapLogResponseAction()`"},
+ {"newFrameStreamUnixLogger", true, "socket [, options]", "create a FrameStream logger object writing to a local unix socket, to use with `DnstapLogAction()` and `DnstapLogResponseAction()`"},
#ifdef HAVE_LMDB
- { "newLMDBKVStore", true, "fname, dbName [, noLock]", "Return a new KeyValueStore object associated to the corresponding LMDB database" },
+ {"newLMDBKVStore", true, "fname, dbName [, noLock]", "Return a new KeyValueStore object associated to the corresponding LMDB database"},
#endif
- { "newNMG", true, "", "Returns a NetmaskGroup" },
- { "newPacketCache", true, "maxEntries[, maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=true, options={}]", "return a new Packet Cache" },
- { "newQPSLimiter", true, "rate, burst", "configure a QPS limiter with that rate and that burst capacity" },
- { "newRemoteLogger", true, "address:port [, timeout=2, maxQueuedEntries=100, reconnectWaitTime=1]", "create a Remote Logger object, to use with `RemoteLogAction()` and `RemoteLogResponseAction()`" },
- { "newRuleAction", true, R"(DNS rule, DNS action [, {uuid="UUID", name="name"}])", "return a pair of DNS Rule and DNS Action, to be used with `setRules()`" },
- { "newServer", true, R"({address="ip:port", qps=1000, order=1, weight=10, pool="abuse", retries=5, tcpConnectTimeout=5, tcpSendTimeout=30, tcpRecvTimeout=30, checkName="a.root-servers.net.", checkType="A", maxCheckFailures=1, mustResolve=false, useClientSubnet=true, source="address|interface name|address@interface", sockets=1, reconnectOnUp=false})", "instantiate a server" },
- { "newServerPolicy", true, "name, function", "create a policy object from a Lua function" },
- { "newSuffixMatchNode", true, "", "returns a new SuffixMatchNode" },
- { "newSVCRecordParameters", true, "priority, target, mandatoryParams, alpns, noDefaultAlpn [, port [, ech [, ipv4hints [, ipv6hints [, additionalParameters ]]]]]", "return a new SVCRecordParameters object, to use with SpoofSVCAction" },
- { "NegativeAndSOAAction", true, "nxd, zone, ttl, mname, rname, serial, refresh, retry, expire, minimum [, options]", "Turn a query into a NXDomain or NoData answer and sets a SOA record in the additional section" },
- { "NoneAction", true, "", "Does nothing. Subsequent rules are processed after this action" },
- { "NotRule", true, "selector", "Matches the traffic if the selector rule does not match" },
- { "OpcodeRule", true, "code", "Matches queries with opcode code. code can be directly specified as an integer, or one of the built-in DNSOpcodes" },
- { "OrRule", true, "selectors", "Matches the traffic if one or more of the the selectors rules does match" },
- { "PoolAction", true, "poolname [, stop]", "set the packet into the specified pool" },
- { "PoolAvailableRule", true, "poolname", "Check whether a pool has any servers available to handle queries" },
- { "PoolOutstandingRule", true, "poolname, limit", "Check whether a pool has outstanding queries above limit" },
- { "printDNSCryptProviderFingerprint", true, R"("/path/to/providerPublic.key")", "display the fingerprint of the provided resolver public key" },
- { "ProbaRule", true, "probability", "Matches queries with a given probability. 1.0 means always" },
- { "ProxyProtocolValueRule", true, "type [, value]", "matches queries with a specified Proxy Protocol TLV value of that type, optionally matching the content of the option as well" },
- { "QClassRule", true, "qclass", "Matches queries with the specified qclass. class can be specified as an integer or as one of the built-in DNSClass" },
- { "QNameLabelsCountRule", true, "min, max", "matches if the qname has less than `min` or more than `max` labels" },
- { "QNameRule", true, "qname", "matches queries with the specified qname" },
- { "QNameSetRule", true, "set", "Matches if the set contains exact qname" },
- { "QNameWireLengthRule", true, "min, max", "matches if the qname's length on the wire is less than `min` or more than `max` bytes" },
- { "QPSAction", true, "maxqps", "Drop a packet if it does exceed the maxqps queries per second limits. Letting the subsequent rules apply otherwise" },
- { "QPSPoolAction", true, "maxqps, poolname [, stop]", "Send the packet into the specified pool only if it does not exceed the maxqps queries per second limits. Letting the subsequent rules apply otherwise" },
- { "QTypeRule", true, "qtype", "matches queries with the specified qtype" },
- { "RCodeAction", true, "rcode", "Reply immediately by turning the query into a response with the specified rcode" },
- { "RCodeRule", true, "rcode", "matches responses with the specified rcode" },
- { "RDRule", true, "", "Matches queries with the RD flag set" },
- { "RecordsCountRule", true, "section, minCount, maxCount", "Matches if there is at least minCount and at most maxCount records in the section section. section can be specified as an integer or as a DNS Packet Sections" },
- { "RecordsTypeCountRule", true, "section, qtype, minCount, maxCount", "Matches if there is at least minCount and at most maxCount records of type type in the section section" },
- { "RegexRule", true, "regex", "matches the query name against the supplied regex" },
- { "registerDynBPFFilter", true, "DynBPFFilter", "register this dynamic BPF filter into the web interface so that its counters are displayed" },
- { "reloadAllCertificates", true, "", "reload all DNSCrypt and TLS certificates, along with their associated keys" },
- { "RemoteLogAction", true, "RemoteLogger [, alterFunction [, serverID]]", "send the content of this query to a remote logger via Protocol Buffer. `alterFunction` is a callback, receiving a DNSQuestion and a DNSDistProtoBufMessage, that can be used to modify the Protocol Buffer content, for example for anonymization purposes. `serverID` is the server identifier." },
- { "RemoteLogResponseAction", true, "RemoteLogger [,alterFunction [,includeCNAME [, serverID]]]", "send the content of this response to a remote logger via Protocol Buffer. `alterFunction` is the same callback than the one in `RemoteLogAction` and `includeCNAME` indicates whether CNAME records inside the response should be parsed and exported. The default is to only exports A and AAAA records. `serverID` is the server identifier." },
- { "requestTCPStatesDump", true, "", "Request a dump of the TCP states (incoming connections, outgoing connections) during the next scan. Useful for debugging purposes only" },
- { "rmACL", true, "netmask", "remove netmask from ACL" },
- { "rmCacheHitResponseRule", true, "id", "remove cache hit response rule in position 'id', or whose uuid matches if 'id' is an UUID string, or finally whose name matches if 'id' is a string but not a valid UUID" },
- { "rmCacheInsertedResponseRule", true, "id", "remove cache inserted response rule in position 'id', or whose uuid matches if 'id' is an UUID string, or finally whose name matches if 'id' is a string but not a valid UUID" },
- { "rmResponseRule", true, "id", "remove response rule in position 'id', or whose uuid matches if 'id' is an UUID string, or finally whose name matches if 'id' is a string but not a valid UUID" },
- { "rmRule", true, "id", "remove rule in position 'id', or whose uuid matches if 'id' is an UUID string, or finally whose name matches if 'id' is a string but not a valid UUID" },
- { "rmSelfAnsweredResponseRule", true, "id", "remove self-answered response rule in position 'id', or whose uuid matches if 'id' is an UUID string, or finally whose name matches if 'id' is a string but not a valid UUID" },
- { "rmServer", true, "id", "remove server with index 'id' or whose uuid matches if 'id' is an UUID string" },
- { "roundrobin", false, "", "Simple round robin over available servers" },
- { "sendCustomTrap", true, "str", "send a custom `SNMP` trap from Lua, containing the `str` string"},
- { "setACL", true, "{netmask, netmask}", "replace the ACL set with these netmasks. Use `setACL({})` to reset the list, meaning no one can use us" },
- { "setACLFromFile", true, "file", "replace the ACL set with netmasks in this file" },
- { "setAddEDNSToSelfGeneratedResponses", true, "add", "set whether to add EDNS to self-generated responses, provided that the initial query had EDNS" },
- { "setAllowEmptyResponse", true, "allow", "Set to true (defaults to false) to allow empty responses (qdcount=0) with a NoError or NXDomain rcode (default) from backends" },
- { "setAPIWritable", true, "bool, dir", "allow modifications via the API. if `dir` is set, it must be a valid directory where the configuration files will be written by the API" },
- { "setCacheCleaningDelay", true, "num", "Set the interval in seconds between two runs of the cache cleaning algorithm, removing expired entries" },
- { "setCacheCleaningPercentage", true, "num", "Set the percentage of the cache that the cache cleaning algorithm will try to free by removing expired entries. By default (100), all expired entries are remove" },
- { "setConsistentHashingBalancingFactor", true, "factor", "Set the balancing factor for bounded-load consistent hashing" },
- { "setConsoleACL", true, "{netmask, netmask}", "replace the console ACL set with these netmasks" },
- { "setConsoleConnectionsLogging", true, "enabled", "whether to log the opening and closing of console connections" },
- { "setConsoleMaximumConcurrentConnections", true, "max", "Set the maximum number of concurrent console connections" },
- { "setConsoleOutputMaxMsgSize", true, "messageSize", "set console message maximum size in bytes, default is 10 MB" },
- { "setDefaultBPFFilter", true, "filter", "When used at configuration time, the corresponding BPFFilter will be attached to every bind" },
- { "setDoHDownstreamCleanupInterval", true, "interval", "minimum interval in seconds between two cleanups of the idle DoH downstream connections" },
- { "setDoHDownstreamMaxIdleTime", true, "time", "Maximum time in seconds that a downstream DoH connection to a backend might stay idle" },
- { "setDynBlocksAction", true, "action", "set which action is performed when a query is blocked. Only DNSAction.Drop (the default) and DNSAction.Refused are supported" },
- { "setDynBlocksPurgeInterval", true, "sec", "set how often the expired dynamic block entries should be removed" },
- { "setDropEmptyQueries", true, "drop", "Whether to drop empty queries right away instead of sending a NOTIMP response" },
- { "setECSOverride", true, "bool", "whether to override an existing EDNS Client Subnet value in the query" },
- { "setECSSourcePrefixV4", true, "prefix-length", "the EDNS Client Subnet prefix-length used for IPv4 queries" },
- { "setECSSourcePrefixV6", true, "prefix-length", "the EDNS Client Subnet prefix-length used for IPv6 queries" },
- { "setKey", true, "key", "set access key to that key" },
- { "setLocal", true, R"(addr [, {doTCP=true, reusePort=false, tcpFastOpenQueueSize=0, interface="", cpus={}}])", "reset the list of addresses we listen on to this address" },
- { "setMaxCachedDoHConnectionsPerDownstream", true, "max", "Set the maximum number of inactive DoH connections to a backend cached by each worker DoH thread" },
- { "setMaxCachedTCPConnectionsPerDownstream", true, "max", "Set the maximum number of inactive TCP connections to a backend cached by each worker TCP thread" },
- { "setMaxTCPClientThreads", true, "n", "set the maximum of TCP client threads, handling TCP connections" },
- { "setMaxTCPConnectionDuration", true, "n", "set the maximum duration of an incoming TCP connection, in seconds. 0 means unlimited" },
- { "setMaxTCPConnectionsPerClient", true, "n", "set the maximum number of TCP connections per client. 0 means unlimited" },
- { "setMaxTCPQueriesPerConnection", true, "n", "set the maximum number of queries in an incoming TCP connection. 0 means unlimited" },
- { "setMaxTCPQueuedConnections", true, "n", "set the maximum number of TCP connections queued (waiting to be picked up by a client thread)" },
- { "setMaxUDPOutstanding", true, "n", "set the maximum number of outstanding UDP queries to a given backend server. This can only be set at configuration time and defaults to 65535" },
- { "setMetric", true, "name, value", "Set the value of a custom metric to the supplied value" },
- { "setPayloadSizeOnSelfGeneratedAnswers", true, "payloadSize", "set the UDP payload size advertised via EDNS on self-generated responses" },
- { "setPoolServerPolicy", true, "policy, pool", "set the server selection policy for this pool to that policy" },
- { "setPoolServerPolicyLua", true, "name, function, pool", "set the server selection policy for this pool to one named 'name' and provided by 'function'" },
- { "setPoolServerPolicyLuaFFI", true, "name, function, pool", "set the server selection policy for this pool to one named 'name' and provided by 'function'" },
- { "setPoolServerPolicyLuaFFIPerThread", true, "name, code", "set server selection policy for this pool to one named 'name' and returned by the Lua FFI code passed in 'code'" },
- { "setProxyProtocolACL", true, "{netmask, netmask}", "Set the netmasks who are allowed to send Proxy Protocol headers in front of queries/connections" },
- { "setProxyProtocolApplyACLToProxiedClients", true, "apply", "Whether the general ACL should be applied to the source IP address gathered from a Proxy Protocol header, in addition to being first applied to the source address seen by dnsdist" },
- { "setProxyProtocolMaximumPayloadSize", true, "max", "Set the maximum size of a Proxy Protocol payload, in bytes" },
- { "setQueryCount", true, "bool", "set whether queries should be counted" },
- { "setQueryCountFilter", true, "func", "filter queries that would be counted, where `func` is a function with parameter `dq` which decides whether a query should and how it should be counted" },
- { "SetReducedTTLResponseAction", true, "percentage", "Reduce the TTL of records in a response to a given percentage" },
- { "setRingBuffersLockRetries", true, "n", "set the number of attempts to get a non-blocking lock to a ringbuffer shard before blocking" },
- { "setRingBuffersOptions", true, "{ lockRetries=int, recordQueries=true, recordResponses=true }", "set ringbuffer options" },
- { "setRingBuffersSize", true, "n [, numberOfShards]", "set the capacity of the ringbuffers used for live traffic inspection to `n`, and optionally the number of shards to use to `numberOfShards`" },
- { "setRoundRobinFailOnNoServer", true, "value", "By default the roundrobin load-balancing policy will still try to select a backend even if all backends are currently down. Setting this to true will make the policy fail and return that no server is available instead" },
- { "setRules", true, "list of rules", "replace the current rules with the supplied list of pairs of DNS Rules and DNS Actions (see `newRuleAction()`)" },
- { "setSecurityPollInterval", true, "n", "set the security polling interval to `n` seconds" },
- { "setSecurityPollSuffix", true, "suffix", "set the security polling suffix to the specified value" },
- { "setServerPolicy", true, "policy", "set server selection policy to that policy" },
- { "setServerPolicyLua", true, "name, function", "set server selection policy to one named 'name' and provided by 'function'" },
- { "setServerPolicyLuaFFI", true, "name, function", "set server selection policy to one named 'name' and provided by the Lua FFI 'function'" },
- { "setServerPolicyLuaFFIPerThread", true, "name, code", "set server selection policy to one named 'name' and returned by the Lua FFI code passed in 'code'" },
- { "setServFailWhenNoServer", true, "bool", "if set, return a ServFail when no servers are available, instead of the default behaviour of dropping the query" },
- { "setStaleCacheEntriesTTL", true, "n", "allows using cache entries expired for at most n seconds when there is no backend available to answer for a query" },
- { "setStructuredLogging", true, "value [, options]", "set whether log messages should be in structured-logging-like format" },
- { "setSyslogFacility", true, "facility", "set the syslog logging facility to 'facility'. Defaults to LOG_DAEMON" },
- { "setTCPDownstreamCleanupInterval", true, "interval", "minimum interval in seconds between two cleanups of the idle TCP downstream connections" },
- { "setTCPFastOpenKey", true, "string", "TCP Fast Open Key" },
- { "setTCPDownstreamMaxIdleTime", true, "time", "Maximum time in seconds that a downstream TCP connection to a backend might stay idle" },
- { "setTCPInternalPipeBufferSize", true, "size", "Set the size in bytes of the internal buffer of the pipes used internally to distribute connections to TCP (and DoT) workers threads" },
- { "setTCPRecvTimeout", true, "n", "set the read timeout on TCP connections from the client, in seconds" },
- { "setTCPSendTimeout", true, "n", "set the write timeout on TCP connections from the client, in seconds" },
- { "setUDPMultipleMessagesVectorSize", true, "n", "set the size of the vector passed to recvmmsg() to receive UDP messages. Default to 1 which means that the feature is disabled and recvmsg() is used instead" },
- { "setUDPSocketBufferSizes", true, "recv, send", "Set the size of the receive (SO_RCVBUF) and send (SO_SNDBUF) buffers for incoming UDP sockets" },
- { "setUDPTimeout", true, "n", "set the maximum time dnsdist will wait for a response from a backend over UDP, in seconds" },
- { "setVerbose", true, "bool", "set whether log messages at the verbose level will be logged" },
- { "setVerboseHealthChecks", true, "bool", "set whether health check errors will be logged" },
- { "setVerboseLogDestination", true, "destination file", "Set a destination file to write the 'verbose' log messages to, instead of sending them to syslog and/or the standard output" },
- { "setWebserverConfig", true, "[{password=string, apiKey=string, customHeaders, statsRequireAuthentication}]", "Updates webserver configuration" },
- { "setWeightedBalancingFactor", true, "factor", "Set the balancing factor for bounded-load weighted policies (whashed, wrandom)" },
- { "setWHashedPertubation", true, "value", "Set the hash perturbation value to be used in the whashed policy instead of a random one, allowing to have consistent whashed results on different instance" },
- { "show", true, "string", "outputs `string`" },
- { "showACL", true, "", "show our ACL set" },
- { "showBinds", true, "", "show listening addresses (frontends)" },
- { "showCacheHitResponseRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "show all defined cache hit response rules, optionally with their UUIDs and optionally truncated to a given width" },
- { "showConsoleACL", true, "", "show our current console ACL set" },
- { "showDNSCryptBinds", true, "", "display the currently configured DNSCrypt binds" },
- { "showDOHFrontends", true, "", "list all the available DOH frontends" },
- { "showDOH3Frontends", true, "", "list all the available DOH3 frontends" },
- { "showDOHResponseCodes", true, "", "show the HTTP response code statistics for the DoH frontends"},
- { "showDOQFrontends", true, "", "list all the available DOQ frontends" },
- { "showDynBlocks", true, "", "show dynamic blocks in force" },
- { "showPools", true, "", "show the available pools" },
- { "showPoolServerPolicy", true, "pool", "show server selection policy for this pool" },
- { "showResponseLatency", true, "", "show a plot of the response time latency distribution" },
- { "showResponseRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "show all defined response rules, optionally with their UUIDs and optionally truncated to a given width" },
- { "showRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "show all defined rules, optionally with their UUIDs and optionally truncated to a given width" },
- { "showSecurityStatus", true, "", "Show the security status"},
- { "showSelfAnsweredResponseRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "show all defined self-answered response rules, optionally with their UUIDs and optionally truncated to a given width" },
- { "showServerPolicy", true, "", "show name of currently operational server selection policy" },
- { "showServers", true, "[{showUUIDs=false}]", "output all servers, optionally with their UUIDs" },
- { "showTCPStats", true, "", "show some statistics regarding TCP" },
- { "showTLSContexts", true, "", "list all the available TLS contexts" },
- { "showTLSErrorCounters", true, "", "show metrics about TLS handshake failures" },
- { "showVersion", true, "", "show the current version" },
- { "showWebserverConfig", true, "", "Show the current webserver configuration" },
- { "shutdown", true, "", "shut down `dnsdist`" },
- { "snmpAgent", true, "enableTraps [, daemonSocket]", "enable `SNMP` support. `enableTraps` is a boolean indicating whether traps should be sent and `daemonSocket` an optional string specifying how to connect to the daemon agent"},
- { "SetAdditionalProxyProtocolValueAction", true, "type, value", "Add a Proxy Protocol TLV value of this type" },
- { "SetDisableECSAction", true, "", "Disable the sending of ECS to the backend. Subsequent rules are processed after this action." },
- { "SetDisableValidationAction", true, "", "set the CD bit in the question, let it go through" },
- { "SetECSAction", true, "v4[, v6]", "Set the ECS prefix and prefix length sent to backends to an arbitrary value" },
- { "SetECSOverrideAction", true, "override", "Whether an existing EDNS Client Subnet value should be overridden (true) or not (false). Subsequent rules are processed after this action" },
- { "SetECSPrefixLengthAction", true, "v4, v6", "Set the ECS prefix length. Subsequent rules are processed after this action" },
- { "SetMacAddrAction", true, "option", "Add the source MAC address to the query as EDNS0 option option. This action is currently only supported on Linux. Subsequent rules are processed after this action" },
- { "SetEDNSOptionAction", true, "option, data", "Add arbitrary EDNS option and data to the query. Subsequent rules are processed after this action" },
- { "SetExtendedDNSErrorAction", true, "infoCode [, extraText]", "Set an Extended DNS Error status that will be added to the response corresponding to the current query. Subsequent rules are processed after this action" },
- { "SetExtendedDNSErrorResponseAction", true, "infoCode [, extraText]", "Set an Extended DNS Error status that will be added to this response. Subsequent rules are processed after this action" },
- { "SetNoRecurseAction", true, "", "strip RD bit from the question, let it go through" },
- { "setOutgoingDoHWorkerThreads", true, "n", "Number of outgoing DoH worker threads" },
- { "SetProxyProtocolValuesAction", true, "values", "Set the Proxy-Protocol values for this queries to 'values'" },
- { "SetSkipCacheAction", true, "", "Don’t lookup the cache for this query, don’t store the answer" },
- { "SetSkipCacheResponseAction", true, "", "Don’t store this response into the cache" },
- { "SetTagAction", true, "name, value", "set the tag named 'name' to the given value" },
- { "SetTagResponseAction", true, "name, value", "set the tag named 'name' to the given value" },
- { "SetTempFailureCacheTTLAction", true, "ttl", "set packetcache TTL for temporary failure replies" },
- { "SNIRule", true, "name", "Create a rule which matches on the incoming TLS SNI value, if any (DoT or DoH)" },
- { "SNMPTrapAction", true, "[reason]", "send an SNMP trap, adding the optional `reason` string as the query description"},
- { "SNMPTrapResponseAction", true, "[reason]", "send an SNMP trap, adding the optional `reason` string as the response description"},
- { "SpoofAction", true, "ip|list of ips [, options]", "forge a response with the specified IPv4 (for an A query) or IPv6 (for an AAAA). If you specify multiple addresses, all that match the query type (A, AAAA or ANY) will get spoofed in" },
- { "SpoofCNAMEAction", true, "cname [, options]", "Forge a response with the specified CNAME value" },
- { "SpoofRawAction", true, "raw|list of raws [, options]", "Forge a response with the specified record data as raw bytes. If you specify multiple raws (it is assumed they match the query type), all will get spoofed in" },
- { "SpoofSVCAction", true, "list of svcParams [, options]", "Forge a response with the specified SVC record data" } ,
- { "SuffixMatchNodeRule", true, "smn[, quiet]", "Matches based on a group of domain suffixes for rapid testing of membership. Pass true as second parameter to prevent listing of all domains matched" },
- { "TagRule", true, "name [, value]", "matches if the tag named 'name' is present, with the given 'value' matching if any" },
- { "TCAction", true, "", "create answer to query with TC and RD bits set, to move to TCP" },
- { "TCPRule", true, "[tcp]", "Matches question received over TCP if tcp is true, over UDP otherwise" },
- { "TCResponseAction", true, "", "truncate a response" },
- { "TeeAction", true, "remote [, addECS [, local]]", "send copy of query to remote, optionally adding ECS info, optionally set local address" },
- { "testCrypto", true, "", "test of the crypto all works" },
- { "TimedIPSetRule", true, "", "Create a rule which matches a set of IP addresses which expire"},
- { "topBandwidth", true, "top", "show top-`top` clients that consume the most bandwidth over length of ringbuffer" },
- { "topCacheHitResponseRules", true, "[top][, vars]", "show `top` cache-hit response rules" },
- { "topCacheInsertedResponseRules", true, "[top][, vars]", "show `top` cache-inserted response rules" },
- { "topClients", true, "n", "show top-`n` clients sending the most queries over length of ringbuffer" },
- { "topQueries", true, "n[, labels]", "show top 'n' queries, as grouped when optionally cut down to 'labels' labels" },
- { "topResponses", true, "n, kind[, labels]", "show top 'n' responses with RCODE=kind (0=NO Error, 2=ServFail, 3=NXDomain), as grouped when optionally cut down to 'labels' labels" },
- { "topResponseRules", true, "[top][, vars]", "show `top` response rules" },
- { "topRules", true, "[top][, vars]", "show `top` rules" },
- { "topSelfAnsweredResponseRules", true, "[top][, vars]", "show `top` self-answered response rules" },
- { "topSlow", true, "[top][, limit][, labels]", "show `top` queries slower than `limit` milliseconds, grouped by last `labels` labels" },
- { "TrailingDataRule", true, "", "Matches if the query has trailing data" },
- { "truncateTC", true, "bool", "if set (defaults to no starting with dnsdist 1.2.0) truncate TC=1 answers so they are actually empty. Fixes an issue for PowerDNS Authoritative Server 2.9.22. Note: turning this on breaks compatibility with RFC 6891." },
- { "unregisterDynBPFFilter", true, "DynBPFFilter", "unregister this dynamic BPF filter" },
- { "webserver", true, "address:port", "launch a webserver with stats on that address" },
- { "whashed", false, "", "Weighted hashed ('sticky') distribution over available servers, based on the server 'weight' parameter" },
- { "chashed", false, "", "Consistent hashed ('sticky') distribution over available servers, also based on the server 'weight' parameter" },
- { "wrandom", false, "", "Weighted random over available servers, based on the server 'weight' parameter" },
+ {"newNMG", true, "", "Returns a NetmaskGroup"},
+ {"newPacketCache", true, "maxEntries[, maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=true, options={}]", "return a new Packet Cache"},
+ {"newQPSLimiter", true, "rate, burst", "configure a QPS limiter with that rate and that burst capacity"},
+ {"newRemoteLogger", true, "address:port [, timeout=2, maxQueuedEntries=100, reconnectWaitTime=1]", "create a Remote Logger object, to use with `RemoteLogAction()` and `RemoteLogResponseAction()`"},
+ {"newRuleAction", true, R"(DNS rule, DNS action [, {uuid="UUID", name="name"}])", "return a pair of DNS Rule and DNS Action, to be used with `setRules()`"},
+ {"newServer", true, R"({address="ip:port", qps=1000, order=1, weight=10, pool="abuse", retries=5, tcpConnectTimeout=5, tcpSendTimeout=30, tcpRecvTimeout=30, checkName="a.root-servers.net.", checkType="A", maxCheckFailures=1, mustResolve=false, useClientSubnet=true, source="address|interface name|address@interface", sockets=1, reconnectOnUp=false})", "instantiate a server"},
+ {"newServerPolicy", true, "name, function", "create a policy object from a Lua function"},
+ {"newSuffixMatchNode", true, "", "returns a new SuffixMatchNode"},
+ {"newSVCRecordParameters", true, "priority, target, mandatoryParams, alpns, noDefaultAlpn [, port [, ech [, ipv4hints [, ipv6hints [, additionalParameters ]]]]]", "return a new SVCRecordParameters object, to use with SpoofSVCAction"},
+ {"NegativeAndSOAAction", true, "nxd, zone, ttl, mname, rname, serial, refresh, retry, expire, minimum [, options]", "Turn a query into a NXDomain or NoData answer and sets a SOA record in the additional section"},
+ {"NoneAction", true, "", "Does nothing. Subsequent rules are processed after this action"},
+ {"NotRule", true, "selector", "Matches the traffic if the selector rule does not match"},
+ {"OpcodeRule", true, "code", "Matches queries with opcode code. code can be directly specified as an integer, or one of the built-in DNSOpcodes"},
+ {"OrRule", true, "selectors", "Matches the traffic if one or more of the the selectors rules does match"},
+ {"PoolAction", true, "poolname [, stop]", "set the packet into the specified pool"},
+ {"PoolAvailableRule", true, "poolname", "Check whether a pool has any servers available to handle queries"},
+ {"PoolOutstandingRule", true, "poolname, limit", "Check whether a pool has outstanding queries above limit"},
+ {"printDNSCryptProviderFingerprint", true, R"("/path/to/providerPublic.key")", "display the fingerprint of the provided resolver public key"},
+ {"ProbaRule", true, "probability", "Matches queries with a given probability. 1.0 means always"},
+ {"ProxyProtocolValueRule", true, "type [, value]", "matches queries with a specified Proxy Protocol TLV value of that type, optionally matching the content of the option as well"},
+ {"QClassRule", true, "qclass", "Matches queries with the specified qclass. class can be specified as an integer or as one of the built-in DNSClass"},
+ {"QNameLabelsCountRule", true, "min, max", "matches if the qname has less than `min` or more than `max` labels"},
+ {"QNameRule", true, "qname", "matches queries with the specified qname"},
+ {"QNameSetRule", true, "set", "Matches if the set contains exact qname"},
+ {"QNameWireLengthRule", true, "min, max", "matches if the qname's length on the wire is less than `min` or more than `max` bytes"},
+ {"QPSAction", true, "maxqps", "Drop a packet if it does exceed the maxqps queries per second limits. Letting the subsequent rules apply otherwise"},
+ {"QPSPoolAction", true, "maxqps, poolname [, stop]", "Send the packet into the specified pool only if it does not exceed the maxqps queries per second limits. Letting the subsequent rules apply otherwise"},
+ {"QTypeRule", true, "qtype", "matches queries with the specified qtype"},
+ {"RCodeAction", true, "rcode", "Reply immediately by turning the query into a response with the specified rcode"},
+ {"RCodeRule", true, "rcode", "matches responses with the specified rcode"},
+ {"RDRule", true, "", "Matches queries with the RD flag set"},
+ {"RecordsCountRule", true, "section, minCount, maxCount", "Matches if there is at least minCount and at most maxCount records in the section section. section can be specified as an integer or as a DNS Packet Sections"},
+ {"RecordsTypeCountRule", true, "section, qtype, minCount, maxCount", "Matches if there is at least minCount and at most maxCount records of type type in the section section"},
+ {"RegexRule", true, "regex", "matches the query name against the supplied regex"},
+ {"registerDynBPFFilter", true, "DynBPFFilter", "register this dynamic BPF filter into the web interface so that its counters are displayed"},
+ {"reloadAllCertificates", true, "", "reload all DNSCrypt and TLS certificates, along with their associated keys"},
+ {"RemoteLogAction", true, "RemoteLogger [, alterFunction [, serverID]]", "send the content of this query to a remote logger via Protocol Buffer. `alterFunction` is a callback, receiving a DNSQuestion and a DNSDistProtoBufMessage, that can be used to modify the Protocol Buffer content, for example for anonymization purposes. `serverID` is the server identifier."},
+ {"RemoteLogResponseAction", true, "RemoteLogger [,alterFunction [,includeCNAME [, serverID]]]", "send the content of this response to a remote logger via Protocol Buffer. `alterFunction` is the same callback than the one in `RemoteLogAction` and `includeCNAME` indicates whether CNAME records inside the response should be parsed and exported. The default is to only exports A and AAAA records. `serverID` is the server identifier."},
+ {"requestTCPStatesDump", true, "", "Request a dump of the TCP states (incoming connections, outgoing connections) during the next scan. Useful for debugging purposes only"},
+ {"rmACL", true, "netmask", "remove netmask from ACL"},
+ {"rmCacheHitResponseRule", true, "id", "remove cache hit response rule in position 'id', or whose uuid matches if 'id' is an UUID string, or finally whose name matches if 'id' is a string but not a valid UUID"},
+ {"rmCacheInsertedResponseRule", true, "id", "remove cache inserted response rule in position 'id', or whose uuid matches if 'id' is an UUID string, or finally whose name matches if 'id' is a string but not a valid UUID"},
+ {"rmResponseRule", true, "id", "remove response rule in position 'id', or whose uuid matches if 'id' is an UUID string, or finally whose name matches if 'id' is a string but not a valid UUID"},
+ {"rmRule", true, "id", "remove rule in position 'id', or whose uuid matches if 'id' is an UUID string, or finally whose name matches if 'id' is a string but not a valid UUID"},
+ {"rmSelfAnsweredResponseRule", true, "id", "remove self-answered response rule in position 'id', or whose uuid matches if 'id' is an UUID string, or finally whose name matches if 'id' is a string but not a valid UUID"},
+ {"rmServer", true, "id", "remove server with index 'id' or whose uuid matches if 'id' is an UUID string"},
+ {"roundrobin", false, "", "Simple round robin over available servers"},
+ {"sendCustomTrap", true, "str", "send a custom `SNMP` trap from Lua, containing the `str` string"},
+ {"setACL", true, "{netmask, netmask}", "replace the ACL set with these netmasks. Use `setACL({})` to reset the list, meaning no one can use us"},
+ {"setACLFromFile", true, "file", "replace the ACL set with netmasks in this file"},
+ {"setAddEDNSToSelfGeneratedResponses", true, "add", "set whether to add EDNS to self-generated responses, provided that the initial query had EDNS"},
+ {"setAllowEmptyResponse", true, "allow", "Set to true (defaults to false) to allow empty responses (qdcount=0) with a NoError or NXDomain rcode (default) from backends"},
+ {"setAPIWritable", true, "bool, dir", "allow modifications via the API. if `dir` is set, it must be a valid directory where the configuration files will be written by the API"},
+ {"setCacheCleaningDelay", true, "num", "Set the interval in seconds between two runs of the cache cleaning algorithm, removing expired entries"},
+ {"setCacheCleaningPercentage", true, "num", "Set the percentage of the cache that the cache cleaning algorithm will try to free by removing expired entries. By default (100), all expired entries are remove"},
+ {"setConsistentHashingBalancingFactor", true, "factor", "Set the balancing factor for bounded-load consistent hashing"},
+ {"setConsoleACL", true, "{netmask, netmask}", "replace the console ACL set with these netmasks"},
+ {"setConsoleConnectionsLogging", true, "enabled", "whether to log the opening and closing of console connections"},
+ {"setConsoleMaximumConcurrentConnections", true, "max", "Set the maximum number of concurrent console connections"},
+ {"setConsoleOutputMaxMsgSize", true, "messageSize", "set console message maximum size in bytes, default is 10 MB"},
+ {"setDefaultBPFFilter", true, "filter", "When used at configuration time, the corresponding BPFFilter will be attached to every bind"},
+ {"setDoHDownstreamCleanupInterval", true, "interval", "minimum interval in seconds between two cleanups of the idle DoH downstream connections"},
+ {"setDoHDownstreamMaxIdleTime", true, "time", "Maximum time in seconds that a downstream DoH connection to a backend might stay idle"},
+ {"setDynBlocksAction", true, "action", "set which action is performed when a query is blocked. Only DNSAction.Drop (the default) and DNSAction.Refused are supported"},
+ {"setDynBlocksPurgeInterval", true, "sec", "set how often the expired dynamic block entries should be removed"},
+ {"setDropEmptyQueries", true, "drop", "Whether to drop empty queries right away instead of sending a NOTIMP response"},
+ {"setECSOverride", true, "bool", "whether to override an existing EDNS Client Subnet value in the query"},
+ {"setECSSourcePrefixV4", true, "prefix-length", "the EDNS Client Subnet prefix-length used for IPv4 queries"},
+ {"setECSSourcePrefixV6", true, "prefix-length", "the EDNS Client Subnet prefix-length used for IPv6 queries"},
+ {"setKey", true, "key", "set access key to that key"},
+ {"setLocal", true, R"(addr [, {doTCP=true, reusePort=false, tcpFastOpenQueueSize=0, interface="", cpus={}}])", "reset the list of addresses we listen on to this address"},
+ {"setMaxCachedDoHConnectionsPerDownstream", true, "max", "Set the maximum number of inactive DoH connections to a backend cached by each worker DoH thread"},
+ {"setMaxCachedTCPConnectionsPerDownstream", true, "max", "Set the maximum number of inactive TCP connections to a backend cached by each worker TCP thread"},
+ {"setMaxTCPClientThreads", true, "n", "set the maximum of TCP client threads, handling TCP connections"},
+ {"setMaxTCPConnectionDuration", true, "n", "set the maximum duration of an incoming TCP connection, in seconds. 0 means unlimited"},
+ {"setMaxTCPConnectionsPerClient", true, "n", "set the maximum number of TCP connections per client. 0 means unlimited"},
+ {"setMaxTCPQueriesPerConnection", true, "n", "set the maximum number of queries in an incoming TCP connection. 0 means unlimited"},
+ {"setMaxTCPQueuedConnections", true, "n", "set the maximum number of TCP connections queued (waiting to be picked up by a client thread)"},
+ {"setMaxUDPOutstanding", true, "n", "set the maximum number of outstanding UDP queries to a given backend server. This can only be set at configuration time and defaults to 65535"},
+ {"setMetric", true, "name, value", "Set the value of a custom metric to the supplied value"},
+ {"setPayloadSizeOnSelfGeneratedAnswers", true, "payloadSize", "set the UDP payload size advertised via EDNS on self-generated responses"},
+ {"setPoolServerPolicy", true, "policy, pool", "set the server selection policy for this pool to that policy"},
+ {"setPoolServerPolicyLua", true, "name, function, pool", "set the server selection policy for this pool to one named 'name' and provided by 'function'"},
+ {"setPoolServerPolicyLuaFFI", true, "name, function, pool", "set the server selection policy for this pool to one named 'name' and provided by 'function'"},
+ {"setPoolServerPolicyLuaFFIPerThread", true, "name, code", "set server selection policy for this pool to one named 'name' and returned by the Lua FFI code passed in 'code'"},
+ {"setProxyProtocolACL", true, "{netmask, netmask}", "Set the netmasks who are allowed to send Proxy Protocol headers in front of queries/connections"},
+ {"setProxyProtocolApplyACLToProxiedClients", true, "apply", "Whether the general ACL should be applied to the source IP address gathered from a Proxy Protocol header, in addition to being first applied to the source address seen by dnsdist"},
+ {"setProxyProtocolMaximumPayloadSize", true, "max", "Set the maximum size of a Proxy Protocol payload, in bytes"},
+ {"setQueryCount", true, "bool", "set whether queries should be counted"},
+ {"setQueryCountFilter", true, "func", "filter queries that would be counted, where `func` is a function with parameter `dq` which decides whether a query should and how it should be counted"},
+ {"SetReducedTTLResponseAction", true, "percentage", "Reduce the TTL of records in a response to a given percentage"},
+ {"setRingBuffersLockRetries", true, "n", "set the number of attempts to get a non-blocking lock to a ringbuffer shard before blocking"},
+ {"setRingBuffersOptions", true, "{ lockRetries=int, recordQueries=true, recordResponses=true }", "set ringbuffer options"},
+ {"setRingBuffersSize", true, "n [, numberOfShards]", "set the capacity of the ringbuffers used for live traffic inspection to `n`, and optionally the number of shards to use to `numberOfShards`"},
+ {"setRoundRobinFailOnNoServer", true, "value", "By default the roundrobin load-balancing policy will still try to select a backend even if all backends are currently down. Setting this to true will make the policy fail and return that no server is available instead"},
+ {"setRules", true, "list of rules", "replace the current rules with the supplied list of pairs of DNS Rules and DNS Actions (see `newRuleAction()`)"},
+ {"setSecurityPollInterval", true, "n", "set the security polling interval to `n` seconds"},
+ {"setSecurityPollSuffix", true, "suffix", "set the security polling suffix to the specified value"},
+ {"setServerPolicy", true, "policy", "set server selection policy to that policy"},
+ {"setServerPolicyLua", true, "name, function", "set server selection policy to one named 'name' and provided by 'function'"},
+ {"setServerPolicyLuaFFI", true, "name, function", "set server selection policy to one named 'name' and provided by the Lua FFI 'function'"},
+ {"setServerPolicyLuaFFIPerThread", true, "name, code", "set server selection policy to one named 'name' and returned by the Lua FFI code passed in 'code'"},
+ {"setServFailWhenNoServer", true, "bool", "if set, return a ServFail when no servers are available, instead of the default behaviour of dropping the query"},
+ {"setStaleCacheEntriesTTL", true, "n", "allows using cache entries expired for at most n seconds when there is no backend available to answer for a query"},
+ {"setStructuredLogging", true, "value [, options]", "set whether log messages should be in structured-logging-like format"},
+ {"setSyslogFacility", true, "facility", "set the syslog logging facility to 'facility'. Defaults to LOG_DAEMON"},
+ {"setTCPDownstreamCleanupInterval", true, "interval", "minimum interval in seconds between two cleanups of the idle TCP downstream connections"},
+ {"setTCPFastOpenKey", true, "string", "TCP Fast Open Key"},
+ {"setTCPDownstreamMaxIdleTime", true, "time", "Maximum time in seconds that a downstream TCP connection to a backend might stay idle"},
+ {"setTCPInternalPipeBufferSize", true, "size", "Set the size in bytes of the internal buffer of the pipes used internally to distribute connections to TCP (and DoT) workers threads"},
+ {"setTCPRecvTimeout", true, "n", "set the read timeout on TCP connections from the client, in seconds"},
+ {"setTCPSendTimeout", true, "n", "set the write timeout on TCP connections from the client, in seconds"},
+ {"setUDPMultipleMessagesVectorSize", true, "n", "set the size of the vector passed to recvmmsg() to receive UDP messages. Default to 1 which means that the feature is disabled and recvmsg() is used instead"},
+ {"setUDPSocketBufferSizes", true, "recv, send", "Set the size of the receive (SO_RCVBUF) and send (SO_SNDBUF) buffers for incoming UDP sockets"},
+ {"setUDPTimeout", true, "n", "set the maximum time dnsdist will wait for a response from a backend over UDP, in seconds"},
+ {"setVerbose", true, "bool", "set whether log messages at the verbose level will be logged"},
+ {"setVerboseHealthChecks", true, "bool", "set whether health check errors will be logged"},
+ {"setVerboseLogDestination", true, "destination file", "Set a destination file to write the 'verbose' log messages to, instead of sending them to syslog and/or the standard output"},
+ {"setWebserverConfig", true, "[{password=string, apiKey=string, customHeaders, statsRequireAuthentication}]", "Updates webserver configuration"},
+ {"setWeightedBalancingFactor", true, "factor", "Set the balancing factor for bounded-load weighted policies (whashed, wrandom)"},
+ {"setWHashedPertubation", true, "value", "Set the hash perturbation value to be used in the whashed policy instead of a random one, allowing to have consistent whashed results on different instance"},
+ {"show", true, "string", "outputs `string`"},
+ {"showACL", true, "", "show our ACL set"},
+ {"showBinds", true, "", "show listening addresses (frontends)"},
+ {"showCacheHitResponseRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "show all defined cache hit response rules, optionally with their UUIDs and optionally truncated to a given width"},
+ {"showConsoleACL", true, "", "show our current console ACL set"},
+ {"showDNSCryptBinds", true, "", "display the currently configured DNSCrypt binds"},
+ {"showDOHFrontends", true, "", "list all the available DOH frontends"},
+ {"showDOH3Frontends", true, "", "list all the available DOH3 frontends"},
+ {"showDOHResponseCodes", true, "", "show the HTTP response code statistics for the DoH frontends"},
+ {"showDOQFrontends", true, "", "list all the available DOQ frontends"},
+ {"showDynBlocks", true, "", "show dynamic blocks in force"},
+ {"showPools", true, "", "show the available pools"},
+ {"showPoolServerPolicy", true, "pool", "show server selection policy for this pool"},
+ {"showResponseLatency", true, "", "show a plot of the response time latency distribution"},
+ {"showResponseRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "show all defined response rules, optionally with their UUIDs and optionally truncated to a given width"},
+ {"showRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "show all defined rules, optionally with their UUIDs and optionally truncated to a given width"},
+ {"showSecurityStatus", true, "", "Show the security status"},
+ {"showSelfAnsweredResponseRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "show all defined self-answered response rules, optionally with their UUIDs and optionally truncated to a given width"},
+ {"showServerPolicy", true, "", "show name of currently operational server selection policy"},
+ {"showServers", true, "[{showUUIDs=false}]", "output all servers, optionally with their UUIDs"},
+ {"showTCPStats", true, "", "show some statistics regarding TCP"},
+ {"showTLSContexts", true, "", "list all the available TLS contexts"},
+ {"showTLSErrorCounters", true, "", "show metrics about TLS handshake failures"},
+ {"showVersion", true, "", "show the current version"},
+ {"showWebserverConfig", true, "", "Show the current webserver configuration"},
+ {"shutdown", true, "", "shut down `dnsdist`"},
+ {"snmpAgent", true, "enableTraps [, daemonSocket]", "enable `SNMP` support. `enableTraps` is a boolean indicating whether traps should be sent and `daemonSocket` an optional string specifying how to connect to the daemon agent"},
+ {"SetAdditionalProxyProtocolValueAction", true, "type, value", "Add a Proxy Protocol TLV value of this type"},
+ {"SetDisableECSAction", true, "", "Disable the sending of ECS to the backend. Subsequent rules are processed after this action."},
+ {"SetDisableValidationAction", true, "", "set the CD bit in the question, let it go through"},
+ {"SetECSAction", true, "v4[, v6]", "Set the ECS prefix and prefix length sent to backends to an arbitrary value"},
+ {"SetECSOverrideAction", true, "override", "Whether an existing EDNS Client Subnet value should be overridden (true) or not (false). Subsequent rules are processed after this action"},
+ {"SetECSPrefixLengthAction", true, "v4, v6", "Set the ECS prefix length. Subsequent rules are processed after this action"},
+ {"SetMacAddrAction", true, "option", "Add the source MAC address to the query as EDNS0 option option. This action is currently only supported on Linux. Subsequent rules are processed after this action"},
+ {"SetEDNSOptionAction", true, "option, data", "Add arbitrary EDNS option and data to the query. Subsequent rules are processed after this action"},
+ {"SetExtendedDNSErrorAction", true, "infoCode [, extraText]", "Set an Extended DNS Error status that will be added to the response corresponding to the current query. Subsequent rules are processed after this action"},
+ {"SetExtendedDNSErrorResponseAction", true, "infoCode [, extraText]", "Set an Extended DNS Error status that will be added to this response. Subsequent rules are processed after this action"},
+ {"SetNoRecurseAction", true, "", "strip RD bit from the question, let it go through"},
+ {"setOutgoingDoHWorkerThreads", true, "n", "Number of outgoing DoH worker threads"},
+ {"SetProxyProtocolValuesAction", true, "values", "Set the Proxy-Protocol values for this queries to 'values'"},
+ {"SetSkipCacheAction", true, "", "Don’t lookup the cache for this query, don’t store the answer"},
+ {"SetSkipCacheResponseAction", true, "", "Don’t store this response into the cache"},
+ {"SetTagAction", true, "name, value", "set the tag named 'name' to the given value"},
+ {"SetTagResponseAction", true, "name, value", "set the tag named 'name' to the given value"},
+ {"SetTempFailureCacheTTLAction", true, "ttl", "set packetcache TTL for temporary failure replies"},
+ {"SNIRule", true, "name", "Create a rule which matches on the incoming TLS SNI value, if any (DoT or DoH)"},
+ {"SNMPTrapAction", true, "[reason]", "send an SNMP trap, adding the optional `reason` string as the query description"},
+ {"SNMPTrapResponseAction", true, "[reason]", "send an SNMP trap, adding the optional `reason` string as the response description"},
+ {"SpoofAction", true, "ip|list of ips [, options]", "forge a response with the specified IPv4 (for an A query) or IPv6 (for an AAAA). If you specify multiple addresses, all that match the query type (A, AAAA or ANY) will get spoofed in"},
+ {"SpoofCNAMEAction", true, "cname [, options]", "Forge a response with the specified CNAME value"},
+ {"SpoofRawAction", true, "raw|list of raws [, options]", "Forge a response with the specified record data as raw bytes. If you specify multiple raws (it is assumed they match the query type), all will get spoofed in"},
+ {"SpoofSVCAction", true, "list of svcParams [, options]", "Forge a response with the specified SVC record data"},
+ {"SuffixMatchNodeRule", true, "smn[, quiet]", "Matches based on a group of domain suffixes for rapid testing of membership. Pass true as second parameter to prevent listing of all domains matched"},
+ {"TagRule", true, "name [, value]", "matches if the tag named 'name' is present, with the given 'value' matching if any"},
+ {"TCAction", true, "", "create answer to query with TC and RD bits set, to move to TCP"},
+ {"TCPRule", true, "[tcp]", "Matches question received over TCP if tcp is true, over UDP otherwise"},
+ {"TCResponseAction", true, "", "truncate a response"},
+ {"TeeAction", true, "remote [, addECS [, local]]", "send copy of query to remote, optionally adding ECS info, optionally set local address"},
+ {"testCrypto", true, "", "test of the crypto all works"},
+ {"TimedIPSetRule", true, "", "Create a rule which matches a set of IP addresses which expire"},
+ {"topBandwidth", true, "top", "show top-`top` clients that consume the most bandwidth over length of ringbuffer"},
+ {"topCacheHitResponseRules", true, "[top][, vars]", "show `top` cache-hit response rules"},
+ {"topCacheInsertedResponseRules", true, "[top][, vars]", "show `top` cache-inserted response rules"},
+ {"topClients", true, "n", "show top-`n` clients sending the most queries over length of ringbuffer"},
+ {"topQueries", true, "n[, labels]", "show top 'n' queries, as grouped when optionally cut down to 'labels' labels"},
+ {"topResponses", true, "n, kind[, labels]", "show top 'n' responses with RCODE=kind (0=NO Error, 2=ServFail, 3=NXDomain), as grouped when optionally cut down to 'labels' labels"},
+ {"topResponseRules", true, "[top][, vars]", "show `top` response rules"},
+ {"topRules", true, "[top][, vars]", "show `top` rules"},
+ {"topSelfAnsweredResponseRules", true, "[top][, vars]", "show `top` self-answered response rules"},
+ {"topSlow", true, "[top][, limit][, labels]", "show `top` queries slower than `limit` milliseconds, grouped by last `labels` labels"},
+ {"TrailingDataRule", true, "", "Matches if the query has trailing data"},
+ {"truncateTC", true, "bool", "if set (defaults to no starting with dnsdist 1.2.0) truncate TC=1 answers so they are actually empty. Fixes an issue for PowerDNS Authoritative Server 2.9.22. Note: turning this on breaks compatibility with RFC 6891."},
+ {"unregisterDynBPFFilter", true, "DynBPFFilter", "unregister this dynamic BPF filter"},
+ {"webserver", true, "address:port", "launch a webserver with stats on that address"},
+ {"whashed", false, "", "Weighted hashed ('sticky') distribution over available servers, based on the server 'weight' parameter"},
+ {"chashed", false, "", "Consistent hashed ('sticky') distribution over available servers, also based on the server 'weight' parameter"},
+ {"wrandom", false, "", "Weighted random over available servers, based on the server 'weight' parameter"},
};
#if defined(HAVE_LIBEDIT)
-extern "C" {
-static char* my_generator(const char* text, int state)
+extern "C"
{
- string textStr(text);
- /* to keep it readable, we try to keep only 4 keywords per line
- and to start a new line when the first letter changes */
- static int s_counter = 0;
- int counter = 0;
- if (state == 0) {
- s_counter = 0;
- }
+ static char* my_generator(const char* text, int state)
+ {
+ string textStr(text);
+ /* to keep it readable, we try to keep only 4 keywords per line
+ and to start a new line when the first letter changes */
+ static int s_counter = 0;
+ int counter = 0;
+ if (state == 0) {
+ s_counter = 0;
+ }
- for (const auto& keyword : g_consoleKeywords) {
- if (boost::starts_with(keyword.name, textStr) && counter++ == s_counter) {
- std::string value(keyword.name);
- s_counter++;
- if (keyword.function) {
- value += "(";
- if (keyword.parameters.empty()) {
- value += ")";
+ for (const auto& keyword : g_consoleKeywords) {
+ if (boost::starts_with(keyword.name, textStr) && counter++ == s_counter) {
+ std::string value(keyword.name);
+ s_counter++;
+ if (keyword.function) {
+ value += "(";
+ if (keyword.parameters.empty()) {
+ value += ")";
+ }
}
+ return strdup(value.c_str());
}
- return strdup(value.c_str());
}
+ return nullptr;
}
- return nullptr;
-}
-char** my_completion( const char * text , int start, int end)
-{
- char **matches = nullptr;
- if (start == 0) {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast): readline
- matches = rl_completion_matches (const_cast<char*>(text), &my_generator);
- }
+ char** my_completion(const char* text, int start, int end)
+ {
+ char** matches = nullptr;
+ if (start == 0) {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast): readline
+ matches = rl_completion_matches(const_cast<char*>(text), &my_generator);
+ }
- // skip default filename completion.
- rl_attempted_completion_over = 1;
+ // skip default filename completion.
+ rl_attempted_completion_over = 1;
- return matches;
-}
+ return matches;
+ }
}
#endif /* HAVE_LIBEDIT */
#endif /* DISABLE_COMPLETION */
string,
shared_ptr<DownstreamState>,
ClientState*,
- std::unordered_map<string, double>
- >
- >
- >(withReturn ? ("return "+line) : line);
+ std::unordered_map<string, double>>>>(withReturn ? ("return " + line) : line);
if (ret) {
if (const auto* dsValue = boost::get<shared_ptr<DownstreamState>>(&*ret)) {
if (*dsValue) {
- response = (*dsValue)->getName()+"\n";
- } else {
+ response = (*dsValue)->getName() + "\n";
+ }
+ else {
response = "";
}
}
else if (const auto* csValue = boost::get<ClientState*>(&*ret)) {
if (*csValue != nullptr) {
- response = (*csValue)->local.toStringWithPort()+"\n";
- } else {
+ response = (*csValue)->local.toStringWithPort() + "\n";
+ }
+ else {
response = "";
}
}
else if (const auto* strValue = boost::get<string>(&*ret)) {
- response = *strValue+"\n";
+ response = *strValue + "\n";
}
- else if (const auto* mapValue = boost::get<std::unordered_map<string, double> >(&*ret)) {
+ else if (const auto* mapValue = boost::get<std::unordered_map<string, double>>(&*ret)) {
using namespace json11;
Json::object obj;
for (const auto& value : *mapValue) {
obj[value.first] = value.second;
}
Json out = obj;
- response = out.dump()+"\n";
+ response = out.dump() + "\n";
}
}
else {
throw;
}
}
- catch(const LuaContext::WrongTypeException& e) {
- response = "Command returned an object we can't print: " +std::string(e.what()) + "\n";
+ catch (const LuaContext::WrongTypeException& e) {
+ response = "Command returned an object we can't print: " + std::string(e.what()) + "\n";
// tried to return something we don't understand
}
catch (const LuaContext::ExecutionErrorException& e) {
- if (strcmp(e.what(),"invalid key to 'next'") == 0) {
+ if (strcmp(e.what(), "invalid key to 'next'") == 0) {
response = "Error: Parsing function parameters, did you forget parameter name?";
}
else {
try {
std::rethrow_if_nested(e);
- } catch (const std::exception& ne) {
+ }
+ catch (const std::exception& ne) {
// ne is the exception that was thrown from inside the lambda
- response+= ": " + string(ne.what());
+ response += ": " + string(ne.what());
}
catch (const PDNSException& ne) {
// ne is the exception that was thrown from inside the lambda
// NOLINTNEXTLINE(performance-unnecessary-value-param): this is thread
void controlThread(std::shared_ptr<Socket> acceptFD, ComboAddress local)
{
- try
- {
+ try {
setThreadName("dnsdist/control");
ComboAddress client;
int sock{-1};
#include "sstuff.hh"
#ifndef DISABLE_COMPLETION
-struct ConsoleKeyword {
+struct ConsoleKeyword
+{
std::string name;
bool function;
std::string parameters;
}
};
extern const std::vector<ConsoleKeyword> g_consoleKeywords;
-extern "C" {
-char** my_completion( const char * text , int start, int end);
+extern "C"
+{
+ char** my_completion(const char* text, int start, int end);
}
#endif /* DISABLE_COMPLETION */
{
auto data = d_data.lock();
- typedef boost::multi_index::nth_index<container_t,1>::type ordered_until;
+ typedef boost::multi_index::nth_index<container_t, 1>::type ordered_until;
ordered_until& ou = boost::multi_index::get<1>(data->d_entries);
- for (ordered_until::iterator it = ou.begin(); it != ou.end(); ) {
+ for (ordered_until::iterator it = ou.begin(); it != ou.end();) {
if (it->d_until < now) {
ComboAddress addr = it->d_addr;
it = ou.erase(it);
}
}
-std::vector<std::tuple<ComboAddress, uint64_t, struct timespec> > DynBPFFilter::getAddrStats()
+std::vector<std::tuple<ComboAddress, uint64_t, struct timespec>> DynBPFFilter::getAddrStats()
{
- std::vector<std::tuple<ComboAddress, uint64_t, struct timespec> > result;
+ std::vector<std::tuple<ComboAddress, uint64_t, struct timespec>> result;
auto data = d_data.lock();
if (!data->d_bpf) {
/* returns true if the addr wasn't already blocked, false otherwise */
bool block(const ComboAddress& addr, const struct timespec& until);
void purgeExpired(const struct timespec& now);
- std::vector<std::tuple<ComboAddress, uint64_t, struct timespec> > getAddrStats();
+ std::vector<std::tuple<ComboAddress, uint64_t, struct timespec>> getAddrStats();
+
private:
struct BlockEntry
{
- BlockEntry(const ComboAddress& addr, const struct timespec until): d_addr(addr), d_until(until)
+ BlockEntry(const ComboAddress& addr, const struct timespec until) :
+ d_addr(addr), d_until(until)
{
}
ComboAddress d_addr;
struct timespec d_until;
};
typedef boost::multi_index_container<BlockEntry,
- boost::multi_index::indexed_by <
- boost::multi_index::ordered_unique< boost::multi_index::member<BlockEntry,ComboAddress,&BlockEntry::d_addr>, ComboAddress::addressOnlyLessThan >,
- boost::multi_index::ordered_non_unique< boost::multi_index::member<BlockEntry,struct timespec,&BlockEntry::d_until> >
- >
- > container_t;
- struct Data {
+ boost::multi_index::indexed_by<
+ boost::multi_index::ordered_unique<boost::multi_index::member<BlockEntry, ComboAddress, &BlockEntry::d_addr>, ComboAddress::addressOnlyLessThan>,
+ boost::multi_index::ordered_non_unique<boost::multi_index::member<BlockEntry, struct timespec, &BlockEntry::d_until>>>>
+ container_t;
+ struct Data
+ {
container_t d_entries;
std::shared_ptr<BPFFilter> d_bpf{nullptr};
NetmaskGroup d_excludedSubnets;
};
LockGuarded<Data> d_data;
};
-
rrclass = pr.get16BitInt();
GenericDNSPacketWriter<PacketBuffer> pw(newContent, rrname, rrtype, rrclass, dh->opcode);
- pw.getHeader()->id=dh->id;
- pw.getHeader()->qr=dh->qr;
- pw.getHeader()->aa=dh->aa;
- pw.getHeader()->tc=dh->tc;
- pw.getHeader()->rd=dh->rd;
- pw.getHeader()->ra=dh->ra;
- pw.getHeader()->ad=dh->ad;
- pw.getHeader()->cd=dh->cd;
- pw.getHeader()->rcode=dh->rcode;
+ pw.getHeader()->id = dh->id;
+ pw.getHeader()->qr = dh->qr;
+ pw.getHeader()->aa = dh->aa;
+ pw.getHeader()->tc = dh->tc;
+ pw.getHeader()->rd = dh->rd;
+ pw.getHeader()->ra = dh->ra;
+ pw.getHeader()->ad = dh->ad;
+ pw.getHeader()->cd = dh->cd;
+ pw.getHeader()->rcode = dh->rcode;
/* consume remaining qd if any */
if (qdcount > 1) {
- for(idx = 1; idx < qdcount; idx++) {
+ for (idx = 1; idx < qdcount; idx++) {
rrname = pr.getName();
rrtype = pr.get16BitInt();
rrclass = pr.get16BitInt();
- (void) rrtype;
- (void) rrclass;
+ (void)rrtype;
+ (void)rrclass;
}
}
pw.startRecord(rrname, ah.d_type, ah.d_ttl, ah.d_class, DNSResourceRecord::ADDITIONAL, true);
pr.xfrBlob(blob);
pw.xfrBlob(blob);
- } else {
+ }
+ else {
pr.skip(ah.d_clen);
}
static bool addOrReplaceEDNSOption(std::vector<std::pair<uint16_t, std::string>>& options, uint16_t optionCode, bool& optionAdded, bool overrideExisting, const string& newOptionContent)
{
- for (auto it = options.begin(); it != options.end(); ) {
+ for (auto it = options.begin(); it != options.end();) {
if (it->first == optionCode) {
optionAdded = false;
rrclass = pr.get16BitInt();
GenericDNSPacketWriter<PacketBuffer> pw(newContent, rrname, rrtype, rrclass, dh->opcode);
- pw.getHeader()->id=dh->id;
- pw.getHeader()->qr=dh->qr;
- pw.getHeader()->aa=dh->aa;
- pw.getHeader()->tc=dh->tc;
- pw.getHeader()->rd=dh->rd;
- pw.getHeader()->ra=dh->ra;
- pw.getHeader()->ad=dh->ad;
- pw.getHeader()->cd=dh->cd;
- pw.getHeader()->rcode=dh->rcode;
+ pw.getHeader()->id = dh->id;
+ pw.getHeader()->qr = dh->qr;
+ pw.getHeader()->aa = dh->aa;
+ pw.getHeader()->tc = dh->tc;
+ pw.getHeader()->rd = dh->rd;
+ pw.getHeader()->ra = dh->ra;
+ pw.getHeader()->ad = dh->ad;
+ pw.getHeader()->cd = dh->cd;
+ pw.getHeader()->rcode = dh->rcode;
/* consume remaining qd if any */
if (qdcount > 1) {
- for(idx = 1; idx < qdcount; idx++) {
+ for (idx = 1; idx < qdcount; idx++) {
rrname = pr.getName();
rrtype = pr.get16BitInt();
rrclass = pr.get16BitInt();
- (void) rrtype;
- (void) rrclass;
+ (void)rrtype;
+ (void)rrclass;
}
}
pw.startRecord(rrname, ah.d_type, ah.d_ttl, ah.d_class, DNSResourceRecord::ADDITIONAL, true);
pr.xfrBlob(blob);
pw.xfrBlob(blob);
- } else {
+ }
+ else {
ednsAdded = false;
pr.xfrBlob(blob);
uint64_t numrecords = ntohs(dh->ancount) + ntohs(dh->nscount) + ntohs(dh->arcount);
DNSPacketMangler dpm(const_cast<char*>(reinterpret_cast<const char*>(&packet.at(0))), packet.size());
uint64_t n;
- for(n=0; n < ntohs(dh->qdcount) ; ++n) {
+ for (n = 0; n < ntohs(dh->qdcount); ++n) {
dpm.skipDomainName();
/* type and class */
dpm.skipBytes(4);
}
- for(n=0; n < numrecords; ++n) {
+ for (n = 0; n < numrecords; ++n) {
dpm.skipDomainName();
uint8_t section = n < ntohs(dh->ancount) ? 1 : (n < (ntohs(dh->ancount) + ntohs(dh->nscount)) ? 2 : 3);
dpm.get16BitInt();
dpm.skipBytes(4); /* TTL */
- if(section == 3 && dnstype == QType::OPT) {
+ if (section == 3 && dnstype == QType::OPT) {
uint32_t offset = dpm.getOffset();
if (offset >= packet.size()) {
return false;
}
}
}
- catch(...)
- {
+ catch (...) {
return false;
}
return true;
}
-int locateEDNSOptRR(const PacketBuffer& packet, uint16_t * optStart, size_t * optLen, bool * last)
+int locateEDNSOptRR(const PacketBuffer& packet, uint16_t* optStart, size_t* optLen, bool* last)
{
assert(optStart != NULL);
assert(optLen != NULL);
struct dnsrecordheader ah;
/* consume qd */
- for(idx = 0; idx < qdcount; idx++) {
+ for (idx = 0; idx < qdcount; idx++) {
rrname = pr.getName();
rrtype = pr.get16BitInt();
rrclass = pr.get16BitInt();
- (void) rrtype;
- (void) rrclass;
+ (void)rrtype;
+ (void)rrclass;
}
/* consume AN and NS */
throw std::range_error("Opt record overflow");
}
- if (idx == ((size_t) arcount - 1)) {
+ if (idx == ((size_t)arcount - 1)) {
*last = true;
}
else {
}
pos += 1;
- uint16_t qtype = packet.at(pos)*256 + packet.at(pos+1);
+ uint16_t qtype = packet.at(pos) * 256 + packet.at(pos + 1);
pos += DNS_TYPE_SIZE;
pos += DNS_CLASS_SIZE;
}
return replaceEDNSClientSubnetOption(packet, maximumSize, optRDPosition + ecsOptionStartPosition, ecsOptionSize, optRDPosition, newECSOption);
- } else {
+ }
+ else {
/* we have an EDNS OPT RR but no existing ECS option */
return addECSToExistingOPT(packet, maximumSize, newECSOption, optRDPosition, ecsAdded);
}
size_t pos = 0;
while ((pos + 4) <= optionsLen) {
unsigned char* optionBegin = p;
- const uint16_t optionCode = 0x100*p[0] + p[1];
+ const uint16_t optionCode = 0x100 * p[0] + p[1];
p += sizeof(optionCode);
pos += sizeof(optionCode);
- const uint16_t optionLen = 0x100*p[0] + p[1];
+ const uint16_t optionLen = 0x100 * p[0] + p[1];
p += sizeof(optionLen);
pos += sizeof(optionLen);
if ((pos + optionLen) > optionsLen) {
if (*optLen < optRecordMinimumSize) {
return EINVAL;
}
- const unsigned char* end = (const unsigned char*) optStart + *optLen;
- unsigned char* p = (unsigned char*) optStart + 9;
+ const unsigned char* end = (const unsigned char*)optStart + *optLen;
+ unsigned char* p = (unsigned char*)optStart + 9;
unsigned char* rdLenPtr = p;
- uint16_t rdLen = (0x100*p[0] + p[1]);
+ uint16_t rdLen = (0x100 * p[0] + p[1]);
p += sizeof(rdLen);
if (p + rdLen != end) {
return EINVAL;
return false;
}
size_t p = optStart + 9;
- uint16_t rdLen = (0x100*static_cast<unsigned char>(packet.at(p)) + static_cast<unsigned char>(packet.at(p+1)));
+ uint16_t rdLen = (0x100 * static_cast<unsigned char>(packet.at(p)) + static_cast<unsigned char>(packet.at(p + 1)));
p += sizeof(rdLen);
if (rdLen > (optLen - optRecordMinimumSize)) {
return false;
size_t rdEnd = p + rdLen;
while ((p + 4) <= rdEnd) {
- const uint16_t optionCode = 0x100*static_cast<unsigned char>(packet.at(p)) + static_cast<unsigned char>(packet.at(p+1));
+ const uint16_t optionCode = 0x100 * static_cast<unsigned char>(packet.at(p)) + static_cast<unsigned char>(packet.at(p + 1));
p += sizeof(optionCode);
- const uint16_t optionLen = 0x100*static_cast<unsigned char>(packet.at(p)) + static_cast<unsigned char>(packet.at(p+1));
+ const uint16_t optionLen = 0x100 * static_cast<unsigned char>(packet.at(p)) + static_cast<unsigned char>(packet.at(p + 1));
p += sizeof(optionLen);
if ((p + optionLen) > rdEnd) {
rrclass = pr.get16BitInt();
GenericDNSPacketWriter<PacketBuffer> pw(newContent, rrname, rrtype, rrclass, dh->opcode);
- pw.getHeader()->id=dh->id;
- pw.getHeader()->qr=dh->qr;
- pw.getHeader()->aa=dh->aa;
- pw.getHeader()->tc=dh->tc;
- pw.getHeader()->rd=dh->rd;
- pw.getHeader()->ra=dh->ra;
- pw.getHeader()->ad=dh->ad;
- pw.getHeader()->cd=dh->cd;
- pw.getHeader()->rcode=dh->rcode;
+ pw.getHeader()->id = dh->id;
+ pw.getHeader()->qr = dh->qr;
+ pw.getHeader()->aa = dh->aa;
+ pw.getHeader()->tc = dh->tc;
+ pw.getHeader()->rd = dh->rd;
+ pw.getHeader()->ra = dh->ra;
+ pw.getHeader()->ad = dh->ad;
+ pw.getHeader()->cd = dh->cd;
+ pw.getHeader()->rcode = dh->rcode;
/* consume remaining qd if any */
if (qdcount > 1) {
- for(idx = 1; idx < qdcount; idx++) {
+ for (idx = 1; idx < qdcount; idx++) {
rrname = pr.getName();
rrtype = pr.get16BitInt();
rrclass = pr.get16BitInt();
- (void) rrtype;
- (void) rrclass;
+ (void)rrtype;
+ (void)rrclass;
}
}
pw.startRecord(rrname, ah.d_type, ah.d_ttl, ah.d_class, DNSResourceRecord::ADDITIONAL, true);
pr.xfrBlob(blob);
pw.xfrBlob(blob);
- } else {
+ }
+ else {
pw.startRecord(rrname, ah.d_type, ah.d_ttl, ah.d_class, DNSResourceRecord::ADDITIONAL, false);
pr.xfrBlob(blob);
uint16_t rdLen = blob.length();
if (rdLen > 0) {
blob.resize((size_t)rdLen);
pw.xfrBlob(blob);
- } else {
+ }
+ else {
pw.commit();
}
}
dnsdist::PacketMangling::editDNSHeaderFromPacket(packet, [soaInAuthoritySection](dnsheader& header) {
if (soaInAuthoritySection) {
header.nscount = htons(1);
- } else {
+ }
+ else {
header.arcount = htons(1);
}
return true;
// goal in life - if you send us a reasonably normal packet, we'll get Z for you, otherwise 0
int getEDNSZ(const DNSQuestion& dq)
{
- try
- {
+ try {
const auto& dh = dq.getHeader();
if (ntohs(dh->qdcount) != 1 || dh->ancount != 0 || ntohs(dh->arcount) != 1 || dh->nscount != 0) {
return 0;
pos++;
- uint16_t qtype = packet.at(pos)*256 + packet.at(pos+1);
+ uint16_t qtype = packet.at(pos) * 256 + packet.at(pos + 1);
pos += DNS_TYPE_SIZE;
pos += DNS_CLASS_SIZE;
}
const uint8_t* z = &packet.at(pos + EDNS_EXTENDED_RCODE_SIZE + EDNS_VERSION_SIZE);
- return 0x100 * (*z) + *(z+1);
+ return 0x100 * (*z) + *(z + 1);
}
- catch(...)
- {
+ catch (...) {
return 0;
}
}
return true;
}
-namespace dnsdist {
-bool setInternalQueryRCode(InternalQueryState& state, PacketBuffer& buffer, uint8_t rcode, bool clearAnswers)
+namespace dnsdist
+{
+bool setInternalQueryRCode(InternalQueryState& state, PacketBuffer& buffer, uint8_t rcode, bool clearAnswers)
{
const auto qnameLength = state.qname.wirelength();
if (buffer.size() < sizeof(dnsheader) + qnameLength + sizeof(uint16_t) + sizeof(uint16_t)) {
hadEDNS = getEDNS0Record(buffer, edns0);
}
- dnsdist::PacketMangling::editDNSHeaderFromPacket(buffer, [rcode,clearAnswers](dnsheader& header) {
+ dnsdist::PacketMangling::editDNSHeaderFromPacket(buffer, [rcode, clearAnswers](dnsheader& header) {
header.rcode = rcode;
header.ad = false;
header.aa = false;
int rewriteResponseWithoutEDNS(const PacketBuffer& initialPacket, PacketBuffer& newContent);
bool slowRewriteEDNSOptionInQueryWithRecords(const PacketBuffer& initialPacket, PacketBuffer& newContent, bool& ednsAdded, uint16_t optionToReplace, bool& optionAdded, bool overrideExisting, const string& newOptionContent);
-int locateEDNSOptRR(const PacketBuffer & packet, uint16_t * optStart, size_t * optLen, bool * last);
+int locateEDNSOptRR(const PacketBuffer& packet, uint16_t* optStart, size_t* optLen, bool* last);
bool generateOptRR(const std::string& optRData, PacketBuffer& res, size_t maximumSize, uint16_t udpPayloadSize, uint8_t ednsrcode, bool dnssecOK);
void generateECSOption(const ComboAddress& source, string& res, uint16_t ECSPrefixLength);
int removeEDNSOptionFromOPT(char* optStart, size_t* optLen, const uint16_t optionCodeToRemove);
int rewriteResponseWithoutEDNSOption(const PacketBuffer& initialPacket, const uint16_t optionCodeToSkip, PacketBuffer& newContent);
-int getEDNSOptionsStart(const PacketBuffer& packet, const size_t offset, uint16_t* optRDPosition, size_t * remaining);
+int getEDNSOptionsStart(const PacketBuffer& packet, const size_t offset, uint16_t* optRDPosition, size_t* remaining);
bool isEDNSOptionInOpt(const PacketBuffer& packet, const size_t optStart, const size_t optLen, const uint16_t optionCodeToFind, size_t* optContentStart = nullptr, uint16_t* optContentLen = nullptr);
bool addEDNS(PacketBuffer& packet, size_t maximumSize, bool dnssecOK, uint16_t payloadSize, uint8_t ednsrcode);
bool addEDNSToQueryTurnedResponse(DNSQuestion& dq);
bool setEDNSOption(DNSQuestion& dq, uint16_t ednsCode, const std::string& data);
struct InternalQueryState;
-namespace dnsdist {
-bool setInternalQueryRCode(InternalQueryState& state, PacketBuffer& buffer, uint8_t rcode, bool clearAnswers);
+namespace dnsdist
+{
+bool setInternalQueryRCode(InternalQueryState& state, PacketBuffer& buffer, uint8_t rcode, bool clearAnswers);
}
class ServerPolicy
{
public:
- template <class T> using NumberedVector = std::vector<std::pair<unsigned int, T> >;
+ template <class T>
+ using NumberedVector = std::vector<std::pair<unsigned int, T>>;
using NumberedServerVector = NumberedVector<shared_ptr<DownstreamState>>;
typedef std::function<shared_ptr<DownstreamState>(const NumberedServerVector& servers, const DNSQuestion*)> policyfunc_t;
typedef std::function<unsigned int(dnsdist_ffi_servers_list_t* servers, dnsdist_ffi_dnsquestion_t* dq)> ffipolicyfunc_t;
- ServerPolicy(const std::string& name_, policyfunc_t policy_, bool isLua_): d_name(name_), d_policy(std::move(policy_)), d_isLua(isLua_)
+ ServerPolicy(const std::string& name_, policyfunc_t policy_, bool isLua_) :
+ d_name(name_), d_policy(std::move(policy_)), d_isLua(isLua_)
{
}
- ServerPolicy(const std::string& name_, ffipolicyfunc_t policy_): d_name(name_), d_ffipolicy(std::move(policy_)), d_isLua(true), d_isFFI(true)
+ ServerPolicy(const std::string& name_, ffipolicyfunc_t policy_) :
+ d_name(name_), d_ffipolicy(std::move(policy_)), d_isLua(true), d_isFFI(true)
{
}
return d_name;
}
- std::string toString() const {
+ std::string toString() const
+ {
return string("ServerPolicy") + (d_isLua ? " (Lua)" : "") + " \"" + d_name + "\"";
}
const ffipolicyfunc_t& getPerThreadPolicy() const;
static thread_local PerThreadState t_perThreadState;
-
public:
std::string d_name;
std::string d_perThreadPolicyCode;
void addServerToPool(pools_t& pools, const string& poolName, std::shared_ptr<DownstreamState> server);
void removeServerFromPool(pools_t& pools, const string& poolName, std::shared_ptr<DownstreamState> server);
-const std::shared_ptr<const ServerPolicy::NumberedServerVector> getDownstreamCandidates(const map<std::string,std::shared_ptr<ServerPool>>& pools, const std::string& poolName);
+const std::shared_ptr<const ServerPolicy::NumberedServerVector> getDownstreamCandidates(const map<std::string, std::shared_ptr<ServerPool>>& pools, const std::string& poolName);
std::shared_ptr<DownstreamState> firstAvailable(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dq);
#ifndef DISABLE_NON_FFI_DQ_BINDINGS
/* DNSQuestion */
/* PowerDNS DNSQuestion compat */
- luaCtx.registerMember<const ComboAddress (DNSQuestion::*)>("localaddr", [](const DNSQuestion& dq) -> const ComboAddress { return dq.ids.origDest; }, [](DNSQuestion& dq, const ComboAddress newLocal) { (void) newLocal; });
- luaCtx.registerMember<const DNSName (DNSQuestion::*)>("qname", [](const DNSQuestion& dq) -> const DNSName { return dq.ids.qname; }, [](DNSQuestion& dq, const DNSName& newName) { (void) newName; });
- luaCtx.registerMember<uint16_t (DNSQuestion::*)>("qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.ids.qtype; }, [](DNSQuestion& dq, uint16_t newType) { (void) newType; });
- luaCtx.registerMember<uint16_t (DNSQuestion::*)>("qclass", [](const DNSQuestion& dq) -> uint16_t { return dq.ids.qclass; }, [](DNSQuestion& dq, uint16_t newClass) { (void) newClass; });
- luaCtx.registerMember<int (DNSQuestion::*)>("rcode", [](const DNSQuestion& dq) -> int { return static_cast<int>(dq.getHeader()->rcode); }, [](DNSQuestion& dq, int newRCode) {
- dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [newRCode](dnsheader& header) {
- header.rcode = static_cast<decltype(header.rcode)>(newRCode);
- return true;
- });
- });
- luaCtx.registerMember<const ComboAddress (DNSQuestion::*)>("remoteaddr", [](const DNSQuestion& dq) -> const ComboAddress { return dq.ids.origRemote; }, [](DNSQuestion& dq, const ComboAddress newRemote) { (void) newRemote; });
+ luaCtx.registerMember<const ComboAddress(DNSQuestion::*)>(
+ "localaddr", [](const DNSQuestion& dq) -> const ComboAddress { return dq.ids.origDest; }, [](DNSQuestion& dq, const ComboAddress newLocal) { (void)newLocal; });
+ luaCtx.registerMember<const DNSName(DNSQuestion::*)>(
+ "qname", [](const DNSQuestion& dq) -> const DNSName { return dq.ids.qname; }, [](DNSQuestion& dq, const DNSName& newName) { (void)newName; });
+ luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
+ "qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.ids.qtype; }, [](DNSQuestion& dq, uint16_t newType) { (void)newType; });
+ luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
+ "qclass", [](const DNSQuestion& dq) -> uint16_t { return dq.ids.qclass; }, [](DNSQuestion& dq, uint16_t newClass) { (void)newClass; });
+ luaCtx.registerMember<int(DNSQuestion::*)>(
+ "rcode", [](const DNSQuestion& dq) -> int { return static_cast<int>(dq.getHeader()->rcode); }, [](DNSQuestion& dq, int newRCode) { dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [newRCode](dnsheader& header) {
+ header.rcode = static_cast<decltype(header.rcode)>(newRCode);
+ return true;
+ }); });
+ luaCtx.registerMember<const ComboAddress(DNSQuestion::*)>(
+ "remoteaddr", [](const DNSQuestion& dq) -> const ComboAddress { return dq.ids.origRemote; }, [](DNSQuestion& dq, const ComboAddress newRemote) { (void)newRemote; });
/* DNSDist DNSQuestion */
- luaCtx.registerMember<dnsheader* (DNSQuestion::*)>("dh", [](const DNSQuestion& dq) -> dnsheader* { return dq.getMutableHeader(); }, [](DNSQuestion& dq, const dnsheader* dh) {
- dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [&dh](dnsheader& header) {
- header = *dh;
- return true;
- });
- });
- luaCtx.registerMember<uint16_t (DNSQuestion::*)>("len", [](const DNSQuestion& dq) -> uint16_t { return dq.getData().size(); }, [](DNSQuestion& dq, uint16_t newlen) { dq.getMutableData().resize(newlen); });
- luaCtx.registerMember<uint8_t (DNSQuestion::*)>("opcode", [](const DNSQuestion& dq) -> uint8_t { return dq.getHeader()->opcode; }, [](DNSQuestion& dq, uint8_t newOpcode) { (void) newOpcode; });
- luaCtx.registerMember<bool (DNSQuestion::*)>("tcp", [](const DNSQuestion& dq) -> bool { return dq.overTCP(); }, [](DNSQuestion& dq, bool newTcp) { (void) newTcp; });
- luaCtx.registerMember<bool (DNSQuestion::*)>("skipCache", [](const DNSQuestion& dq) -> bool { return dq.ids.skipCache; }, [](DNSQuestion& dq, bool newSkipCache) { dq.ids.skipCache = newSkipCache; });
- luaCtx.registerMember<std::string (DNSQuestion::*)>("pool", [](const DNSQuestion& dq) -> std::string { return dq.ids.poolName; }, [](DNSQuestion& dq, const std::string& newPoolName) { dq.ids.poolName = newPoolName; });
- luaCtx.registerMember<bool (DNSQuestion::*)>("useECS", [](const DNSQuestion& dq) -> bool { return dq.useECS; }, [](DNSQuestion& dq, bool useECS) { dq.useECS = useECS; });
- luaCtx.registerMember<bool (DNSQuestion::*)>("ecsOverride", [](const DNSQuestion& dq) -> bool { return dq.ecsOverride; }, [](DNSQuestion& dq, bool ecsOverride) { dq.ecsOverride = ecsOverride; });
- luaCtx.registerMember<uint16_t (DNSQuestion::*)>("ecsPrefixLength", [](const DNSQuestion& dq) -> uint16_t { return dq.ecsPrefixLength; }, [](DNSQuestion& dq, uint16_t newPrefixLength) { dq.ecsPrefixLength = newPrefixLength; });
- luaCtx.registerMember<boost::optional<uint32_t> (DNSQuestion::*)>("tempFailureTTL",
- [](const DNSQuestion& dq) -> boost::optional<uint32_t> {
- return dq.ids.tempFailureTTL;
- },
- [](DNSQuestion& dq, boost::optional<uint32_t> newValue) {
- dq.ids.tempFailureTTL = newValue;
- }
- );
- luaCtx.registerMember<std::string (DNSQuestion::*)>("deviceID", [](const DNSQuestion& dq) -> std::string {
+ luaCtx.registerMember<dnsheader*(DNSQuestion::*)>(
+ "dh", [](const DNSQuestion& dq) -> dnsheader* { return dq.getMutableHeader(); }, [](DNSQuestion& dq, const dnsheader* dh) { dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [&dh](dnsheader& header) {
+ header = *dh;
+ return true;
+ }); });
+ luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
+ "len", [](const DNSQuestion& dq) -> uint16_t { return dq.getData().size(); }, [](DNSQuestion& dq, uint16_t newlen) { dq.getMutableData().resize(newlen); });
+ luaCtx.registerMember<uint8_t(DNSQuestion::*)>(
+ "opcode", [](const DNSQuestion& dq) -> uint8_t { return dq.getHeader()->opcode; }, [](DNSQuestion& dq, uint8_t newOpcode) { (void)newOpcode; });
+ luaCtx.registerMember<bool(DNSQuestion::*)>(
+ "tcp", [](const DNSQuestion& dq) -> bool { return dq.overTCP(); }, [](DNSQuestion& dq, bool newTcp) { (void)newTcp; });
+ luaCtx.registerMember<bool(DNSQuestion::*)>(
+ "skipCache", [](const DNSQuestion& dq) -> bool { return dq.ids.skipCache; }, [](DNSQuestion& dq, bool newSkipCache) { dq.ids.skipCache = newSkipCache; });
+ luaCtx.registerMember<std::string(DNSQuestion::*)>(
+ "pool", [](const DNSQuestion& dq) -> std::string { return dq.ids.poolName; }, [](DNSQuestion& dq, const std::string& newPoolName) { dq.ids.poolName = newPoolName; });
+ luaCtx.registerMember<bool(DNSQuestion::*)>(
+ "useECS", [](const DNSQuestion& dq) -> bool { return dq.useECS; }, [](DNSQuestion& dq, bool useECS) { dq.useECS = useECS; });
+ luaCtx.registerMember<bool(DNSQuestion::*)>(
+ "ecsOverride", [](const DNSQuestion& dq) -> bool { return dq.ecsOverride; }, [](DNSQuestion& dq, bool ecsOverride) { dq.ecsOverride = ecsOverride; });
+ luaCtx.registerMember<uint16_t(DNSQuestion::*)>(
+ "ecsPrefixLength", [](const DNSQuestion& dq) -> uint16_t { return dq.ecsPrefixLength; }, [](DNSQuestion& dq, uint16_t newPrefixLength) { dq.ecsPrefixLength = newPrefixLength; });
+ luaCtx.registerMember<boost::optional<uint32_t>(DNSQuestion::*)>(
+ "tempFailureTTL",
+ [](const DNSQuestion& dq) -> boost::optional<uint32_t> {
+ return dq.ids.tempFailureTTL;
+ },
+ [](DNSQuestion& dq, boost::optional<uint32_t> newValue) {
+ dq.ids.tempFailureTTL = newValue;
+ });
+ luaCtx.registerMember<std::string(DNSQuestion::*)>(
+ "deviceID", [](const DNSQuestion& dq) -> std::string {
if (dq.ids.d_protoBufData) {
return dq.ids.d_protoBufData->d_deviceID;
}
- return std::string();
- }, [](DNSQuestion& dq, const std::string& newValue) {
+ return std::string(); }, [](DNSQuestion& dq, const std::string& newValue) {
if (!dq.ids.d_protoBufData) {
dq.ids.d_protoBufData = std::make_unique<InternalQueryState::ProtoBufData>();
}
- dq.ids.d_protoBufData->d_deviceID = newValue;
- });
- luaCtx.registerMember<std::string (DNSQuestion::*)>("deviceName", [](const DNSQuestion& dq) -> std::string {
+ dq.ids.d_protoBufData->d_deviceID = newValue; });
+ luaCtx.registerMember<std::string(DNSQuestion::*)>(
+ "deviceName", [](const DNSQuestion& dq) -> std::string {
if (dq.ids.d_protoBufData) {
return dq.ids.d_protoBufData->d_deviceName;
}
- return std::string();
- }, [](DNSQuestion& dq, const std::string& newValue) {
+ return std::string(); }, [](DNSQuestion& dq, const std::string& newValue) {
if (!dq.ids.d_protoBufData) {
dq.ids.d_protoBufData = std::make_unique<InternalQueryState::ProtoBufData>();
}
- dq.ids.d_protoBufData->d_deviceName = newValue;
- });
- luaCtx.registerMember<std::string (DNSQuestion::*)>("requestorID", [](const DNSQuestion& dq) -> std::string {
+ dq.ids.d_protoBufData->d_deviceName = newValue; });
+ luaCtx.registerMember<std::string(DNSQuestion::*)>(
+ "requestorID", [](const DNSQuestion& dq) -> std::string {
if (dq.ids.d_protoBufData) {
return dq.ids.d_protoBufData->d_requestorID;
}
- return std::string();
- }, [](DNSQuestion& dq, const std::string& newValue) {
+ return std::string(); }, [](DNSQuestion& dq, const std::string& newValue) {
if (!dq.ids.d_protoBufData) {
dq.ids.d_protoBufData = std::make_unique<InternalQueryState::ProtoBufData>();
}
- dq.ids.d_protoBufData->d_requestorID = newValue;
- });
- luaCtx.registerFunction<bool(DNSQuestion::*)()const>("getDO", [](const DNSQuestion& dq) {
+ dq.ids.d_protoBufData->d_requestorID = newValue; });
+ luaCtx.registerFunction<bool (DNSQuestion::*)() const>("getDO", [](const DNSQuestion& dq) {
return getEDNSZ(dq) & EDNS_HEADER_FLAG_DO;
- });
- luaCtx.registerFunction<std::string(DNSQuestion::*)()const>("getContent", [](const DNSQuestion& dq) {
+ });
+ luaCtx.registerFunction<std::string (DNSQuestion::*)() const>("getContent", [](const DNSQuestion& dq) {
return std::string(reinterpret_cast<const char*>(dq.getData().data()), dq.getData().size());
});
- luaCtx.registerFunction<void(DNSQuestion::*)(const std::string&)>("setContent", [](DNSQuestion& dq, const std::string& raw) {
+ luaCtx.registerFunction<void (DNSQuestion::*)(const std::string&)>("setContent", [](DNSQuestion& dq, const std::string& raw) {
uint16_t oldID = dq.getHeader()->id;
auto& buffer = dq.getMutableData();
buffer.clear();
return true;
});
});
- luaCtx.registerFunction<std::map<uint16_t, EDNSOptionView>(DNSQuestion::*)()const>("getEDNSOptions", [](const DNSQuestion& dq) {
+ luaCtx.registerFunction<std::map<uint16_t, EDNSOptionView> (DNSQuestion::*)() const>("getEDNSOptions", [](const DNSQuestion& dq) {
+ if (dq.ednsOptions == nullptr) {
+ parseEDNSOptions(dq);
if (dq.ednsOptions == nullptr) {
- parseEDNSOptions(dq);
- if (dq.ednsOptions == nullptr) {
- throw std::runtime_error("parseEDNSOptions should have populated the EDNS options");
- }
+ throw std::runtime_error("parseEDNSOptions should have populated the EDNS options");
}
+ }
- return *dq.ednsOptions;
- });
- luaCtx.registerFunction<std::string(DNSQuestion::*)(void)const>("getTrailingData", [](const DNSQuestion& dq) {
- return dq.getTrailingData();
- });
- luaCtx.registerFunction<bool(DNSQuestion::*)(std::string)>("setTrailingData", [](DNSQuestion& dq, const std::string& tail) {
- return dq.setTrailingData(tail);
- });
+ return *dq.ednsOptions;
+ });
+ luaCtx.registerFunction<std::string (DNSQuestion::*)(void) const>("getTrailingData", [](const DNSQuestion& dq) {
+ return dq.getTrailingData();
+ });
+ luaCtx.registerFunction<bool (DNSQuestion::*)(std::string)>("setTrailingData", [](DNSQuestion& dq, const std::string& tail) {
+ return dq.setTrailingData(tail);
+ });
- luaCtx.registerFunction<std::string(DNSQuestion::*)()const>("getServerNameIndication", [](const DNSQuestion& dq) {
- return dq.sni;
- });
+ luaCtx.registerFunction<std::string (DNSQuestion::*)() const>("getServerNameIndication", [](const DNSQuestion& dq) {
+ return dq.sni;
+ });
- luaCtx.registerFunction<std::string (DNSQuestion::*)()const>("getProtocol", [](const DNSQuestion& dq) {
+ luaCtx.registerFunction<std::string (DNSQuestion::*)() const>("getProtocol", [](const DNSQuestion& dq) {
return dq.getProtocol().toPrettyString();
});
- luaCtx.registerFunction<timespec(DNSQuestion::*)()const>("getQueryTime", [](const DNSQuestion& dq) {
+ luaCtx.registerFunction<timespec (DNSQuestion::*)() const>("getQueryTime", [](const DNSQuestion& dq) {
return dq.ids.queryRealTime.getStartTime();
});
- luaCtx.registerFunction<void(DNSQuestion::*)(std::string)>("sendTrap", [](const DNSQuestion& dq, boost::optional<std::string> reason) {
+ luaCtx.registerFunction<void (DNSQuestion::*)(std::string)>("sendTrap", [](const DNSQuestion& dq, boost::optional<std::string> reason) {
#ifdef HAVE_NET_SNMP
- if (g_snmpAgent && g_snmpTrapsEnabled) {
- g_snmpAgent->sendDNSTrap(dq, reason ? *reason : "");
- }
+ if (g_snmpAgent && g_snmpTrapsEnabled) {
+ g_snmpAgent->sendDNSTrap(dq, reason ? *reason : "");
+ }
#endif /* HAVE_NET_SNMP */
- });
+ });
- luaCtx.registerFunction<void(DNSQuestion::*)(std::string, std::string)>("setTag", [](DNSQuestion& dq, const std::string& strLabel, const std::string& strValue) {
- dq.setTag(strLabel, strValue);
- });
- luaCtx.registerFunction<void(DNSQuestion::*)(LuaAssociativeTable<std::string>)>("setTagArray", [](DNSQuestion& dq, const LuaAssociativeTable<std::string>&tags) {
- for (const auto& tag : tags) {
- dq.setTag(tag.first, tag.second);
- }
- });
- luaCtx.registerFunction<string(DNSQuestion::*)(std::string)const>("getTag", [](const DNSQuestion& dq, const std::string& strLabel) {
- if (!dq.ids.qTag) {
- return string();
- }
+ luaCtx.registerFunction<void (DNSQuestion::*)(std::string, std::string)>("setTag", [](DNSQuestion& dq, const std::string& strLabel, const std::string& strValue) {
+ dq.setTag(strLabel, strValue);
+ });
+ luaCtx.registerFunction<void (DNSQuestion::*)(LuaAssociativeTable<std::string>)>("setTagArray", [](DNSQuestion& dq, const LuaAssociativeTable<std::string>& tags) {
+ for (const auto& tag : tags) {
+ dq.setTag(tag.first, tag.second);
+ }
+ });
+ luaCtx.registerFunction<string (DNSQuestion::*)(std::string) const>("getTag", [](const DNSQuestion& dq, const std::string& strLabel) {
+ if (!dq.ids.qTag) {
+ return string();
+ }
- std::string strValue;
- const auto it = dq.ids.qTag->find(strLabel);
- if (it == dq.ids.qTag->cend()) {
- return string();
- }
- return it->second;
- });
- luaCtx.registerFunction<QTag(DNSQuestion::*)(void)const>("getTagArray", [](const DNSQuestion& dq) {
- if (!dq.ids.qTag) {
- QTag empty;
- return empty;
- }
+ std::string strValue;
+ const auto it = dq.ids.qTag->find(strLabel);
+ if (it == dq.ids.qTag->cend()) {
+ return string();
+ }
+ return it->second;
+ });
+ luaCtx.registerFunction<QTag (DNSQuestion::*)(void) const>("getTagArray", [](const DNSQuestion& dq) {
+ if (!dq.ids.qTag) {
+ QTag empty;
+ return empty;
+ }
- return *dq.ids.qTag;
- });
+ return *dq.ids.qTag;
+ });
- luaCtx.registerFunction<void(DNSQuestion::*)(LuaArray<std::string>)>("setProxyProtocolValues", [](DNSQuestion& dq, const LuaArray<std::string>& values) {
+ luaCtx.registerFunction<void (DNSQuestion::*)(LuaArray<std::string>)>("setProxyProtocolValues", [](DNSQuestion& dq, const LuaArray<std::string>& values) {
if (!dq.proxyProtocolValues) {
dq.proxyProtocolValues = make_unique<std::vector<ProxyProtocolValue>>();
}
}
});
- luaCtx.registerFunction<void(DNSQuestion::*)(uint64_t, std::string)>("addProxyProtocolValue", [](DNSQuestion& dq, uint64_t type, std::string value) {
+ luaCtx.registerFunction<void (DNSQuestion::*)(uint64_t, std::string)>("addProxyProtocolValue", [](DNSQuestion& dq, uint64_t type, std::string value) {
checkParameterBound("addProxyProtocolValue", type, std::numeric_limits<uint8_t>::max());
if (!dq.proxyProtocolValues) {
dq.proxyProtocolValues = make_unique<std::vector<ProxyProtocolValue>>();
dq.proxyProtocolValues->push_back({std::move(value), static_cast<uint8_t>(type)});
});
- luaCtx.registerFunction<LuaArray<std::string>(DNSQuestion::*)()>("getProxyProtocolValues", [](const DNSQuestion& dq) {
+ luaCtx.registerFunction<LuaArray<std::string> (DNSQuestion::*)()>("getProxyProtocolValues", [](const DNSQuestion& dq) {
LuaArray<std::string> result;
if (!dq.proxyProtocolValues) {
return result;
result.resize(dq.proxyProtocolValues->size());
for (const auto& value : *dq.proxyProtocolValues) {
- result.push_back({ value.type, value.content });
+ result.push_back({value.type, value.content});
}
return result;
});
- luaCtx.registerFunction<bool(DNSQuestion::*)(const DNSName& newName)>("changeName", [](DNSQuestion& dq, const DNSName& newName) -> bool {
+ luaCtx.registerFunction<bool (DNSQuestion::*)(const DNSName& newName)>("changeName", [](DNSQuestion& dq, const DNSName& newName) -> bool {
if (!dnsdist::changeNameInDNSPacket(dq.getMutableData(), dq.ids.qname, newName)) {
return false;
}
return true;
});
- luaCtx.registerFunction<void(DNSQuestion::*)(const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>&, boost::optional<uint16_t>)>("spoof", [](DNSQuestion& dnsQuestion, const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>& response, boost::optional<uint16_t> typeForAny) {
- if (response.type() == typeid(LuaArray<ComboAddress>)) {
- std::vector<ComboAddress> data;
- auto responses = boost::get<LuaArray<ComboAddress>>(response);
- data.reserve(responses.size());
- for (const auto& resp : responses) {
- data.push_back(resp.second);
- }
- std::string result;
- SpoofAction tempSpoofAction(data);
- tempSpoofAction(&dnsQuestion, &result);
- return;
+ luaCtx.registerFunction<void (DNSQuestion::*)(const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>&, boost::optional<uint16_t>)>("spoof", [](DNSQuestion& dnsQuestion, const boost::variant<LuaArray<ComboAddress>, LuaArray<std::string>>& response, boost::optional<uint16_t> typeForAny) {
+ if (response.type() == typeid(LuaArray<ComboAddress>)) {
+ std::vector<ComboAddress> data;
+ auto responses = boost::get<LuaArray<ComboAddress>>(response);
+ data.reserve(responses.size());
+ for (const auto& resp : responses) {
+ data.push_back(resp.second);
}
- if (response.type() == typeid(LuaArray<std::string>)) {
- std::vector<std::string> data;
- auto responses = boost::get<LuaArray<std::string>>(response);
- data.reserve(responses.size());
- for (const auto& resp : responses) {
- data.push_back(resp.second);
- }
- std::string result;
- SpoofAction tempSpoofAction(data, typeForAny ? *typeForAny : std::optional<uint16_t>());
- tempSpoofAction(&dnsQuestion, &result);
- return;
+ std::string result;
+ SpoofAction tempSpoofAction(data);
+ tempSpoofAction(&dnsQuestion, &result);
+ return;
+ }
+ if (response.type() == typeid(LuaArray<std::string>)) {
+ std::vector<std::string> data;
+ auto responses = boost::get<LuaArray<std::string>>(response);
+ data.reserve(responses.size());
+ for (const auto& resp : responses) {
+ data.push_back(resp.second);
}
+ std::string result;
+ SpoofAction tempSpoofAction(data, typeForAny ? *typeForAny : std::optional<uint16_t>());
+ tempSpoofAction(&dnsQuestion, &result);
+ return;
+ }
});
- luaCtx.registerFunction<void(DNSQuestion::*)(uint16_t code, const std::string&)>("setEDNSOption", [](DNSQuestion& dq, uint16_t code, const std::string& data) {
+ luaCtx.registerFunction<void (DNSQuestion::*)(uint16_t code, const std::string&)>("setEDNSOption", [](DNSQuestion& dq, uint16_t code, const std::string& data) {
setEDNSOption(dq, code, data);
});
- luaCtx.registerFunction<void(DNSQuestion::*)(uint16_t infoCode, const boost::optional<std::string>& extraText)>("setExtendedDNSError", [](DNSQuestion& dnsQuestion, uint16_t infoCode, const boost::optional<std::string>& extraText) {
+ luaCtx.registerFunction<void (DNSQuestion::*)(uint16_t infoCode, const boost::optional<std::string>& extraText)>("setExtendedDNSError", [](DNSQuestion& dnsQuestion, uint16_t infoCode, const boost::optional<std::string>& extraText) {
EDNSExtendedError ede;
ede.infoCode = infoCode;
if (extraText) {
dnsQuestion.ids.d_extendedError = std::make_unique<EDNSExtendedError>(ede);
});
- luaCtx.registerFunction<bool(DNSQuestion::*)(uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs)>("suspend", [](DNSQuestion& dq, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) {
+ luaCtx.registerFunction<bool (DNSQuestion::*)(uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs)>("suspend", [](DNSQuestion& dq, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) {
dq.asynchronous = true;
return dnsdist::suspendQuery(dq, asyncID, queryID, timeoutMs);
});
- luaCtx.registerFunction<bool(DNSQuestion::*)()>("setRestartable", [](DNSQuestion& dq) {
+ luaCtx.registerFunction<bool (DNSQuestion::*)()>("setRestartable", [](DNSQuestion& dq) {
dq.ids.d_packet = std::make_unique<PacketBuffer>(dq.getData());
return true;
});
-class AsynchronousObject
-{
-public:
- AsynchronousObject(std::unique_ptr<CrossProtocolQuery>&& obj_): object(std::move(obj_))
- {
- }
-
- DNSQuestion getDQ() const
+ class AsynchronousObject
{
- return object->getDQ();
- }
+ public:
+ AsynchronousObject(std::unique_ptr<CrossProtocolQuery>&& obj_) :
+ object(std::move(obj_))
+ {
+ }
- DNSResponse getDR() const
- {
- return object->getDR();
- }
+ DNSQuestion getDQ() const
+ {
+ return object->getDQ();
+ }
- bool resume()
- {
- return dnsdist::queueQueryResumptionEvent(std::move(object));
- }
+ DNSResponse getDR() const
+ {
+ return object->getDR();
+ }
- bool drop()
- {
- auto sender = object->getTCPQuerySender();
- if (!sender) {
- return false;
+ bool resume()
+ {
+ return dnsdist::queueQueryResumptionEvent(std::move(object));
}
- struct timeval now;
- gettimeofday(&now, nullptr);
- sender->notifyIOError(now, TCPResponse(std::move(object->query)));
- return true;
- }
+ bool drop()
+ {
+ auto sender = object->getTCPQuerySender();
+ if (!sender) {
+ return false;
+ }
- bool setRCode(uint8_t rcode, bool clearAnswers)
- {
- return dnsdist::setInternalQueryRCode(object->query.d_idstate, object->query.d_buffer, rcode, clearAnswers);
- }
+ struct timeval now;
+ gettimeofday(&now, nullptr);
+ sender->notifyIOError(now, TCPResponse(std::move(object->query)));
+ return true;
+ }
-private:
- std::unique_ptr<CrossProtocolQuery> object;
-};
+ bool setRCode(uint8_t rcode, bool clearAnswers)
+ {
+ return dnsdist::setInternalQueryRCode(object->query.d_idstate, object->query.d_buffer, rcode, clearAnswers);
+ }
- luaCtx.registerFunction<DNSQuestion(AsynchronousObject::*)(void) const>("getDQ", [](const AsynchronousObject& obj) {
- return obj.getDQ();
- });
+ private:
+ std::unique_ptr<CrossProtocolQuery> object;
+ };
- luaCtx.registerFunction<DNSQuestion(AsynchronousObject::*)(void) const>("getDR", [](const AsynchronousObject& obj) {
- return obj.getDR();
- });
+ luaCtx.registerFunction<DNSQuestion (AsynchronousObject::*)(void) const>("getDQ", [](const AsynchronousObject& obj) {
+ return obj.getDQ();
+ });
- luaCtx.registerFunction<bool(AsynchronousObject::*)(void)>("resume", [](AsynchronousObject& obj) {
- return obj.resume();
- });
+ luaCtx.registerFunction<DNSQuestion (AsynchronousObject::*)(void) const>("getDR", [](const AsynchronousObject& obj) {
+ return obj.getDR();
+ });
- luaCtx.registerFunction<bool(AsynchronousObject::*)(void)>("drop", [](AsynchronousObject& obj) {
- return obj.drop();
- });
+ luaCtx.registerFunction<bool (AsynchronousObject::*)(void)>("resume", [](AsynchronousObject& obj) {
+ return obj.resume();
+ });
+
+ luaCtx.registerFunction<bool (AsynchronousObject::*)(void)>("drop", [](AsynchronousObject& obj) {
+ return obj.drop();
+ });
- luaCtx.registerFunction<bool(AsynchronousObject::*)(uint8_t, bool)>("setRCode", [](AsynchronousObject& obj, uint8_t rcode, bool clearAnswers) {
+ luaCtx.registerFunction<bool (AsynchronousObject::*)(uint8_t, bool)>("setRCode", [](AsynchronousObject& obj, uint8_t rcode, bool clearAnswers) {
return obj.setRCode(rcode, clearAnswers);
});
});
/* LuaWrapper doesn't support inheritance */
- luaCtx.registerMember<const ComboAddress (DNSResponse::*)>("localaddr", [](const DNSResponse& dq) -> const ComboAddress { return dq.ids.origDest; }, [](DNSResponse& dq, const ComboAddress newLocal) { (void) newLocal; });
- luaCtx.registerMember<const DNSName (DNSResponse::*)>("qname", [](const DNSResponse& dq) -> const DNSName { return dq.ids.qname; }, [](DNSResponse& dq, const DNSName& newName) { (void) newName; });
- luaCtx.registerMember<uint16_t (DNSResponse::*)>("qtype", [](const DNSResponse& dq) -> uint16_t { return dq.ids.qtype; }, [](DNSResponse& dq, uint16_t newType) { (void) newType; });
- luaCtx.registerMember<uint16_t (DNSResponse::*)>("qclass", [](const DNSResponse& dq) -> uint16_t { return dq.ids.qclass; }, [](DNSResponse& dq, uint16_t newClass) { (void) newClass; });
- luaCtx.registerMember<int (DNSResponse::*)>("rcode", [](const DNSResponse& dq) -> int { return static_cast<int>(dq.getHeader()->rcode); }, [](DNSResponse& dq, int newRCode) {
- dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [newRCode](dnsheader& header) {
- header.rcode = static_cast<decltype(header.rcode)>(newRCode);
- return true;
- });
+ luaCtx.registerMember<const ComboAddress(DNSResponse::*)>(
+ "localaddr", [](const DNSResponse& dq) -> const ComboAddress { return dq.ids.origDest; }, [](DNSResponse& dq, const ComboAddress newLocal) { (void)newLocal; });
+ luaCtx.registerMember<const DNSName(DNSResponse::*)>(
+ "qname", [](const DNSResponse& dq) -> const DNSName { return dq.ids.qname; }, [](DNSResponse& dq, const DNSName& newName) { (void)newName; });
+ luaCtx.registerMember<uint16_t(DNSResponse::*)>(
+ "qtype", [](const DNSResponse& dq) -> uint16_t { return dq.ids.qtype; }, [](DNSResponse& dq, uint16_t newType) { (void)newType; });
+ luaCtx.registerMember<uint16_t(DNSResponse::*)>(
+ "qclass", [](const DNSResponse& dq) -> uint16_t { return dq.ids.qclass; }, [](DNSResponse& dq, uint16_t newClass) { (void)newClass; });
+ luaCtx.registerMember<int(DNSResponse::*)>(
+ "rcode", [](const DNSResponse& dq) -> int { return static_cast<int>(dq.getHeader()->rcode); }, [](DNSResponse& dq, int newRCode) { dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [newRCode](dnsheader& header) {
+ header.rcode = static_cast<decltype(header.rcode)>(newRCode);
+ return true;
+ }); });
+ luaCtx.registerMember<const ComboAddress(DNSResponse::*)>(
+ "remoteaddr", [](const DNSResponse& dq) -> const ComboAddress { return dq.ids.origRemote; }, [](DNSResponse& dq, const ComboAddress newRemote) { (void)newRemote; });
+ luaCtx.registerMember<dnsheader*(DNSResponse::*)>(
+ "dh", [](const DNSResponse& dr) -> dnsheader* { return dr.getMutableHeader(); }, [](DNSResponse& dr, const dnsheader* dh) { dnsdist::PacketMangling::editDNSHeaderFromPacket(dr.getMutableData(), [&dh](dnsheader& header) {
+ header = *dh;
+ return true;
+ }); });
+ luaCtx.registerMember<uint16_t(DNSResponse::*)>(
+ "len", [](const DNSResponse& dq) -> uint16_t { return dq.getData().size(); }, [](DNSResponse& dq, uint16_t newlen) { dq.getMutableData().resize(newlen); });
+ luaCtx.registerMember<uint8_t(DNSResponse::*)>(
+ "opcode", [](const DNSResponse& dq) -> uint8_t { return dq.getHeader()->opcode; }, [](DNSResponse& dq, uint8_t newOpcode) { (void)newOpcode; });
+ luaCtx.registerMember<bool(DNSResponse::*)>(
+ "tcp", [](const DNSResponse& dq) -> bool { return dq.overTCP(); }, [](DNSResponse& dq, bool newTcp) { (void)newTcp; });
+ luaCtx.registerMember<bool(DNSResponse::*)>(
+ "skipCache", [](const DNSResponse& dq) -> bool { return dq.ids.skipCache; }, [](DNSResponse& dq, bool newSkipCache) { dq.ids.skipCache = newSkipCache; });
+ luaCtx.registerMember<std::string(DNSResponse::*)>(
+ "pool", [](const DNSResponse& dq) -> std::string { return dq.ids.poolName; }, [](DNSResponse& dq, const std::string& newPoolName) { dq.ids.poolName = newPoolName; });
+ luaCtx.registerFunction<void (DNSResponse::*)(std::function<uint32_t(uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl)> editFunc)>("editTTLs", [](DNSResponse& dr, std::function<uint32_t(uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl)> editFunc) {
+ editDNSPacketTTL(reinterpret_cast<char*>(dr.getMutableData().data()), dr.getData().size(), editFunc);
});
- luaCtx.registerMember<const ComboAddress (DNSResponse::*)>("remoteaddr", [](const DNSResponse& dq) -> const ComboAddress { return dq.ids.origRemote; }, [](DNSResponse& dq, const ComboAddress newRemote) { (void) newRemote; });
- luaCtx.registerMember<dnsheader* (DNSResponse::*)>("dh", [](const DNSResponse& dr) -> dnsheader* { return dr.getMutableHeader(); }, [](DNSResponse& dr, const dnsheader* dh) {
- dnsdist::PacketMangling::editDNSHeaderFromPacket(dr.getMutableData(), [&dh](dnsheader& header) {
- header = *dh;
- return true;
- });
+ luaCtx.registerFunction<bool (DNSResponse::*)() const>("getDO", [](const DNSResponse& dq) {
+ return getEDNSZ(dq) & EDNS_HEADER_FLAG_DO;
});
- luaCtx.registerMember<uint16_t (DNSResponse::*)>("len", [](const DNSResponse& dq) -> uint16_t { return dq.getData().size(); }, [](DNSResponse& dq, uint16_t newlen) { dq.getMutableData().resize(newlen); });
- luaCtx.registerMember<uint8_t (DNSResponse::*)>("opcode", [](const DNSResponse& dq) -> uint8_t { return dq.getHeader()->opcode; }, [](DNSResponse& dq, uint8_t newOpcode) { (void) newOpcode; });
- luaCtx.registerMember<bool (DNSResponse::*)>("tcp", [](const DNSResponse& dq) -> bool { return dq.overTCP(); }, [](DNSResponse& dq, bool newTcp) { (void) newTcp; });
- luaCtx.registerMember<bool (DNSResponse::*)>("skipCache", [](const DNSResponse& dq) -> bool { return dq.ids.skipCache; }, [](DNSResponse& dq, bool newSkipCache) { dq.ids.skipCache = newSkipCache; });
- luaCtx.registerMember<std::string (DNSResponse::*)>("pool", [](const DNSResponse& dq) -> std::string { return dq.ids.poolName; }, [](DNSResponse& dq, const std::string& newPoolName) { dq.ids.poolName = newPoolName; });
- luaCtx.registerFunction<void(DNSResponse::*)(std::function<uint32_t(uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl)> editFunc)>("editTTLs", [](DNSResponse& dr, std::function<uint32_t(uint8_t section, uint16_t qclass, uint16_t qtype, uint32_t ttl)> editFunc) {
- editDNSPacketTTL(reinterpret_cast<char *>(dr.getMutableData().data()), dr.getData().size(), editFunc);
- });
- luaCtx.registerFunction<bool(DNSResponse::*)()const>("getDO", [](const DNSResponse& dq) {
- return getEDNSZ(dq) & EDNS_HEADER_FLAG_DO;
- });
- luaCtx.registerFunction<std::string(DNSResponse::*)()const>("getContent", [](const DNSResponse& dq) {
+ luaCtx.registerFunction<std::string (DNSResponse::*)() const>("getContent", [](const DNSResponse& dq) {
return std::string(reinterpret_cast<const char*>(dq.getData().data()), dq.getData().size());
});
- luaCtx.registerFunction<void(DNSResponse::*)(const std::string&)>("setContent", [](DNSResponse& dr, const std::string& raw) {
+ luaCtx.registerFunction<void (DNSResponse::*)(const std::string&)>("setContent", [](DNSResponse& dr, const std::string& raw) {
uint16_t oldID = dr.getHeader()->id;
auto& buffer = dr.getMutableData();
buffer.clear();
});
});
- luaCtx.registerFunction<std::map<uint16_t, EDNSOptionView>(DNSResponse::*)()const>("getEDNSOptions", [](const DNSResponse& dq) {
+ luaCtx.registerFunction<std::map<uint16_t, EDNSOptionView> (DNSResponse::*)() const>("getEDNSOptions", [](const DNSResponse& dq) {
+ if (dq.ednsOptions == nullptr) {
+ parseEDNSOptions(dq);
if (dq.ednsOptions == nullptr) {
- parseEDNSOptions(dq);
- if (dq.ednsOptions == nullptr) {
- throw std::runtime_error("parseEDNSOptions should have populated the EDNS options");
- }
+ throw std::runtime_error("parseEDNSOptions should have populated the EDNS options");
}
+ }
- return *dq.ednsOptions;
- });
- luaCtx.registerFunction<std::string(DNSResponse::*)(void)const>("getTrailingData", [](const DNSResponse& dq) {
- return dq.getTrailingData();
- });
- luaCtx.registerFunction<bool(DNSResponse::*)(std::string)>("setTrailingData", [](DNSResponse& dq, const std::string& tail) {
- return dq.setTrailingData(tail);
- });
+ return *dq.ednsOptions;
+ });
+ luaCtx.registerFunction<std::string (DNSResponse::*)(void) const>("getTrailingData", [](const DNSResponse& dq) {
+ return dq.getTrailingData();
+ });
+ luaCtx.registerFunction<bool (DNSResponse::*)(std::string)>("setTrailingData", [](DNSResponse& dq, const std::string& tail) {
+ return dq.setTrailingData(tail);
+ });
- luaCtx.registerFunction<void(DNSResponse::*)(std::string, std::string)>("setTag", [](DNSResponse& dr, const std::string& strLabel, const std::string& strValue) {
- dr.setTag(strLabel, strValue);
- });
+ luaCtx.registerFunction<void (DNSResponse::*)(std::string, std::string)>("setTag", [](DNSResponse& dr, const std::string& strLabel, const std::string& strValue) {
+ dr.setTag(strLabel, strValue);
+ });
- luaCtx.registerFunction<void(DNSResponse::*)(LuaAssociativeTable<std::string>)>("setTagArray", [](DNSResponse& dr, const LuaAssociativeTable<string>&tags) {
- for (const auto& tag : tags) {
- dr.setTag(tag.first, tag.second);
- }
- });
- luaCtx.registerFunction<string(DNSResponse::*)(std::string)const>("getTag", [](const DNSResponse& dr, const std::string& strLabel) {
- if (!dr.ids.qTag) {
- return string();
- }
+ luaCtx.registerFunction<void (DNSResponse::*)(LuaAssociativeTable<std::string>)>("setTagArray", [](DNSResponse& dr, const LuaAssociativeTable<string>& tags) {
+ for (const auto& tag : tags) {
+ dr.setTag(tag.first, tag.second);
+ }
+ });
+ luaCtx.registerFunction<string (DNSResponse::*)(std::string) const>("getTag", [](const DNSResponse& dr, const std::string& strLabel) {
+ if (!dr.ids.qTag) {
+ return string();
+ }
- std::string strValue;
- const auto it = dr.ids.qTag->find(strLabel);
- if (it == dr.ids.qTag->cend()) {
- return string();
- }
- return it->second;
- });
- luaCtx.registerFunction<QTag(DNSResponse::*)(void)const>("getTagArray", [](const DNSResponse& dr) {
- if (!dr.ids.qTag) {
- QTag empty;
- return empty;
- }
+ std::string strValue;
+ const auto it = dr.ids.qTag->find(strLabel);
+ if (it == dr.ids.qTag->cend()) {
+ return string();
+ }
+ return it->second;
+ });
+ luaCtx.registerFunction<QTag (DNSResponse::*)(void) const>("getTagArray", [](const DNSResponse& dr) {
+ if (!dr.ids.qTag) {
+ QTag empty;
+ return empty;
+ }
- return *dr.ids.qTag;
- });
+ return *dr.ids.qTag;
+ });
- luaCtx.registerFunction<std::string (DNSResponse::*)()const>("getProtocol", [](const DNSResponse& dr) {
+ luaCtx.registerFunction<std::string (DNSResponse::*)() const>("getProtocol", [](const DNSResponse& dr) {
return dr.getProtocol().toPrettyString();
});
- luaCtx.registerFunction<timespec(DNSResponse::*)()const>("getQueryTime", [](const DNSResponse& dr) {
+ luaCtx.registerFunction<timespec (DNSResponse::*)() const>("getQueryTime", [](const DNSResponse& dr) {
return dr.ids.queryRealTime.getStartTime();
});
- luaCtx.registerFunction<void(DNSResponse::*)(std::string)>("sendTrap", [](const DNSResponse& dr, boost::optional<std::string> reason) {
+ luaCtx.registerFunction<void (DNSResponse::*)(std::string)>("sendTrap", [](const DNSResponse& dr, boost::optional<std::string> reason) {
#ifdef HAVE_NET_SNMP
- if (g_snmpAgent && g_snmpTrapsEnabled) {
- g_snmpAgent->sendDNSTrap(dr, reason ? *reason : "");
- }
+ if (g_snmpAgent && g_snmpTrapsEnabled) {
+ g_snmpAgent->sendDNSTrap(dr, reason ? *reason : "");
+ }
#endif /* HAVE_NET_SNMP */
- });
+ });
#ifdef HAVE_DNS_OVER_HTTPS
- luaCtx.registerFunction<std::string(DNSQuestion::*)(void)const>("getHTTPPath", [](const DNSQuestion& dq) {
- if (dq.ids.du == nullptr) {
- return std::string();
- }
- return dq.ids.du->getHTTPPath();
- });
+ luaCtx.registerFunction<std::string (DNSQuestion::*)(void) const>("getHTTPPath", [](const DNSQuestion& dq) {
+ if (dq.ids.du == nullptr) {
+ return std::string();
+ }
+ return dq.ids.du->getHTTPPath();
+ });
- luaCtx.registerFunction<std::string(DNSQuestion::*)(void)const>("getHTTPQueryString", [](const DNSQuestion& dq) {
- if (dq.ids.du == nullptr) {
- return std::string();
- }
- return dq.ids.du->getHTTPQueryString();
- });
+ luaCtx.registerFunction<std::string (DNSQuestion::*)(void) const>("getHTTPQueryString", [](const DNSQuestion& dq) {
+ if (dq.ids.du == nullptr) {
+ return std::string();
+ }
+ return dq.ids.du->getHTTPQueryString();
+ });
- luaCtx.registerFunction<std::string(DNSQuestion::*)(void)const>("getHTTPHost", [](const DNSQuestion& dq) {
- if (dq.ids.du == nullptr) {
- return std::string();
- }
- return dq.ids.du->getHTTPHost();
- });
+ luaCtx.registerFunction<std::string (DNSQuestion::*)(void) const>("getHTTPHost", [](const DNSQuestion& dq) {
+ if (dq.ids.du == nullptr) {
+ return std::string();
+ }
+ return dq.ids.du->getHTTPHost();
+ });
- luaCtx.registerFunction<std::string(DNSQuestion::*)(void)const>("getHTTPScheme", [](const DNSQuestion& dq) {
- if (dq.ids.du == nullptr) {
- return std::string();
- }
- return dq.ids.du->getHTTPScheme();
- });
+ luaCtx.registerFunction<std::string (DNSQuestion::*)(void) const>("getHTTPScheme", [](const DNSQuestion& dq) {
+ if (dq.ids.du == nullptr) {
+ return std::string();
+ }
+ return dq.ids.du->getHTTPScheme();
+ });
- luaCtx.registerFunction<LuaAssociativeTable<std::string>(DNSQuestion::*)(void)const>("getHTTPHeaders", [](const DNSQuestion& dq) {
- if (dq.ids.du == nullptr) {
- return LuaAssociativeTable<std::string>();
- }
- return dq.ids.du->getHTTPHeaders();
- });
+ luaCtx.registerFunction<LuaAssociativeTable<std::string> (DNSQuestion::*)(void) const>("getHTTPHeaders", [](const DNSQuestion& dq) {
+ if (dq.ids.du == nullptr) {
+ return LuaAssociativeTable<std::string>();
+ }
+ return dq.ids.du->getHTTPHeaders();
+ });
- luaCtx.registerFunction<void(DNSQuestion::*)(uint64_t statusCode, const std::string& body, const boost::optional<std::string> contentType)>("setHTTPResponse", [](DNSQuestion& dq, uint64_t statusCode, const std::string& body, const boost::optional<std::string> contentType) {
- if (dq.ids.du == nullptr) {
- return;
- }
- checkParameterBound("DNSQuestion::setHTTPResponse", statusCode, std::numeric_limits<uint16_t>::max());
- PacketBuffer vect(body.begin(), body.end());
- dq.ids.du->setHTTPResponse(statusCode, std::move(vect), contentType ? *contentType : "");
- });
+ luaCtx.registerFunction<void (DNSQuestion::*)(uint64_t statusCode, const std::string& body, const boost::optional<std::string> contentType)>("setHTTPResponse", [](DNSQuestion& dq, uint64_t statusCode, const std::string& body, const boost::optional<std::string> contentType) {
+ if (dq.ids.du == nullptr) {
+ return;
+ }
+ checkParameterBound("DNSQuestion::setHTTPResponse", statusCode, std::numeric_limits<uint16_t>::max());
+ PacketBuffer vect(body.begin(), body.end());
+ dq.ids.du->setHTTPResponse(statusCode, std::move(vect), contentType ? *contentType : "");
+ });
#endif /* HAVE_DNS_OVER_HTTPS */
- luaCtx.registerFunction<bool(DNSQuestion::*)(bool nxd, const std::string& zone, uint64_t ttl, const std::string& mname, const std::string& rname, uint64_t serial, uint64_t refresh, uint64_t retry, uint64_t expire, uint64_t minimum)>("setNegativeAndAdditionalSOA", [](DNSQuestion& dq, bool nxd, const std::string& zone, uint64_t ttl, const std::string& mname, const std::string& rname, uint64_t serial, uint64_t refresh, uint64_t retry, uint64_t expire, uint64_t minimum) {
- checkParameterBound("setNegativeAndAdditionalSOA", ttl, std::numeric_limits<uint32_t>::max());
- checkParameterBound("setNegativeAndAdditionalSOA", serial, std::numeric_limits<uint32_t>::max());
- checkParameterBound("setNegativeAndAdditionalSOA", refresh, std::numeric_limits<uint32_t>::max());
- checkParameterBound("setNegativeAndAdditionalSOA", retry, std::numeric_limits<uint32_t>::max());
- checkParameterBound("setNegativeAndAdditionalSOA", expire, std::numeric_limits<uint32_t>::max());
- checkParameterBound("setNegativeAndAdditionalSOA", minimum, std::numeric_limits<uint32_t>::max());
+ luaCtx.registerFunction<bool (DNSQuestion::*)(bool nxd, const std::string& zone, uint64_t ttl, const std::string& mname, const std::string& rname, uint64_t serial, uint64_t refresh, uint64_t retry, uint64_t expire, uint64_t minimum)>("setNegativeAndAdditionalSOA", [](DNSQuestion& dq, bool nxd, const std::string& zone, uint64_t ttl, const std::string& mname, const std::string& rname, uint64_t serial, uint64_t refresh, uint64_t retry, uint64_t expire, uint64_t minimum) {
+ checkParameterBound("setNegativeAndAdditionalSOA", ttl, std::numeric_limits<uint32_t>::max());
+ checkParameterBound("setNegativeAndAdditionalSOA", serial, std::numeric_limits<uint32_t>::max());
+ checkParameterBound("setNegativeAndAdditionalSOA", refresh, std::numeric_limits<uint32_t>::max());
+ checkParameterBound("setNegativeAndAdditionalSOA", retry, std::numeric_limits<uint32_t>::max());
+ checkParameterBound("setNegativeAndAdditionalSOA", expire, std::numeric_limits<uint32_t>::max());
+ checkParameterBound("setNegativeAndAdditionalSOA", minimum, std::numeric_limits<uint32_t>::max());
- return setNegativeAndAdditionalSOA(dq, nxd, DNSName(zone), ttl, DNSName(mname), DNSName(rname), serial, refresh, retry, expire, minimum, false);
- });
+ return setNegativeAndAdditionalSOA(dq, nxd, DNSName(zone), ttl, DNSName(mname), DNSName(rname), serial, refresh, retry, expire, minimum, false);
+ });
- luaCtx.registerFunction<void(DNSResponse::*)(uint16_t infoCode, const boost::optional<std::string>& extraText)>("setExtendedDNSError", [](DNSResponse& dnsResponse, uint16_t infoCode, const boost::optional<std::string>& extraText) {
+ luaCtx.registerFunction<void (DNSResponse::*)(uint16_t infoCode, const boost::optional<std::string>& extraText)>("setExtendedDNSError", [](DNSResponse& dnsResponse, uint16_t infoCode, const boost::optional<std::string>& extraText) {
EDNSExtendedError ede;
ede.infoCode = infoCode;
if (extraText) {
dnsResponse.ids.d_extendedError = std::make_unique<EDNSExtendedError>(ede);
});
- luaCtx.registerFunction<bool(DNSResponse::*)(uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs)>("suspend", [](DNSResponse& dr, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) {
+ luaCtx.registerFunction<bool (DNSResponse::*)(uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs)>("suspend", [](DNSResponse& dr, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) {
dr.asynchronous = true;
return dnsdist::suspendResponse(dr, asyncID, queryID, timeoutMs);
});
- luaCtx.registerFunction<bool(DNSResponse::*)(const DNSName& newName)>("changeName", [](DNSResponse& dr, const DNSName& newName) -> bool {
+ luaCtx.registerFunction<bool (DNSResponse::*)(const DNSName& newName)>("changeName", [](DNSResponse& dr, const DNSName& newName) -> bool {
if (!dnsdist::changeNameInDNSPacket(dr.getMutableData(), dr.ids.qname, newName)) {
return false;
}
return true;
});
- luaCtx.registerFunction<bool(DNSResponse::*)()>("restart", [](DNSResponse& dr) {
+ luaCtx.registerFunction<bool (DNSResponse::*)()>("restart", [](DNSResponse& dr) {
if (!dr.ids.d_packet) {
return false;
}
return dnsdist::queueQueryResumptionEvent(std::move(query));
});
- luaCtx.registerFunction<std::shared_ptr<DownstreamState>(DNSResponse::*)(void)const>("getSelectedBackend", [](const DNSResponse& dr) {
+ luaCtx.registerFunction<std::shared_ptr<DownstreamState> (DNSResponse::*)(void) const>("getSelectedBackend", [](const DNSResponse& dr) {
return dr.d_downstream;
});
#endif /* DISABLE_NON_FFI_DQ_BINDINGS */
void setupLuaBindings(LuaContext& luaCtx, bool client, bool configCheck)
{
luaCtx.writeFunction("vinfolog", [](const string& arg) {
- vinfolog("%s", arg);
- });
+ vinfolog("%s", arg);
+ });
luaCtx.writeFunction("infolog", [](const string& arg) {
- infolog("%s", arg);
- });
+ infolog("%s", arg);
+ });
luaCtx.writeFunction("errlog", [](const string& arg) {
- errlog("%s", arg);
- });
+ errlog("%s", arg);
+ });
luaCtx.writeFunction("warnlog", [](const string& arg) {
- warnlog("%s", arg);
- });
+ warnlog("%s", arg);
+ });
luaCtx.writeFunction("show", [](const string& arg) {
- g_outputBuffer+=arg;
- g_outputBuffer+="\n";
- });
+ g_outputBuffer += arg;
+ g_outputBuffer += "\n";
+ });
/* Exceptions */
- luaCtx.registerFunction<string(std::exception_ptr::*)()const>("__tostring", [](const std::exception_ptr& eptr) -> std::string {
- try {
- if (eptr) {
- std::rethrow_exception(eptr);
- }
- } catch(const std::exception& e) {
- return string(e.what());
- } catch(const PDNSException& e) {
- return e.reason;
- } catch(...) {
- return string("Unknown exception");
+ luaCtx.registerFunction<string (std::exception_ptr::*)() const>("__tostring", [](const std::exception_ptr& eptr) -> std::string {
+ try {
+ if (eptr) {
+ std::rethrow_exception(eptr);
}
- return string("No exception");
- });
+ }
+ catch (const std::exception& e) {
+ return string(e.what());
+ }
+ catch (const PDNSException& e) {
+ return e.reason;
+ }
+ catch (...) {
+ return string("Unknown exception");
+ }
+ return string("No exception");
+ });
#ifndef DISABLE_POLICIES_BINDINGS
/* ServerPolicy */
- luaCtx.writeFunction("newServerPolicy", [](string name, ServerPolicy::policyfunc_t policy) { return std::make_shared<ServerPolicy>(name, policy, true);});
+ luaCtx.writeFunction("newServerPolicy", [](string name, ServerPolicy::policyfunc_t policy) { return std::make_shared<ServerPolicy>(name, policy, true); });
luaCtx.registerMember("name", &ServerPolicy::d_name);
luaCtx.registerMember("policy", &ServerPolicy::d_policy);
luaCtx.registerMember("ffipolicy", &ServerPolicy::d_ffipolicy);
std::make_shared<ServerPolicy>("wrandom", wrandom, false),
std::make_shared<ServerPolicy>("whashed", whashed, false),
std::make_shared<ServerPolicy>("chashed", chashed, false),
- std::make_shared<ServerPolicy>("leastOutstanding", leastOutstanding, false)
- };
+ std::make_shared<ServerPolicy>("leastOutstanding", leastOutstanding, false)};
for (const auto& policy : policies) {
luaCtx.writeVariable(policy->d_name, policy);
}
#endif /* DISABLE_POLICIES_BINDINGS */
/* ServerPool */
- luaCtx.registerFunction<void(std::shared_ptr<ServerPool>::*)(std::shared_ptr<DNSDistPacketCache>)>("setCache", [](std::shared_ptr<ServerPool> pool, std::shared_ptr<DNSDistPacketCache> cache) {
- if (pool) {
- pool->packetCache = std::move(cache);
- }
- });
+ luaCtx.registerFunction<void (std::shared_ptr<ServerPool>::*)(std::shared_ptr<DNSDistPacketCache>)>("setCache", [](std::shared_ptr<ServerPool> pool, std::shared_ptr<DNSDistPacketCache> cache) {
+ if (pool) {
+ pool->packetCache = std::move(cache);
+ }
+ });
luaCtx.registerFunction("getCache", &ServerPool::getCache);
- luaCtx.registerFunction<void(std::shared_ptr<ServerPool>::*)()>("unsetCache", [](std::shared_ptr<ServerPool> pool) {
- if (pool) {
- pool->packetCache = nullptr;
- }
- });
+ luaCtx.registerFunction<void (std::shared_ptr<ServerPool>::*)()>("unsetCache", [](std::shared_ptr<ServerPool> pool) {
+ if (pool) {
+ pool->packetCache = nullptr;
+ }
+ });
luaCtx.registerFunction("getECS", &ServerPool::getECS);
luaCtx.registerFunction("setECS", &ServerPool::setECS);
#ifndef DISABLE_DOWNSTREAM_BINDINGS
/* DownstreamState */
- luaCtx.registerFunction<void(DownstreamState::*)(int)>("setQPS", [](DownstreamState& state, int lim) { state.qps = lim > 0 ? QPSLimiter(lim, lim) : QPSLimiter(); });
- luaCtx.registerFunction<void(std::shared_ptr<DownstreamState>::*)(string)>("addPool", [](const std::shared_ptr<DownstreamState>& state, const string& pool) {
- auto localPools = g_pools.getCopy();
- addServerToPool(localPools, pool, state);
- g_pools.setState(localPools);
- state->d_config.pools.insert(pool);
- });
- luaCtx.registerFunction<void(std::shared_ptr<DownstreamState>::*)(string)>("rmPool", [](const std::shared_ptr<DownstreamState>& state, const string& pool) {
- auto localPools = g_pools.getCopy();
- removeServerFromPool(localPools, pool, state);
- g_pools.setState(localPools);
- state->d_config.pools.erase(pool);
- });
- luaCtx.registerFunction<uint64_t(DownstreamState::*)()const>("getOutstanding", [](const DownstreamState& state) { return state.outstanding.load(); });
- luaCtx.registerFunction<uint64_t(DownstreamState::*)()const>("getDrops", [](const DownstreamState& state) { return state.reuseds.load(); });
- luaCtx.registerFunction<double(DownstreamState::*)()const>("getLatency", [](const DownstreamState& state) { return state.getRelevantLatencyUsec(); });
+ luaCtx.registerFunction<void (DownstreamState::*)(int)>("setQPS", [](DownstreamState& state, int lim) { state.qps = lim > 0 ? QPSLimiter(lim, lim) : QPSLimiter(); });
+ luaCtx.registerFunction<void (std::shared_ptr<DownstreamState>::*)(string)>("addPool", [](const std::shared_ptr<DownstreamState>& state, const string& pool) {
+ auto localPools = g_pools.getCopy();
+ addServerToPool(localPools, pool, state);
+ g_pools.setState(localPools);
+ state->d_config.pools.insert(pool);
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DownstreamState>::*)(string)>("rmPool", [](const std::shared_ptr<DownstreamState>& state, const string& pool) {
+ auto localPools = g_pools.getCopy();
+ removeServerFromPool(localPools, pool, state);
+ g_pools.setState(localPools);
+ state->d_config.pools.erase(pool);
+ });
+ luaCtx.registerFunction<uint64_t (DownstreamState::*)() const>("getOutstanding", [](const DownstreamState& state) { return state.outstanding.load(); });
+ luaCtx.registerFunction<uint64_t (DownstreamState::*)() const>("getDrops", [](const DownstreamState& state) { return state.reuseds.load(); });
+ luaCtx.registerFunction<double (DownstreamState::*)() const>("getLatency", [](const DownstreamState& state) { return state.getRelevantLatencyUsec(); });
luaCtx.registerFunction("isUp", &DownstreamState::isUp);
luaCtx.registerFunction("setDown", &DownstreamState::setDown);
luaCtx.registerFunction("setUp", &DownstreamState::setUp);
- luaCtx.registerFunction<void(DownstreamState::*)(boost::optional<bool> newStatus)>("setAuto", [](DownstreamState& state, boost::optional<bool> newStatus) {
- if (newStatus) {
- state.setUpStatus(*newStatus);
- }
- state.setAuto();
- });
- luaCtx.registerFunction<void(DownstreamState::*)(boost::optional<bool> newStatus)>("setLazyAuto", [](DownstreamState& state, boost::optional<bool> newStatus) {
- if (newStatus) {
- state.setUpStatus(*newStatus);
- }
- state.setLazyAuto();
- });
- luaCtx.registerFunction<std::string(DownstreamState::*)()const>("getName", [](const DownstreamState& state) -> const std::string& { return state.getName(); });
- luaCtx.registerFunction<std::string(DownstreamState::*)()const>("getNameWithAddr", [](const DownstreamState& state) -> const std::string& { return state.getNameWithAddr(); });
+ luaCtx.registerFunction<void (DownstreamState::*)(boost::optional<bool> newStatus)>("setAuto", [](DownstreamState& state, boost::optional<bool> newStatus) {
+ if (newStatus) {
+ state.setUpStatus(*newStatus);
+ }
+ state.setAuto();
+ });
+ luaCtx.registerFunction<void (DownstreamState::*)(boost::optional<bool> newStatus)>("setLazyAuto", [](DownstreamState& state, boost::optional<bool> newStatus) {
+ if (newStatus) {
+ state.setUpStatus(*newStatus);
+ }
+ state.setLazyAuto();
+ });
+ luaCtx.registerFunction<std::string (DownstreamState::*)() const>("getName", [](const DownstreamState& state) -> const std::string& { return state.getName(); });
+ luaCtx.registerFunction<std::string (DownstreamState::*)() const>("getNameWithAddr", [](const DownstreamState& state) -> const std::string& { return state.getNameWithAddr(); });
luaCtx.registerMember("upStatus", &DownstreamState::upStatus);
- luaCtx.registerMember<int (DownstreamState::*)>("weight",
- [](const DownstreamState& state) -> int {return state.d_config.d_weight;},
- [](DownstreamState& state, int newWeight) { state.setWeight(newWeight); }
- );
- luaCtx.registerMember<int (DownstreamState::*)>("order",
- [](const DownstreamState& state) -> int {return state.d_config.order; },
- [](DownstreamState& state, int newOrder) { state.d_config.order = newOrder; }
- );
- luaCtx.registerMember<const std::string(DownstreamState::*)>("name", [](const DownstreamState& backend) -> const std::string { return backend.getName(); }, [](DownstreamState& backend, const std::string& newName) { backend.setName(newName); });
- luaCtx.registerFunction<std::string(DownstreamState::*)()const>("getID", [](const DownstreamState& state) { return boost::uuids::to_string(*state.d_config.id); });
+ luaCtx.registerMember<int(DownstreamState::*)>(
+ "weight",
+ [](const DownstreamState& state) -> int { return state.d_config.d_weight; },
+ [](DownstreamState& state, int newWeight) { state.setWeight(newWeight); });
+ luaCtx.registerMember<int(DownstreamState::*)>(
+ "order",
+ [](const DownstreamState& state) -> int { return state.d_config.order; },
+ [](DownstreamState& state, int newOrder) { state.d_config.order = newOrder; });
+ luaCtx.registerMember<const std::string(DownstreamState::*)>(
+ "name", [](const DownstreamState& backend) -> const std::string { return backend.getName(); }, [](DownstreamState& backend, const std::string& newName) { backend.setName(newName); });
+ luaCtx.registerFunction<std::string (DownstreamState::*)() const>("getID", [](const DownstreamState& state) { return boost::uuids::to_string(*state.d_config.id); });
#endif /* DISABLE_DOWNSTREAM_BINDINGS */
#ifndef DISABLE_DNSHEADER_BINDINGS
/* dnsheader */
- luaCtx.registerFunction<void(dnsheader::*)(bool)>("setRD", [](dnsheader& dh, bool v) {
- dh.rd=v;
- });
+ luaCtx.registerFunction<void (dnsheader::*)(bool)>("setRD", [](dnsheader& dh, bool v) {
+ dh.rd = v;
+ });
- luaCtx.registerFunction<bool(dnsheader::*)()const>("getRD", [](const dnsheader& dh) {
- return (bool)dh.rd;
- });
+ luaCtx.registerFunction<bool (dnsheader::*)() const>("getRD", [](const dnsheader& dh) {
+ return (bool)dh.rd;
+ });
- luaCtx.registerFunction<void(dnsheader::*)(bool)>("setRA", [](dnsheader& dh, bool v) {
- dh.ra=v;
- });
+ luaCtx.registerFunction<void (dnsheader::*)(bool)>("setRA", [](dnsheader& dh, bool v) {
+ dh.ra = v;
+ });
- luaCtx.registerFunction<bool(dnsheader::*)()const>("getRA", [](const dnsheader& dh) {
- return (bool)dh.ra;
- });
+ luaCtx.registerFunction<bool (dnsheader::*)() const>("getRA", [](const dnsheader& dh) {
+ return (bool)dh.ra;
+ });
- luaCtx.registerFunction<void(dnsheader::*)(bool)>("setAD", [](dnsheader& dh, bool v) {
- dh.ad=v;
- });
+ luaCtx.registerFunction<void (dnsheader::*)(bool)>("setAD", [](dnsheader& dh, bool v) {
+ dh.ad = v;
+ });
- luaCtx.registerFunction<bool(dnsheader::*)()const>("getAD", [](const dnsheader& dh) {
- return (bool)dh.ad;
- });
+ luaCtx.registerFunction<bool (dnsheader::*)() const>("getAD", [](const dnsheader& dh) {
+ return (bool)dh.ad;
+ });
- luaCtx.registerFunction<void(dnsheader::*)(bool)>("setAA", [](dnsheader& dh, bool v) {
- dh.aa=v;
- });
+ luaCtx.registerFunction<void (dnsheader::*)(bool)>("setAA", [](dnsheader& dh, bool v) {
+ dh.aa = v;
+ });
- luaCtx.registerFunction<bool(dnsheader::*)()const>("getAA", [](const dnsheader& dh) {
- return (bool)dh.aa;
- });
+ luaCtx.registerFunction<bool (dnsheader::*)() const>("getAA", [](const dnsheader& dh) {
+ return (bool)dh.aa;
+ });
- luaCtx.registerFunction<void(dnsheader::*)(bool)>("setCD", [](dnsheader& dh, bool v) {
- dh.cd=v;
- });
+ luaCtx.registerFunction<void (dnsheader::*)(bool)>("setCD", [](dnsheader& dh, bool v) {
+ dh.cd = v;
+ });
- luaCtx.registerFunction<bool(dnsheader::*)()const >("getCD", [](const dnsheader& dh) {
- return (bool)dh.cd;
- });
+ luaCtx.registerFunction<bool (dnsheader::*)() const>("getCD", [](const dnsheader& dh) {
+ return (bool)dh.cd;
+ });
- luaCtx.registerFunction<uint16_t(dnsheader::*)()const>("getID", [](const dnsheader& dh) {
- return ntohs(dh.id);
- });
+ luaCtx.registerFunction<uint16_t (dnsheader::*)() const>("getID", [](const dnsheader& dh) {
+ return ntohs(dh.id);
+ });
- luaCtx.registerFunction<bool(dnsheader::*)()const>("getTC", [](const dnsheader& dh) {
- return (bool)dh.tc;
- });
+ luaCtx.registerFunction<bool (dnsheader::*)() const>("getTC", [](const dnsheader& dh) {
+ return (bool)dh.tc;
+ });
- luaCtx.registerFunction<void(dnsheader::*)(bool)>("setTC", [](dnsheader& dh, bool v) {
- dh.tc=v;
- if(v) dh.ra = dh.rd; // you'll always need this, otherwise TC=1 gets ignored
- });
+ luaCtx.registerFunction<void (dnsheader::*)(bool)>("setTC", [](dnsheader& dh, bool v) {
+ dh.tc = v;
+ if (v)
+ dh.ra = dh.rd; // you'll always need this, otherwise TC=1 gets ignored
+ });
- luaCtx.registerFunction<void(dnsheader::*)(bool)>("setQR", [](dnsheader& dh, bool v) {
- dh.qr=v;
- });
+ luaCtx.registerFunction<void (dnsheader::*)(bool)>("setQR", [](dnsheader& dh, bool v) {
+ dh.qr = v;
+ });
#endif /* DISABLE_DNSHEADER_BINDINGS */
#ifndef DISABLE_COMBO_ADDR_BINDINGS
/* ComboAddress */
luaCtx.writeFunction("newCA", [](const std::string& name) { return ComboAddress(name); });
luaCtx.writeFunction("newCAFromRaw", [](const std::string& raw, boost::optional<uint16_t> port) {
- if (raw.size() == 4) {
- struct sockaddr_in sin4;
- memset(&sin4, 0, sizeof(sin4));
- sin4.sin_family = AF_INET;
- memcpy(&sin4.sin_addr.s_addr, raw.c_str(), raw.size());
- if (port) {
- sin4.sin_port = htons(*port);
- }
- return ComboAddress(&sin4);
- }
- else if (raw.size() == 16) {
- struct sockaddr_in6 sin6;
- memset(&sin6, 0, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- memcpy(&sin6.sin6_addr.s6_addr, raw.c_str(), raw.size());
- if (port) {
- sin6.sin6_port = htons(*port);
- }
- return ComboAddress(&sin6);
- }
- return ComboAddress();
- });
- luaCtx.registerFunction<string(ComboAddress::*)()const>("tostring", [](const ComboAddress& ca) { return ca.toString(); });
- luaCtx.registerFunction<string(ComboAddress::*)()const>("tostringWithPort", [](const ComboAddress& ca) { return ca.toStringWithPort(); });
- luaCtx.registerFunction<string(ComboAddress::*)()const>("__tostring", [](const ComboAddress& ca) { return ca.toString(); });
- luaCtx.registerFunction<string(ComboAddress::*)()const>("toString", [](const ComboAddress& ca) { return ca.toString(); });
- luaCtx.registerFunction<string(ComboAddress::*)()const>("toStringWithPort", [](const ComboAddress& ca) { return ca.toStringWithPort(); });
- luaCtx.registerFunction<uint16_t(ComboAddress::*)()const>("getPort", [](const ComboAddress& ca) { return ntohs(ca.sin4.sin_port); } );
- luaCtx.registerFunction<void(ComboAddress::*)(unsigned int)>("truncate", [](ComboAddress& ca, unsigned int bits) { ca.truncate(bits); });
- luaCtx.registerFunction<bool(ComboAddress::*)()const>("isIPv4", [](const ComboAddress& ca) { return ca.sin4.sin_family == AF_INET; });
- luaCtx.registerFunction<bool(ComboAddress::*)()const>("isIPv6", [](const ComboAddress& ca) { return ca.sin4.sin_family == AF_INET6; });
- luaCtx.registerFunction<bool(ComboAddress::*)()const>("isMappedIPv4", [](const ComboAddress& ca) { return ca.isMappedIPv4(); });
- luaCtx.registerFunction<ComboAddress(ComboAddress::*)()const>("mapToIPv4", [](const ComboAddress& ca) { return ca.mapToIPv4(); });
- luaCtx.registerFunction<bool(nmts_t::*)(const ComboAddress&)>("match", [](nmts_t& s, const ComboAddress& ca) { return s.match(ca); });
+ if (raw.size() == 4) {
+ struct sockaddr_in sin4;
+ memset(&sin4, 0, sizeof(sin4));
+ sin4.sin_family = AF_INET;
+ memcpy(&sin4.sin_addr.s_addr, raw.c_str(), raw.size());
+ if (port) {
+ sin4.sin_port = htons(*port);
+ }
+ return ComboAddress(&sin4);
+ }
+ else if (raw.size() == 16) {
+ struct sockaddr_in6 sin6;
+ memset(&sin6, 0, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+ memcpy(&sin6.sin6_addr.s6_addr, raw.c_str(), raw.size());
+ if (port) {
+ sin6.sin6_port = htons(*port);
+ }
+ return ComboAddress(&sin6);
+ }
+ return ComboAddress();
+ });
+ luaCtx.registerFunction<string (ComboAddress::*)() const>("tostring", [](const ComboAddress& ca) { return ca.toString(); });
+ luaCtx.registerFunction<string (ComboAddress::*)() const>("tostringWithPort", [](const ComboAddress& ca) { return ca.toStringWithPort(); });
+ luaCtx.registerFunction<string (ComboAddress::*)() const>("__tostring", [](const ComboAddress& ca) { return ca.toString(); });
+ luaCtx.registerFunction<string (ComboAddress::*)() const>("toString", [](const ComboAddress& ca) { return ca.toString(); });
+ luaCtx.registerFunction<string (ComboAddress::*)() const>("toStringWithPort", [](const ComboAddress& ca) { return ca.toStringWithPort(); });
+ luaCtx.registerFunction<uint16_t (ComboAddress::*)() const>("getPort", [](const ComboAddress& ca) { return ntohs(ca.sin4.sin_port); });
+ luaCtx.registerFunction<void (ComboAddress::*)(unsigned int)>("truncate", [](ComboAddress& ca, unsigned int bits) { ca.truncate(bits); });
+ luaCtx.registerFunction<bool (ComboAddress::*)() const>("isIPv4", [](const ComboAddress& ca) { return ca.sin4.sin_family == AF_INET; });
+ luaCtx.registerFunction<bool (ComboAddress::*)() const>("isIPv6", [](const ComboAddress& ca) { return ca.sin4.sin_family == AF_INET6; });
+ luaCtx.registerFunction<bool (ComboAddress::*)() const>("isMappedIPv4", [](const ComboAddress& ca) { return ca.isMappedIPv4(); });
+ luaCtx.registerFunction<ComboAddress (ComboAddress::*)() const>("mapToIPv4", [](const ComboAddress& ca) { return ca.mapToIPv4(); });
+ luaCtx.registerFunction<bool (nmts_t::*)(const ComboAddress&)>("match", [](nmts_t& s, const ComboAddress& ca) { return s.match(ca); });
#endif /* DISABLE_COMBO_ADDR_BINDINGS */
#ifndef DISABLE_DNSNAME_BINDINGS
/* DNSName */
luaCtx.registerFunction("isPartOf", &DNSName::isPartOf);
- luaCtx.registerFunction<bool(DNSName::*)()>("chopOff", [](DNSName&dn ) { return dn.chopOff(); });
- luaCtx.registerFunction<unsigned int(DNSName::*)()const>("countLabels", [](const DNSName& name) { return name.countLabels(); });
- luaCtx.registerFunction<size_t(DNSName::*)()const>("hash", [](const DNSName& name) { return name.hash(); });
- luaCtx.registerFunction<size_t(DNSName::*)()const>("wirelength", [](const DNSName& name) { return name.wirelength(); });
- luaCtx.registerFunction<string(DNSName::*)()const>("tostring", [](const DNSName&dn ) { return dn.toString(); });
- luaCtx.registerFunction<string(DNSName::*)()const>("toString", [](const DNSName&dn ) { return dn.toString(); });
- luaCtx.registerFunction<string(DNSName::*)()const>("toStringNoDot", [](const DNSName&dn ) { return dn.toStringNoDot(); });
- luaCtx.registerFunction<string(DNSName::*)()const>("__tostring", [](const DNSName&dn ) { return dn.toString(); });
- luaCtx.registerFunction<string(DNSName::*)()const>("toDNSString", [](const DNSName&dn ) { return dn.toDNSString(); });
- luaCtx.registerFunction<DNSName(DNSName::*)(const DNSName&)const>("makeRelative", [](const DNSName& dn, const DNSName& to) { return dn.makeRelative(to); });
+ luaCtx.registerFunction<bool (DNSName::*)()>("chopOff", [](DNSName& dn) { return dn.chopOff(); });
+ luaCtx.registerFunction<unsigned int (DNSName::*)() const>("countLabels", [](const DNSName& name) { return name.countLabels(); });
+ luaCtx.registerFunction<size_t (DNSName::*)() const>("hash", [](const DNSName& name) { return name.hash(); });
+ luaCtx.registerFunction<size_t (DNSName::*)() const>("wirelength", [](const DNSName& name) { return name.wirelength(); });
+ luaCtx.registerFunction<string (DNSName::*)() const>("tostring", [](const DNSName& dn) { return dn.toString(); });
+ luaCtx.registerFunction<string (DNSName::*)() const>("toString", [](const DNSName& dn) { return dn.toString(); });
+ luaCtx.registerFunction<string (DNSName::*)() const>("toStringNoDot", [](const DNSName& dn) { return dn.toStringNoDot(); });
+ luaCtx.registerFunction<string (DNSName::*)() const>("__tostring", [](const DNSName& dn) { return dn.toString(); });
+ luaCtx.registerFunction<string (DNSName::*)() const>("toDNSString", [](const DNSName& dn) { return dn.toDNSString(); });
+ luaCtx.registerFunction<DNSName (DNSName::*)(const DNSName&) const>("makeRelative", [](const DNSName& dn, const DNSName& to) { return dn.makeRelative(to); });
luaCtx.writeFunction("newDNSName", [](const std::string& name) { return DNSName(name); });
luaCtx.writeFunction("newDNSNameFromRaw", [](const std::string& name) { return DNSName(name.c_str(), name.size(), 0, false); });
luaCtx.writeFunction("newSuffixMatchNode", []() { return SuffixMatchNode(); });
luaCtx.writeFunction("newDNSNameSet", []() { return DNSNameSet(); });
/* DNSNameSet */
- luaCtx.registerFunction<string(DNSNameSet::*)()const>("toString", [](const DNSNameSet&dns ) { return dns.toString(); });
- luaCtx.registerFunction<string(DNSNameSet::*)()const>("__tostring", [](const DNSNameSet&dns ) { return dns.toString(); });
- luaCtx.registerFunction<void(DNSNameSet::*)(DNSName&)>("add", [](DNSNameSet& dns, DNSName& dn) { dns.insert(dn); });
- luaCtx.registerFunction<bool(DNSNameSet::*)(DNSName&)>("check", [](DNSNameSet& dns, DNSName& dn) { return dns.find(dn) != dns.end(); });
- luaCtx.registerFunction("delete",(size_t (DNSNameSet::*)(const DNSName&)) &DNSNameSet::erase);
- luaCtx.registerFunction("size",(size_t (DNSNameSet::*)() const) &DNSNameSet::size);
- luaCtx.registerFunction("clear",(void (DNSNameSet::*)()) &DNSNameSet::clear);
- luaCtx.registerFunction("empty",(bool (DNSNameSet::*)() const) &DNSNameSet::empty);
+ luaCtx.registerFunction<string (DNSNameSet::*)() const>("toString", [](const DNSNameSet& dns) { return dns.toString(); });
+ luaCtx.registerFunction<string (DNSNameSet::*)() const>("__tostring", [](const DNSNameSet& dns) { return dns.toString(); });
+ luaCtx.registerFunction<void (DNSNameSet::*)(DNSName&)>("add", [](DNSNameSet& dns, DNSName& dn) { dns.insert(dn); });
+ luaCtx.registerFunction<bool (DNSNameSet::*)(DNSName&)>("check", [](DNSNameSet& dns, DNSName& dn) { return dns.find(dn) != dns.end(); });
+ luaCtx.registerFunction("delete", (size_t(DNSNameSet::*)(const DNSName&)) & DNSNameSet::erase);
+ luaCtx.registerFunction("size", (size_t(DNSNameSet::*)() const) & DNSNameSet::size);
+ luaCtx.registerFunction("clear", (void(DNSNameSet::*)()) & DNSNameSet::clear);
+ luaCtx.registerFunction("empty", (bool(DNSNameSet::*)() const) & DNSNameSet::empty);
#endif /* DISABLE_DNSNAME_BINDINGS */
#ifndef DISABLE_SUFFIX_MATCH_BINDINGS
/* SuffixMatchNode */
- luaCtx.registerFunction<void (SuffixMatchNode::*)(const boost::variant<DNSName, std::string, LuaArray<DNSName>, LuaArray<std::string>> &name)>("add", [](SuffixMatchNode &smn, const boost::variant<DNSName, std::string, LuaArray<DNSName>, LuaArray<std::string>> &name) {
- if (name.type() == typeid(DNSName)) {
- const auto& actualName = boost::get<DNSName>(name);
- smn.add(actualName);
- return;
- }
- if (name.type() == typeid(std::string)) {
- const auto& actualName = boost::get<std::string>(name);
- smn.add(actualName);
- return;
- }
- if (name.type() == typeid(LuaArray<DNSName>)) {
- const auto& names = boost::get<LuaArray<DNSName>>(name);
- for (const auto& actualName : names) {
- smn.add(actualName.second);
- }
- return;
+ luaCtx.registerFunction<void (SuffixMatchNode::*)(const boost::variant<DNSName, std::string, LuaArray<DNSName>, LuaArray<std::string>>& name)>("add", [](SuffixMatchNode& smn, const boost::variant<DNSName, std::string, LuaArray<DNSName>, LuaArray<std::string>>& name) {
+ if (name.type() == typeid(DNSName)) {
+ const auto& actualName = boost::get<DNSName>(name);
+ smn.add(actualName);
+ return;
+ }
+ if (name.type() == typeid(std::string)) {
+ const auto& actualName = boost::get<std::string>(name);
+ smn.add(actualName);
+ return;
+ }
+ if (name.type() == typeid(LuaArray<DNSName>)) {
+ const auto& names = boost::get<LuaArray<DNSName>>(name);
+ for (const auto& actualName : names) {
+ smn.add(actualName.second);
}
- if (name.type() == typeid(LuaArray<std::string>)) {
- const auto& names = boost::get<LuaArray<string>>(name);
- for (const auto& actualName : names) {
- smn.add(actualName.second);
- }
- return;
+ return;
+ }
+ if (name.type() == typeid(LuaArray<std::string>)) {
+ const auto& names = boost::get<LuaArray<string>>(name);
+ for (const auto& actualName : names) {
+ smn.add(actualName.second);
}
+ return;
+ }
});
- luaCtx.registerFunction<void (SuffixMatchNode::*)(const boost::variant<DNSName, string, LuaArray<DNSName>, LuaArray<std::string>> &name)>("remove", [](SuffixMatchNode &smn, const boost::variant<DNSName, string, LuaArray<DNSName>, LuaArray<std::string>> &name) {
- if (name.type() == typeid(DNSName)) {
- const auto& actualName = boost::get<DNSName>(name);
- smn.remove(actualName);
- return;
- }
- if (name.type() == typeid(string)) {
- const auto& actualName = boost::get<string>(name);
- DNSName dnsName(actualName);
- smn.remove(dnsName);
- return;
- }
- if (name.type() == typeid(LuaArray<DNSName>)) {
- const auto& names = boost::get<LuaArray<DNSName>>(name);
- for (const auto& actualName : names) {
- smn.remove(actualName.second);
- }
- return;
+ luaCtx.registerFunction<void (SuffixMatchNode::*)(const boost::variant<DNSName, string, LuaArray<DNSName>, LuaArray<std::string>>& name)>("remove", [](SuffixMatchNode& smn, const boost::variant<DNSName, string, LuaArray<DNSName>, LuaArray<std::string>>& name) {
+ if (name.type() == typeid(DNSName)) {
+ const auto& actualName = boost::get<DNSName>(name);
+ smn.remove(actualName);
+ return;
+ }
+ if (name.type() == typeid(string)) {
+ const auto& actualName = boost::get<string>(name);
+ DNSName dnsName(actualName);
+ smn.remove(dnsName);
+ return;
+ }
+ if (name.type() == typeid(LuaArray<DNSName>)) {
+ const auto& names = boost::get<LuaArray<DNSName>>(name);
+ for (const auto& actualName : names) {
+ smn.remove(actualName.second);
}
- if (name.type() == typeid(LuaArray<std::string>)) {
- const auto& names = boost::get<LuaArray<std::string>>(name);
- for (const auto& actualName : names) {
- DNSName dnsName(actualName.second);
- smn.remove(dnsName);
- }
- return;
+ return;
+ }
+ if (name.type() == typeid(LuaArray<std::string>)) {
+ const auto& names = boost::get<LuaArray<std::string>>(name);
+ for (const auto& actualName : names) {
+ DNSName dnsName(actualName.second);
+ smn.remove(dnsName);
}
+ return;
+ }
});
- luaCtx.registerFunction("check", (bool (SuffixMatchNode::*)(const DNSName&) const) &SuffixMatchNode::check);
+ luaCtx.registerFunction("check", (bool(SuffixMatchNode::*)(const DNSName&) const) & SuffixMatchNode::check);
luaCtx.registerFunction<boost::optional<DNSName> (SuffixMatchNode::*)(const DNSName&) const>("getBestMatch", [](const SuffixMatchNode& smn, const DNSName& needle) {
boost::optional<DNSName> result{boost::none};
auto res = smn.getBestMatch(needle);
#ifndef DISABLE_NETMASK_BINDINGS
/* Netmask */
- luaCtx.writeFunction("newNetmask", [](boost::variant<std::string,ComboAddress> addrOrStr, boost::optional<uint8_t> bits) {
+ luaCtx.writeFunction("newNetmask", [](boost::variant<std::string, ComboAddress> addrOrStr, boost::optional<uint8_t> bits) {
if (addrOrStr.type() == typeid(ComboAddress)) {
const auto& comboAddr = boost::get<ComboAddress>(addrOrStr);
if (bits) {
});
luaCtx.registerFunction("empty", &Netmask::empty);
luaCtx.registerFunction("getBits", &Netmask::getBits);
- luaCtx.registerFunction<ComboAddress(Netmask::*)()const>("getNetwork", [](const Netmask& nm) { return nm.getNetwork(); } ); // const reference makes this necessary
- luaCtx.registerFunction<ComboAddress(Netmask::*)()const>("getMaskedNetwork", [](const Netmask& nm) { return nm.getMaskedNetwork(); } );
+ luaCtx.registerFunction<ComboAddress (Netmask::*)() const>("getNetwork", [](const Netmask& nm) { return nm.getNetwork(); }); // const reference makes this necessary
+ luaCtx.registerFunction<ComboAddress (Netmask::*)() const>("getMaskedNetwork", [](const Netmask& nm) { return nm.getMaskedNetwork(); });
luaCtx.registerFunction("isIpv4", &Netmask::isIPv4);
luaCtx.registerFunction("isIPv4", &Netmask::isIPv4);
luaCtx.registerFunction("isIpv6", &Netmask::isIPv6);
luaCtx.registerFunction("isIPv6", &Netmask::isIPv6);
- luaCtx.registerFunction("match", (bool (Netmask::*)(const string&) const)&Netmask::match);
+ luaCtx.registerFunction("match", (bool(Netmask::*)(const string&) const) & Netmask::match);
luaCtx.registerFunction("toString", &Netmask::toString);
luaCtx.registerFunction("__tostring", &Netmask::toString);
luaCtx.registerEqFunction(&Netmask::operator==);
/* NetmaskGroup */
luaCtx.writeFunction("newNMG", []() { return NetmaskGroup(); });
- luaCtx.registerFunction<void(NetmaskGroup::*)(const std::string& mask)>("addMask", [](NetmaskGroup& nmg, const std::string& mask)
- {
- nmg.addMask(mask);
- });
- luaCtx.registerFunction<void(NetmaskGroup::*)(const NetmaskGroup& otherNMG)>("addNMG", [](NetmaskGroup& nmg, const NetmaskGroup& otherNMG) {
+ luaCtx.registerFunction<void (NetmaskGroup::*)(const std::string& mask)>("addMask", [](NetmaskGroup& nmg, const std::string& mask) {
+ nmg.addMask(mask);
+ });
+ luaCtx.registerFunction<void (NetmaskGroup::*)(const NetmaskGroup& otherNMG)>("addNMG", [](NetmaskGroup& nmg, const NetmaskGroup& otherNMG) {
/* this is not going to be very efficient, sorry */
auto entries = otherNMG.toStringVector();
for (const auto& entry : entries) {
nmg.addMask(entry);
}
});
- luaCtx.registerFunction<void(NetmaskGroup::*)(const std::map<ComboAddress,int>& map)>("addMasks", [](NetmaskGroup&nmg, const std::map<ComboAddress,int>& map)
- {
- for (const auto& entry : map) {
- nmg.addMask(Netmask(entry.first));
- }
- });
+ luaCtx.registerFunction<void (NetmaskGroup::*)(const std::map<ComboAddress, int>& map)>("addMasks", [](NetmaskGroup& nmg, const std::map<ComboAddress, int>& map) {
+ for (const auto& entry : map) {
+ nmg.addMask(Netmask(entry.first));
+ }
+ });
- luaCtx.registerFunction("match", (bool (NetmaskGroup::*)(const ComboAddress&) const)&NetmaskGroup::match);
+ luaCtx.registerFunction("match", (bool(NetmaskGroup::*)(const ComboAddress&) const) & NetmaskGroup::match);
luaCtx.registerFunction("size", &NetmaskGroup::size);
luaCtx.registerFunction("clear", &NetmaskGroup::clear);
- luaCtx.registerFunction<string(NetmaskGroup::*)()const>("toString", [](const NetmaskGroup& nmg ) { return "NetmaskGroup " + nmg.toString(); });
- luaCtx.registerFunction<string(NetmaskGroup::*)()const>("__tostring", [](const NetmaskGroup& nmg ) { return "NetmaskGroup " + nmg.toString(); });
+ luaCtx.registerFunction<string (NetmaskGroup::*)() const>("toString", [](const NetmaskGroup& nmg) { return "NetmaskGroup " + nmg.toString(); });
+ luaCtx.registerFunction<string (NetmaskGroup::*)() const>("__tostring", [](const NetmaskGroup& nmg) { return "NetmaskGroup " + nmg.toString(); });
#endif /* DISABLE_NETMASK_BINDINGS */
#ifndef DISABLE_QPS_LIMITER_BINDINGS
#ifndef DISABLE_CLIENT_STATE_BINDINGS
/* ClientState */
- luaCtx.registerFunction<std::string(ClientState::*)()const>("toString", [](const ClientState& fe) {
- setLuaNoSideEffect();
- return fe.local.toStringWithPort();
- });
- luaCtx.registerFunction<std::string(ClientState::*)()const>("__tostring", [](const ClientState& fe) {
- setLuaNoSideEffect();
- return fe.local.toStringWithPort();
- });
- luaCtx.registerFunction<std::string(ClientState::*)()const>("getType", [](const ClientState& fe) {
- setLuaNoSideEffect();
- return fe.getType();
- });
- luaCtx.registerFunction<std::string(ClientState::*)()const>("getConfiguredTLSProvider", [](const ClientState& fe) {
- setLuaNoSideEffect();
- if (fe.tlsFrontend != nullptr) {
- return fe.tlsFrontend->getRequestedProvider();
- }
- else if (fe.dohFrontend != nullptr) {
- return std::string("openssl");
- }
- return std::string();
+ luaCtx.registerFunction<std::string (ClientState::*)() const>("toString", [](const ClientState& fe) {
+ setLuaNoSideEffect();
+ return fe.local.toStringWithPort();
});
- luaCtx.registerFunction<std::string(ClientState::*)()const>("getEffectiveTLSProvider", [](const ClientState& fe) {
- setLuaNoSideEffect();
- if (fe.tlsFrontend != nullptr) {
- return fe.tlsFrontend->getEffectiveProvider();
- }
- else if (fe.dohFrontend != nullptr) {
- return std::string("openssl");
- }
- return std::string();
+ luaCtx.registerFunction<std::string (ClientState::*)() const>("__tostring", [](const ClientState& fe) {
+ setLuaNoSideEffect();
+ return fe.local.toStringWithPort();
+ });
+ luaCtx.registerFunction<std::string (ClientState::*)() const>("getType", [](const ClientState& fe) {
+ setLuaNoSideEffect();
+ return fe.getType();
+ });
+ luaCtx.registerFunction<std::string (ClientState::*)() const>("getConfiguredTLSProvider", [](const ClientState& fe) {
+ setLuaNoSideEffect();
+ if (fe.tlsFrontend != nullptr) {
+ return fe.tlsFrontend->getRequestedProvider();
+ }
+ else if (fe.dohFrontend != nullptr) {
+ return std::string("openssl");
+ }
+ return std::string();
+ });
+ luaCtx.registerFunction<std::string (ClientState::*)() const>("getEffectiveTLSProvider", [](const ClientState& fe) {
+ setLuaNoSideEffect();
+ if (fe.tlsFrontend != nullptr) {
+ return fe.tlsFrontend->getEffectiveProvider();
+ }
+ else if (fe.dohFrontend != nullptr) {
+ return std::string("openssl");
+ }
+ return std::string();
});
luaCtx.registerMember("muted", &ClientState::muted);
#ifdef HAVE_EBPF
- luaCtx.registerFunction<void(ClientState::*)(std::shared_ptr<BPFFilter>)>("attachFilter", [](ClientState& frontend, std::shared_ptr<BPFFilter> bpf) {
- if (bpf) {
- frontend.attachFilter(bpf, frontend.getSocket());
- }
- });
- luaCtx.registerFunction<void(ClientState::*)()>("detachFilter", [](ClientState& frontend) {
- frontend.detachFilter(frontend.getSocket());
- });
+ luaCtx.registerFunction<void (ClientState::*)(std::shared_ptr<BPFFilter>)>("attachFilter", [](ClientState& frontend, std::shared_ptr<BPFFilter> bpf) {
+ if (bpf) {
+ frontend.attachFilter(bpf, frontend.getSocket());
+ }
+ });
+ luaCtx.registerFunction<void (ClientState::*)()>("detachFilter", [](ClientState& frontend) {
+ frontend.detachFilter(frontend.getSocket());
+ });
#endif /* HAVE_EBPF */
#endif /* DISABLE_CLIENT_STATE_BINDINGS */
#ifdef HAVE_EBPF
using bpfopts_t = LuaAssociativeTable<boost::variant<bool, uint32_t, std::string>>;
luaCtx.writeFunction("newBPFFilter", [client](bpfopts_t opts) {
- if (client) {
- return std::shared_ptr<BPFFilter>(nullptr);
- }
- std::unordered_map<std::string, BPFFilter::MapConfiguration> mapsConfig;
-
- const auto convertParamsToConfig = [&](const std::string& name, BPFFilter::MapType type) {
- BPFFilter::MapConfiguration config;
- config.d_type = type;
- if (const string key = name + "MaxItems"; opts.count(key)) {
- const auto& tmp = opts.at(key);
- if (tmp.type() != typeid(uint32_t)) {
- throw std::runtime_error("params is invalid");
- }
- const auto& params = boost::get<uint32_t>(tmp);
- config.d_maxItems = params;
+ if (client) {
+ return std::shared_ptr<BPFFilter>(nullptr);
+ }
+ std::unordered_map<std::string, BPFFilter::MapConfiguration> mapsConfig;
+
+ const auto convertParamsToConfig = [&](const std::string& name, BPFFilter::MapType type) {
+ BPFFilter::MapConfiguration config;
+ config.d_type = type;
+ if (const string key = name + "MaxItems"; opts.count(key)) {
+ const auto& tmp = opts.at(key);
+ if (tmp.type() != typeid(uint32_t)) {
+ throw std::runtime_error("params is invalid");
}
+ const auto& params = boost::get<uint32_t>(tmp);
+ config.d_maxItems = params;
+ }
- if (const string key = name + "PinnedPath"; opts.count(key)) {
- auto& tmp = opts.at(key);
- if (tmp.type() != typeid(string)) {
- throw std::runtime_error("params is invalid");
- }
- auto& params = boost::get<string>(tmp);
- config.d_pinnedPath = std::move(params);
- }
- mapsConfig[name] = std::move(config);
- };
-
- convertParamsToConfig("ipv4", BPFFilter::MapType::IPv4);
- convertParamsToConfig("ipv6", BPFFilter::MapType::IPv6);
- convertParamsToConfig("qnames", BPFFilter::MapType::QNames);
- convertParamsToConfig("cidr4", BPFFilter::MapType::CIDR4);
- convertParamsToConfig("cidr6", BPFFilter::MapType::CIDR6);
-
- BPFFilter::MapFormat format = BPFFilter::MapFormat::Legacy;
- bool external = false;
- if (opts.count("external")) {
- const auto& tmp = opts.at("external");
- if (tmp.type() != typeid(bool)) {
+ if (const string key = name + "PinnedPath"; opts.count(key)) {
+ auto& tmp = opts.at(key);
+ if (tmp.type() != typeid(string)) {
throw std::runtime_error("params is invalid");
}
- if ((external = boost::get<bool>(tmp))) {
- format = BPFFilter::MapFormat::WithActions;
- }
+ auto& params = boost::get<string>(tmp);
+ config.d_pinnedPath = std::move(params);
+ }
+ mapsConfig[name] = std::move(config);
+ };
+
+ convertParamsToConfig("ipv4", BPFFilter::MapType::IPv4);
+ convertParamsToConfig("ipv6", BPFFilter::MapType::IPv6);
+ convertParamsToConfig("qnames", BPFFilter::MapType::QNames);
+ convertParamsToConfig("cidr4", BPFFilter::MapType::CIDR4);
+ convertParamsToConfig("cidr6", BPFFilter::MapType::CIDR6);
+
+ BPFFilter::MapFormat format = BPFFilter::MapFormat::Legacy;
+ bool external = false;
+ if (opts.count("external")) {
+ const auto& tmp = opts.at("external");
+ if (tmp.type() != typeid(bool)) {
+ throw std::runtime_error("params is invalid");
+ }
+ if ((external = boost::get<bool>(tmp))) {
+ format = BPFFilter::MapFormat::WithActions;
}
+ }
- return std::make_shared<BPFFilter>(mapsConfig, format, external);
+ return std::make_shared<BPFFilter>(mapsConfig, format, external);
});
- luaCtx.registerFunction<void(std::shared_ptr<BPFFilter>::*)(const ComboAddress& ca, boost::optional<uint32_t> action)>("block", [](std::shared_ptr<BPFFilter> bpf, const ComboAddress& ca, boost::optional<uint32_t> action) {
- if (bpf) {
- if (!action) {
- return bpf->block(ca, BPFFilter::MatchAction::Drop);
- }
- else {
- BPFFilter::MatchAction match;
-
- switch (*action) {
- case 0:
- match = BPFFilter::MatchAction::Pass;
- break;
- case 1:
- match = BPFFilter::MatchAction::Drop;
- break;
- case 2:
- match = BPFFilter::MatchAction::Truncate;
- break;
- default:
- throw std::runtime_error("Unsupported action for BPFFilter::block");
- }
- return bpf->block(ca, match);
+ luaCtx.registerFunction<void (std::shared_ptr<BPFFilter>::*)(const ComboAddress& ca, boost::optional<uint32_t> action)>("block", [](std::shared_ptr<BPFFilter> bpf, const ComboAddress& ca, boost::optional<uint32_t> action) {
+ if (bpf) {
+ if (!action) {
+ return bpf->block(ca, BPFFilter::MatchAction::Drop);
+ }
+ else {
+ BPFFilter::MatchAction match;
+
+ switch (*action) {
+ case 0:
+ match = BPFFilter::MatchAction::Pass;
+ break;
+ case 1:
+ match = BPFFilter::MatchAction::Drop;
+ break;
+ case 2:
+ match = BPFFilter::MatchAction::Truncate;
+ break;
+ default:
+ throw std::runtime_error("Unsupported action for BPFFilter::block");
}
+ return bpf->block(ca, match);
}
- });
+ }
+ });
luaCtx.registerFunction<void (std::shared_ptr<BPFFilter>::*)(const string& range, uint32_t action, boost::optional<bool> force)>("addRangeRule", [](std::shared_ptr<BPFFilter> bpf, const string& range, uint32_t action, boost::optional<bool> force) {
if (!bpf) {
return;
}
return bpf->addRangeRule(Netmask(range), force ? *force : false, match);
});
- luaCtx.registerFunction<void(std::shared_ptr<BPFFilter>::*)(const DNSName& qname, boost::optional<uint16_t> qtype, boost::optional<uint32_t> action)>("blockQName", [](std::shared_ptr<BPFFilter> bpf, const DNSName& qname, boost::optional<uint16_t> qtype, boost::optional<uint32_t> action) {
- if (bpf) {
- if (!action) {
- return bpf->block(qname, BPFFilter::MatchAction::Drop, qtype ? *qtype : 255);
- }
- else {
- BPFFilter::MatchAction match;
-
- switch (*action) {
- case 0:
- match = BPFFilter::MatchAction::Pass;
- break;
- case 1:
- match = BPFFilter::MatchAction::Drop;
- break;
- case 2:
- match = BPFFilter::MatchAction::Truncate;
- break;
- default:
- throw std::runtime_error("Unsupported action for BPFFilter::blockQName");
- }
- return bpf->block(qname, match, qtype ? *qtype : 255);
+ luaCtx.registerFunction<void (std::shared_ptr<BPFFilter>::*)(const DNSName& qname, boost::optional<uint16_t> qtype, boost::optional<uint32_t> action)>("blockQName", [](std::shared_ptr<BPFFilter> bpf, const DNSName& qname, boost::optional<uint16_t> qtype, boost::optional<uint32_t> action) {
+ if (bpf) {
+ if (!action) {
+ return bpf->block(qname, BPFFilter::MatchAction::Drop, qtype ? *qtype : 255);
+ }
+ else {
+ BPFFilter::MatchAction match;
+
+ switch (*action) {
+ case 0:
+ match = BPFFilter::MatchAction::Pass;
+ break;
+ case 1:
+ match = BPFFilter::MatchAction::Drop;
+ break;
+ case 2:
+ match = BPFFilter::MatchAction::Truncate;
+ break;
+ default:
+ throw std::runtime_error("Unsupported action for BPFFilter::blockQName");
}
+ return bpf->block(qname, match, qtype ? *qtype : 255);
}
- });
+ }
+ });
- luaCtx.registerFunction<void(std::shared_ptr<BPFFilter>::*)(const ComboAddress& ca)>("unblock", [](std::shared_ptr<BPFFilter> bpf, const ComboAddress& ca) {
- if (bpf) {
- return bpf->unblock(ca);
- }
- });
+ luaCtx.registerFunction<void (std::shared_ptr<BPFFilter>::*)(const ComboAddress& ca)>("unblock", [](std::shared_ptr<BPFFilter> bpf, const ComboAddress& ca) {
+ if (bpf) {
+ return bpf->unblock(ca);
+ }
+ });
luaCtx.registerFunction<void (std::shared_ptr<BPFFilter>::*)(const string& range)>("rmRangeRule", [](std::shared_ptr<BPFFilter> bpf, const string& range) {
if (!bpf) {
return;
}
return res;
});
- luaCtx.registerFunction<void(std::shared_ptr<BPFFilter>::*)(const DNSName& qname, boost::optional<uint16_t> qtype)>("unblockQName", [](std::shared_ptr<BPFFilter> bpf, const DNSName& qname, boost::optional<uint16_t> qtype) {
- if (bpf) {
- return bpf->unblock(qname, qtype ? *qtype : 255);
- }
- });
+ luaCtx.registerFunction<void (std::shared_ptr<BPFFilter>::*)(const DNSName& qname, boost::optional<uint16_t> qtype)>("unblockQName", [](std::shared_ptr<BPFFilter> bpf, const DNSName& qname, boost::optional<uint16_t> qtype) {
+ if (bpf) {
+ return bpf->unblock(qname, qtype ? *qtype : 255);
+ }
+ });
- luaCtx.registerFunction<std::string(std::shared_ptr<BPFFilter>::*)()const>("getStats", [](const std::shared_ptr<BPFFilter> bpf) {
- setLuaNoSideEffect();
- std::string res;
- if (bpf) {
- auto stats = bpf->getAddrStats();
- for (const auto& value : stats) {
- if (value.first.sin4.sin_family == AF_INET) {
- res += value.first.toString() + ": " + std::to_string(value.second) + "\n";
- }
- else if (value.first.sin4.sin_family == AF_INET6) {
- res += "[" + value.first.toString() + "]: " + std::to_string(value.second) + "\n";
- }
+ luaCtx.registerFunction<std::string (std::shared_ptr<BPFFilter>::*)() const>("getStats", [](const std::shared_ptr<BPFFilter> bpf) {
+ setLuaNoSideEffect();
+ std::string res;
+ if (bpf) {
+ auto stats = bpf->getAddrStats();
+ for (const auto& value : stats) {
+ if (value.first.sin4.sin_family == AF_INET) {
+ res += value.first.toString() + ": " + std::to_string(value.second) + "\n";
}
- const auto rangeStat = bpf->getRangeRule();
- for (const auto& value : rangeStat) {
- if (value.first.isIPv4()) {
- res += BPFFilter::toString(value.second.action) + "\t " + value.first.toString() + ": " + std::to_string(value.second.counter) + "\n";
- }
- else if (value.first.isIPv6()) {
- res += BPFFilter::toString(value.second.action) + "\t[" + value.first.toString() + "]: " + std::to_string(value.second.counter) + "\n";
- }
+ else if (value.first.sin4.sin_family == AF_INET6) {
+ res += "[" + value.first.toString() + "]: " + std::to_string(value.second) + "\n";
}
- auto qstats = bpf->getQNameStats();
- for (const auto& value : qstats) {
- res += std::get<0>(value).toString() + " " + std::to_string(std::get<1>(value)) + ": " + std::to_string(std::get<2>(value)) + "\n";
+ }
+ const auto rangeStat = bpf->getRangeRule();
+ for (const auto& value : rangeStat) {
+ if (value.first.isIPv4()) {
+ res += BPFFilter::toString(value.second.action) + "\t " + value.first.toString() + ": " + std::to_string(value.second.counter) + "\n";
+ }
+ else if (value.first.isIPv6()) {
+ res += BPFFilter::toString(value.second.action) + "\t[" + value.first.toString() + "]: " + std::to_string(value.second.counter) + "\n";
}
}
- return res;
- });
-
- luaCtx.registerFunction<void(std::shared_ptr<BPFFilter>::*)()>("attachToAllBinds", [](std::shared_ptr<BPFFilter> bpf) {
- std::string res;
- if (!g_configurationDone) {
- throw std::runtime_error("attachToAllBinds() cannot be used at configuration time!");
- return;
+ auto qstats = bpf->getQNameStats();
+ for (const auto& value : qstats) {
+ res += std::get<0>(value).toString() + " " + std::to_string(std::get<1>(value)) + ": " + std::to_string(std::get<2>(value)) + "\n";
}
- if (bpf) {
- for (const auto& frontend : g_frontends) {
- frontend->attachFilter(bpf, frontend->getSocket());
- }
+ }
+ return res;
+ });
+
+ luaCtx.registerFunction<void (std::shared_ptr<BPFFilter>::*)()>("attachToAllBinds", [](std::shared_ptr<BPFFilter> bpf) {
+ std::string res;
+ if (!g_configurationDone) {
+ throw std::runtime_error("attachToAllBinds() cannot be used at configuration time!");
+ return;
+ }
+ if (bpf) {
+ for (const auto& frontend : g_frontends) {
+ frontend->attachFilter(bpf, frontend->getSocket());
}
- });
+ }
+ });
- luaCtx.writeFunction("newDynBPFFilter", [client](std::shared_ptr<BPFFilter> bpf) {
- if (client) {
- return std::shared_ptr<DynBPFFilter>(nullptr);
- }
- return std::make_shared<DynBPFFilter>(bpf);
- });
-
- luaCtx.registerFunction<void(std::shared_ptr<DynBPFFilter>::*)(const ComboAddress& addr, boost::optional<int> seconds)>("block", [](std::shared_ptr<DynBPFFilter> dbpf, const ComboAddress& addr, boost::optional<int> seconds) {
- if (dbpf) {
- struct timespec until;
- clock_gettime(CLOCK_MONOTONIC, &until);
- until.tv_sec += seconds ? *seconds : 10;
- dbpf->block(addr, until);
- }
- });
+ luaCtx.writeFunction("newDynBPFFilter", [client](std::shared_ptr<BPFFilter> bpf) {
+ if (client) {
+ return std::shared_ptr<DynBPFFilter>(nullptr);
+ }
+ return std::make_shared<DynBPFFilter>(bpf);
+ });
- luaCtx.registerFunction<void(std::shared_ptr<DynBPFFilter>::*)()>("purgeExpired", [](std::shared_ptr<DynBPFFilter> dbpf) {
- if (dbpf) {
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- dbpf->purgeExpired(now);
- }
- });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBPFFilter>::*)(const ComboAddress& addr, boost::optional<int> seconds)>("block", [](std::shared_ptr<DynBPFFilter> dbpf, const ComboAddress& addr, boost::optional<int> seconds) {
+ if (dbpf) {
+ struct timespec until;
+ clock_gettime(CLOCK_MONOTONIC, &until);
+ until.tv_sec += seconds ? *seconds : 10;
+ dbpf->block(addr, until);
+ }
+ });
- luaCtx.registerFunction<void(std::shared_ptr<DynBPFFilter>::*)(LuaTypeOrArrayOf<std::string>)>("excludeRange", [](std::shared_ptr<DynBPFFilter> dbpf, LuaTypeOrArrayOf<std::string> ranges) {
- if (!dbpf) {
- return;
- }
+ luaCtx.registerFunction<void (std::shared_ptr<DynBPFFilter>::*)()>("purgeExpired", [](std::shared_ptr<DynBPFFilter> dbpf) {
+ if (dbpf) {
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ dbpf->purgeExpired(now);
+ }
+ });
- if (ranges.type() == typeid(LuaArray<std::string>)) {
- for (const auto& range : *boost::get<LuaArray<std::string>>(&ranges)) {
- dbpf->excludeRange(Netmask(range.second));
- }
- }
- else {
- dbpf->excludeRange(Netmask(*boost::get<std::string>(&ranges)));
- }
- });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBPFFilter>::*)(LuaTypeOrArrayOf<std::string>)>("excludeRange", [](std::shared_ptr<DynBPFFilter> dbpf, LuaTypeOrArrayOf<std::string> ranges) {
+ if (!dbpf) {
+ return;
+ }
- luaCtx.registerFunction<void(std::shared_ptr<DynBPFFilter>::*)(LuaTypeOrArrayOf<std::string>)>("includeRange", [](std::shared_ptr<DynBPFFilter> dbpf, LuaTypeOrArrayOf<std::string> ranges) {
- if (!dbpf) {
- return;
+ if (ranges.type() == typeid(LuaArray<std::string>)) {
+ for (const auto& range : *boost::get<LuaArray<std::string>>(&ranges)) {
+ dbpf->excludeRange(Netmask(range.second));
}
+ }
+ else {
+ dbpf->excludeRange(Netmask(*boost::get<std::string>(&ranges)));
+ }
+ });
- if (ranges.type() == typeid(LuaArray<std::string>)) {
- for (const auto& range : *boost::get<LuaArray<std::string>>(&ranges)) {
- dbpf->includeRange(Netmask(range.second));
- }
- }
- else {
- dbpf->includeRange(Netmask(*boost::get<std::string>(&ranges)));
+ luaCtx.registerFunction<void (std::shared_ptr<DynBPFFilter>::*)(LuaTypeOrArrayOf<std::string>)>("includeRange", [](std::shared_ptr<DynBPFFilter> dbpf, LuaTypeOrArrayOf<std::string> ranges) {
+ if (!dbpf) {
+ return;
+ }
+
+ if (ranges.type() == typeid(LuaArray<std::string>)) {
+ for (const auto& range : *boost::get<LuaArray<std::string>>(&ranges)) {
+ dbpf->includeRange(Netmask(range.second));
}
- });
+ }
+ else {
+ dbpf->includeRange(Netmask(*boost::get<std::string>(&ranges)));
+ }
+ });
#endif /* HAVE_EBPF */
#ifdef HAVE_XSK
using xskopt_t = LuaAssociativeTable<boost::variant<uint32_t, std::string>>;
dnsdist::xsk::g_xsk.push_back(socket);
return socket;
});
- luaCtx.registerFunction<std::string(std::shared_ptr<XskSocket>::*)()const>("getMetrics", [](const std::shared_ptr<XskSocket>& xsk) -> std::string {
+ luaCtx.registerFunction<std::string (std::shared_ptr<XskSocket>::*)() const>("getMetrics", [](const std::shared_ptr<XskSocket>& xsk) -> std::string {
if (!xsk) {
return {};
}
});
#endif /* HAVE_XSK */
/* EDNSOptionView */
- luaCtx.registerFunction<size_t(EDNSOptionView::*)()const>("count", [](const EDNSOptionView& option) {
- return option.values.size();
- });
- luaCtx.registerFunction<std::vector<string>(EDNSOptionView::*)()const>("getValues", [] (const EDNSOptionView& option) {
+ luaCtx.registerFunction<size_t (EDNSOptionView::*)() const>("count", [](const EDNSOptionView& option) {
+ return option.values.size();
+ });
+ luaCtx.registerFunction<std::vector<string> (EDNSOptionView::*)() const>("getValues", [](const EDNSOptionView& option) {
std::vector<string> values;
for (const auto& value : option.values) {
values.push_back(std::string(value.content, value.size));
return std::make_shared<DOHResponseMapEntry>(regex, status, PacketBuffer(content.begin(), content.end()), headers);
});
- luaCtx.writeFunction("newSVCRecordParameters", [](uint64_t priority, const std::string& target, boost::optional<svcParamsLua_t> additionalParameters)
- {
+ luaCtx.writeFunction("newSVCRecordParameters", [](uint64_t priority, const std::string& target, boost::optional<svcParamsLua_t> additionalParameters) {
checkParameterBound("newSVCRecordParameters", priority, std::numeric_limits<uint16_t>::max());
SVCRecordParameters parameters;
if (additionalParameters) {
if (client || configCheck) {
return;
}
- std::thread newThread(dnsdist::resolver::asynchronousResolver, std::move(hostname), [callback=std::move(callback)](const std::string& resolvedHostname, std::vector<ComboAddress>& ips) {
+ std::thread newThread(dnsdist::resolver::asynchronousResolver, std::move(hostname), [callback = std::move(callback)](const std::string& resolvedHostname, std::vector<ComboAddress>& ips) {
LuaArray<ComboAddress> result;
result.reserve(ips.size());
for (const auto& entry : ips) {
#include "statnode.hh"
#ifndef DISABLE_TOP_N_BINDINGS
-static LuaArray<std::vector<boost::variant<string,double>>> getGenResponses(uint64_t top, boost::optional<int> labels, std::function<bool(const Rings::Response&)> pred)
+static LuaArray<std::vector<boost::variant<string, double>>> getGenResponses(uint64_t top, boost::optional<int> labels, std::function<bool(const Rings::Response&)> pred)
{
setLuaNoSideEffect();
map<DNSName, unsigned int> counts;
- unsigned int total=0;
+ unsigned int total = 0;
{
for (const auto& shard : g_rings.d_shards) {
auto rl = shard->respRing.lock();
if (!labels) {
- for(const auto& a : *rl) {
- if(!pred(a))
+ for (const auto& a : *rl) {
+ if (!pred(a))
continue;
counts[a.name]++;
total++;
}
else {
unsigned int lab = *labels;
- for(const auto& a : *rl) {
- if(!pred(a))
+ for (const auto& a : *rl) {
+ if (!pred(a))
continue;
DNSName temp(a.name);
for (const auto& c : counts)
rcounts.emplace_back(c.second, c.first.makeLowerCase());
- sort(rcounts.begin(), rcounts.end(), [](const decltype(rcounts)::value_type& a,
- const decltype(rcounts)::value_type& b) {
- return b.first < a.first;
- });
+ sort(rcounts.begin(), rcounts.end(), [](const decltype(rcounts)::value_type& a, const decltype(rcounts)::value_type& b) {
+ return b.first < a.first;
+ });
- LuaArray<vector<boost::variant<string,double>>> ret;
+ LuaArray<vector<boost::variant<string, double>>> ret;
ret.reserve(std::min(rcounts.size(), static_cast<size_t>(top + 1U)));
int count = 1;
unsigned int rest = 0;
for (const auto& rc : rcounts) {
if (count == static_cast<int>(top + 1)) {
- rest+=rc.first;
+ rest += rc.first;
}
else {
- ret.push_back({count++, {rc.second.toString(), rc.first, 100.0*rc.first/total}});
+ ret.push_back({count++, {rc.second.toString(), rc.first, 100.0 * rc.first / total}});
}
}
if (total > 0) {
- ret.push_back({count, {"Rest", rest, 100.0*rest/total}});
+ ret.push_back({count, {"Rest", rest, 100.0 * rest / total}});
}
else {
- ret.push_back({count, {"Rest", rest, 100.0 }});
+ ret.push_back({count, {"Rest", rest, 100.0}});
}
return ret;
typedef std::unordered_map<ComboAddress, unsigned int, ComboAddress::addressOnlyHash, ComboAddress::addressOnlyEqual> counts_t;
static counts_t filterScore(const counts_t& counts,
- double delta, unsigned int rate)
+ double delta, unsigned int rate)
{
counts_t ret;
- double lim = delta*rate;
- for(const auto& c : counts) {
+ double lim = delta * rate;
+ for (const auto& c : counts) {
if (c.second > lim) {
ret[c.first] = c.second;
}
for (const auto& shard : g_rings.d_shards) {
auto rl = shard->respRing.lock();
- for(const auto& c : *rl) {
- if (now < c.when){
+ for (const auto& c : *rl) {
+ if (now < c.when) {
continue;
}
}
StatNode::Stat node;
- root.visit([visitor = std::move(visitor)](const StatNode* node_, const StatNode::Stat& self, const StatNode::Stat& children) {
- visitor(*node_, self, children);}, node);
+ root.visit([visitor = std::move(visitor)](const StatNode* node_, const StatNode::Stat& self, const StatNode::Stat& children) { visitor(*node_, self, children); }, node);
}
static LuaArray<LuaAssociativeTable<std::string>> getRespRing(boost::optional<int> rcode)
for (const auto& shard : g_rings.d_shards) {
auto rl = shard->respRing.lock();
- for(const auto& c : *rl) {
+ for (const auto& c : *rl) {
- if(seconds && c.when < cutoff)
+ if (seconds && c.when < cutoff)
continue;
- if(now < c.when)
+ if (now < c.when)
continue;
T(counts, c);
- if(c.when < mintime)
+ if (c.when < mintime)
mintime = c.when;
}
}
for (const auto& shard : g_rings.d_shards) {
auto rl = shard->queryRing.lock();
- for(const auto& c : *rl) {
- if(seconds && c.when < cutoff)
+ for (const auto& c : *rl) {
+ if (seconds && c.when < cutoff)
continue;
- if(now < c.when)
+ if (now < c.when)
continue;
T(counts, c);
- if(c.when < mintime)
+ if (c.when < mintime)
mintime = c.when;
}
}
return filterScore(counts, delta, rate);
}
-
static counts_t exceedRCode(unsigned int rate, int seconds, int rcode)
{
- return exceedRespGen(rate, seconds, [rcode](counts_t& counts, const Rings::Response& r)
- {
- if(r.dh.rcode == rcode)
- counts[r.requestor]++;
- });
+ return exceedRespGen(rate, seconds, [rcode](counts_t& counts, const Rings::Response& r) {
+ if (r.dh.rcode == rcode)
+ counts[r.requestor]++;
+ });
}
static counts_t exceedRespByterate(unsigned int rate, int seconds)
{
- return exceedRespGen(rate, seconds, [](counts_t& counts, const Rings::Response& r)
- {
- counts[r.requestor]+=r.size;
- });
+ return exceedRespGen(rate, seconds, [](counts_t& counts, const Rings::Response& r) {
+ counts[r.requestor] += r.size;
+ });
}
#endif /* DISABLE_DEPRECATED_DYNBLOCK */
{
#ifndef DISABLE_TOP_N_BINDINGS
luaCtx.writeFunction("topClients", [](boost::optional<uint64_t> top_) {
- setLuaNoSideEffect();
- uint64_t top = top_ ? *top_ : 10U;
- map<ComboAddress, unsigned int,ComboAddress::addressOnlyLessThan > counts;
- unsigned int total=0;
- {
- for (const auto& shard : g_rings.d_shards) {
- auto rl = shard->queryRing.lock();
- for(const auto& c : *rl) {
- counts[c.requestor]++;
- total++;
- }
+ setLuaNoSideEffect();
+ uint64_t top = top_ ? *top_ : 10U;
+ map<ComboAddress, unsigned int, ComboAddress::addressOnlyLessThan> counts;
+ unsigned int total = 0;
+ {
+ for (const auto& shard : g_rings.d_shards) {
+ auto rl = shard->queryRing.lock();
+ for (const auto& c : *rl) {
+ counts[c.requestor]++;
+ total++;
}
}
- vector<pair<unsigned int, ComboAddress>> rcounts;
- rcounts.reserve(counts.size());
- for(const auto& c : counts)
- rcounts.emplace_back(c.second, c.first);
-
- sort(rcounts.begin(), rcounts.end(), [](const decltype(rcounts)::value_type& a,
- const decltype(rcounts)::value_type& b) {
- return b.first < a.first;
- });
- unsigned int count=1, rest=0;
- boost::format fmt("%4d %-40s %4d %4.1f%%\n");
- for(const auto& rc : rcounts) {
- if(count==top+1)
- rest+=rc.first;
- else
- g_outputBuffer += (fmt % (count++) % rc.second.toString() % rc.first % (100.0*rc.first/total)).str();
- }
- g_outputBuffer += (fmt % (count) % "Rest" % rest % (total > 0 ? 100.0*rest/total : 100.0)).str();
- });
+ }
+ vector<pair<unsigned int, ComboAddress>> rcounts;
+ rcounts.reserve(counts.size());
+ for (const auto& c : counts)
+ rcounts.emplace_back(c.second, c.first);
+
+ sort(rcounts.begin(), rcounts.end(), [](const decltype(rcounts)::value_type& a, const decltype(rcounts)::value_type& b) {
+ return b.first < a.first;
+ });
+ unsigned int count = 1, rest = 0;
+ boost::format fmt("%4d %-40s %4d %4.1f%%\n");
+ for (const auto& rc : rcounts) {
+ if (count == top + 1)
+ rest += rc.first;
+ else
+ g_outputBuffer += (fmt % (count++) % rc.second.toString() % rc.first % (100.0 * rc.first / total)).str();
+ }
+ g_outputBuffer += (fmt % (count) % "Rest" % rest % (total > 0 ? 100.0 * rest / total : 100.0)).str();
+ });
luaCtx.writeFunction("getTopQueries", [](uint64_t top, boost::optional<int> labels) {
- setLuaNoSideEffect();
- map<DNSName, unsigned int> counts;
- unsigned int total=0;
- if(!labels) {
- for (const auto& shard : g_rings.d_shards) {
- auto rl = shard->queryRing.lock();
- for(const auto& a : *rl) {
- counts[a.name]++;
- total++;
- }
+ setLuaNoSideEffect();
+ map<DNSName, unsigned int> counts;
+ unsigned int total = 0;
+ if (!labels) {
+ for (const auto& shard : g_rings.d_shards) {
+ auto rl = shard->queryRing.lock();
+ for (const auto& a : *rl) {
+ counts[a.name]++;
+ total++;
}
}
- else {
- unsigned int lab = *labels;
- for (const auto& shard : g_rings.d_shards) {
- auto rl = shard->queryRing.lock();
- // coverity[auto_causes_copy]
- for (auto a : *rl) {
- a.name.trimToLabels(lab);
- counts[a.name]++;
- total++;
- }
+ }
+ else {
+ unsigned int lab = *labels;
+ for (const auto& shard : g_rings.d_shards) {
+ auto rl = shard->queryRing.lock();
+ // coverity[auto_causes_copy]
+ for (auto a : *rl) {
+ a.name.trimToLabels(lab);
+ counts[a.name]++;
+ total++;
}
}
- // cout<<"Looked at "<<total<<" queries, "<<counts.size()<<" different ones"<<endl;
- vector<pair<unsigned int, DNSName>> rcounts;
- rcounts.reserve(counts.size());
- for(const auto& c : counts)
- rcounts.emplace_back(c.second, c.first.makeLowerCase());
-
- sort(rcounts.begin(), rcounts.end(), [](const decltype(rcounts)::value_type& a,
- const decltype(rcounts)::value_type& b) {
- return b.first < a.first;
- });
-
- std::unordered_map<unsigned int, vector<boost::variant<string,double>>> ret;
- unsigned int count=1, rest=0;
- for(const auto& rc : rcounts) {
- if(count==top+1)
- rest+=rc.first;
- else
- ret.insert({count++, {rc.second.toString(), rc.first, 100.0*rc.first/total}});
- }
-
- if (total > 0) {
- ret.insert({count, {"Rest", rest, 100.0*rest/total}});
- }
- else {
- ret.insert({count, {"Rest", rest, 100.0}});
- }
+ }
+ // cout<<"Looked at "<<total<<" queries, "<<counts.size()<<" different ones"<<endl;
+ vector<pair<unsigned int, DNSName>> rcounts;
+ rcounts.reserve(counts.size());
+ for (const auto& c : counts)
+ rcounts.emplace_back(c.second, c.first.makeLowerCase());
+
+ sort(rcounts.begin(), rcounts.end(), [](const decltype(rcounts)::value_type& a, const decltype(rcounts)::value_type& b) {
+ return b.first < a.first;
+ });
+
+ std::unordered_map<unsigned int, vector<boost::variant<string, double>>> ret;
+ unsigned int count = 1, rest = 0;
+ for (const auto& rc : rcounts) {
+ if (count == top + 1)
+ rest += rc.first;
+ else
+ ret.insert({count++, {rc.second.toString(), rc.first, 100.0 * rc.first / total}});
+ }
- return ret;
+ if (total > 0) {
+ ret.insert({count, {"Rest", rest, 100.0 * rest / total}});
+ }
+ else {
+ ret.insert({count, {"Rest", rest, 100.0}});
+ }
- });
+ return ret;
+ });
luaCtx.executeCode(R"(function topQueries(top, labels) top = top or 10; for k,v in ipairs(getTopQueries(top,labels)) do show(string.format("%4d %-40s %4d %4.1f%%",k,v[1],v[2], v[3])) end end)");
luaCtx.writeFunction("getResponseRing", []() {
- setLuaNoSideEffect();
- size_t totalEntries = 0;
- std::vector<boost::circular_buffer<Rings::Response>> rings;
- rings.reserve(g_rings.getNumberOfShards());
- for (const auto& shard : g_rings.d_shards) {
- {
- auto rl = shard->respRing.lock();
- rings.push_back(*rl);
- }
- totalEntries += rings.back().size();
- }
- vector<std::unordered_map<string, boost::variant<string, unsigned int> > > ret;
- ret.reserve(totalEntries);
- decltype(ret)::value_type item;
- for (size_t idx = 0; idx < rings.size(); idx++) {
- for(const auto& r : rings[idx]) {
- item["name"]=r.name.toString();
- item["qtype"]=r.qtype;
- item["rcode"]=r.dh.rcode;
- item["usec"]=r.usec;
- ret.push_back(item);
- }
+ setLuaNoSideEffect();
+ size_t totalEntries = 0;
+ std::vector<boost::circular_buffer<Rings::Response>> rings;
+ rings.reserve(g_rings.getNumberOfShards());
+ for (const auto& shard : g_rings.d_shards) {
+ {
+ auto rl = shard->respRing.lock();
+ rings.push_back(*rl);
}
- return ret;
- });
+ totalEntries += rings.back().size();
+ }
+ vector<std::unordered_map<string, boost::variant<string, unsigned int>>> ret;
+ ret.reserve(totalEntries);
+ decltype(ret)::value_type item;
+ for (size_t idx = 0; idx < rings.size(); idx++) {
+ for (const auto& r : rings[idx]) {
+ item["name"] = r.name.toString();
+ item["qtype"] = r.qtype;
+ item["rcode"] = r.dh.rcode;
+ item["usec"] = r.usec;
+ ret.push_back(item);
+ }
+ }
+ return ret;
+ });
luaCtx.writeFunction("getTopResponses", [](uint64_t top, uint64_t kind, boost::optional<int> labels) {
- return getGenResponses(top, labels, [kind](const Rings::Response& r) { return r.dh.rcode == kind; });
- });
+ return getGenResponses(top, labels, [kind](const Rings::Response& r) { return r.dh.rcode == kind; });
+ });
luaCtx.executeCode(R"(function topResponses(top, kind, labels) top = top or 10; kind = kind or 0; for k,v in ipairs(getTopResponses(top, kind, labels)) do show(string.format("%4d %-40s %4d %4.1f%%",k,v[1],v[2],v[3])) end end)");
-
luaCtx.writeFunction("getSlowResponses", [](uint64_t top, uint64_t msec, boost::optional<int> labels) {
- return getGenResponses(top, labels, [msec](const Rings::Response& r) { return r.usec > msec*1000; });
- });
-
+ return getGenResponses(top, labels, [msec](const Rings::Response& r) { return r.usec > msec * 1000; });
+ });
luaCtx.executeCode(R"(function topSlow(top, msec, labels) top = top or 10; msec = msec or 500; for k,v in ipairs(getSlowResponses(top, msec, labels)) do show(string.format("%4d %-40s %4d %4.1f%%",k,v[1],v[2],v[3])) end end)");
luaCtx.writeFunction("getTopBandwidth", [](uint64_t top) {
- setLuaNoSideEffect();
- return g_rings.getTopBandwidth(top);
- });
+ setLuaNoSideEffect();
+ return g_rings.getTopBandwidth(top);
+ });
luaCtx.executeCode(R"(function topBandwidth(top) top = top or 10; for k,v in ipairs(getTopBandwidth(top)) do show(string.format("%4d %-40s %4d %4.1f%%",k,v[1],v[2],v[3])) end end)");
#endif /* DISABLE_TOP_N_BINDINGS */
luaCtx.writeFunction("delta", []() {
- setLuaNoSideEffect();
- // we hold the lua lock already!
- for(const auto& d : g_confDelta) {
- struct tm tm;
- localtime_r(&d.first.tv_sec, &tm);
- char date[80];
- strftime(date, sizeof(date)-1, "-- %a %b %d %Y %H:%M:%S %Z\n", &tm);
- g_outputBuffer += date;
- g_outputBuffer += d.second + "\n";
- }
- });
+ setLuaNoSideEffect();
+ // we hold the lua lock already!
+ for (const auto& d : g_confDelta) {
+ struct tm tm;
+ localtime_r(&d.first.tv_sec, &tm);
+ char date[80];
+ strftime(date, sizeof(date) - 1, "-- %a %b %d %Y %H:%M:%S %Z\n", &tm);
+ g_outputBuffer += date;
+ g_outputBuffer += d.second + "\n";
+ }
+ });
luaCtx.writeFunction("grepq", [](LuaTypeOrArrayOf<std::string> inp, boost::optional<unsigned int> limit, boost::optional<LuaAssociativeTable<std::string>> options) {
- setLuaNoSideEffect();
- boost::optional<Netmask> nm;
- boost::optional<DNSName> dn;
- int msec = -1;
- std::unique_ptr<FILE, decltype(&fclose)> outputFile{nullptr, fclose};
-
- if (options) {
- std::string outputFileName;
- if (getOptionalValue<std::string>(options, "outputFile", outputFileName) > 0) {
- int fd = open(outputFileName.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0600);
- if (fd < 0) {
- g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n";
- return;
- }
- outputFile = std::unique_ptr<FILE, decltype(&fclose)>(fdopen(fd, "w"), fclose);
- if (outputFile == nullptr) {
- g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n";
- close(fd);
- return;
- }
- }
- checkAllParametersConsumed("grepq", options);
- }
+ setLuaNoSideEffect();
+ boost::optional<Netmask> nm;
+ boost::optional<DNSName> dn;
+ int msec = -1;
+ std::unique_ptr<FILE, decltype(&fclose)> outputFile{nullptr, fclose};
+
+ if (options) {
+ std::string outputFileName;
+ if (getOptionalValue<std::string>(options, "outputFile", outputFileName) > 0) {
+ int fd = open(outputFileName.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0600);
+ if (fd < 0) {
+ g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n";
+ return;
+ }
+ outputFile = std::unique_ptr<FILE, decltype(&fclose)>(fdopen(fd, "w"), fclose);
+ if (outputFile == nullptr) {
+ g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n";
+ close(fd);
+ return;
+ }
+ }
+ checkAllParametersConsumed("grepq", options);
+ }
- vector<string> vec;
- auto str = boost::get<string>(&inp);
- if (str) {
- vec.push_back(*str);
- }
- else {
- auto v = boost::get<LuaArray<std::string>>(inp);
- for (const auto& a: v) {
- vec.push_back(a.second);
- }
+ vector<string> vec;
+ auto str = boost::get<string>(&inp);
+ if (str) {
+ vec.push_back(*str);
+ }
+ else {
+ auto v = boost::get<LuaArray<std::string>>(inp);
+ for (const auto& a : v) {
+ vec.push_back(a.second);
}
+ }
- for (const auto& s : vec) {
- try {
- nm = Netmask(s);
+ for (const auto& s : vec) {
+ try {
+ nm = Netmask(s);
+ }
+ catch (...) {
+ if (boost::ends_with(s, "ms") && sscanf(s.c_str(), "%ums", &msec)) {
+ ;
}
- catch (...) {
- if (boost::ends_with(s,"ms") && sscanf(s.c_str(), "%ums", &msec)) {
- ;
+ else {
+ try {
+ dn = DNSName(s);
}
- else {
- try {
- dn = DNSName(s);
- }
- catch (...) {
- g_outputBuffer = "Could not parse '"+s+"' as domain name or netmask";
- return;
- }
+ catch (...) {
+ g_outputBuffer = "Could not parse '" + s + "' as domain name or netmask";
+ return;
}
}
}
+ }
- std::vector<Rings::Query> qr;
- std::vector<Rings::Response> rr;
- qr.reserve(g_rings.getNumberOfQueryEntries());
- rr.reserve(g_rings.getNumberOfResponseEntries());
- for (const auto& shard : g_rings.d_shards) {
- {
- auto rl = shard->queryRing.lock();
- for (const auto& entry : *rl) {
- qr.push_back(entry);
- }
+ std::vector<Rings::Query> qr;
+ std::vector<Rings::Response> rr;
+ qr.reserve(g_rings.getNumberOfQueryEntries());
+ rr.reserve(g_rings.getNumberOfResponseEntries());
+ for (const auto& shard : g_rings.d_shards) {
+ {
+ auto rl = shard->queryRing.lock();
+ for (const auto& entry : *rl) {
+ qr.push_back(entry);
}
- {
- auto rl = shard->respRing.lock();
- for (const auto& entry : *rl) {
- rr.push_back(entry);
- }
+ }
+ {
+ auto rl = shard->respRing.lock();
+ for (const auto& entry : *rl) {
+ rr.push_back(entry);
}
}
+ }
- sort(qr.begin(), qr.end(), [](const decltype(qr)::value_type& a, const decltype(qr)::value_type& b) {
- return b.when < a.when;
- });
-
- sort(rr.begin(), rr.end(), [](const decltype(rr)::value_type& a, const decltype(rr)::value_type& b) {
- return b.when < a.when;
- });
+ sort(qr.begin(), qr.end(), [](const decltype(qr)::value_type& a, const decltype(qr)::value_type& b) {
+ return b.when < a.when;
+ });
- unsigned int num=0;
- struct timespec now;
- gettime(&now);
+ sort(rr.begin(), rr.end(), [](const decltype(rr)::value_type& a, const decltype(rr)::value_type& b) {
+ return b.when < a.when;
+ });
- std::multimap<struct timespec, string> out;
+ unsigned int num = 0;
+ struct timespec now;
+ gettime(&now);
- boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n");
- const auto headLine = (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str();
- if (!outputFile) {
- g_outputBuffer += headLine;
- }
- else {
- fprintf(outputFile.get(), "%s", headLine.c_str());
- }
+ std::multimap<struct timespec, string> out;
- if (msec == -1) {
- for (const auto& c : qr) {
- bool nmmatch = true;
- bool dnmatch = true;
- if (nm) {
- nmmatch = nm->match(c.requestor);
- }
- if (dn) {
- if (c.name.empty()) {
- dnmatch = false;
- }
- else {
- dnmatch = c.name.isPartOf(*dn);
- }
- }
- if (nmmatch && dnmatch) {
- QType qt(c.qtype);
- std::string extra;
- if (c.dh.opcode != 0) {
- extra = " (" + Opcode::to_s(c.dh.opcode) + ")";
- }
- out.emplace(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % "" % htons(c.dh.id) % c.name.toString() % qt.toString() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd ? "RD" : "") % (c.dh.aa ? "AA" : "") % ("Question" + extra)).str());
-
- if (limit && *limit == ++num) {
- break;
- }
- }
- }
- }
- num = 0;
+ boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n");
+ const auto headLine = (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str();
+ if (!outputFile) {
+ g_outputBuffer += headLine;
+ }
+ else {
+ fprintf(outputFile.get(), "%s", headLine.c_str());
+ }
- string extra;
- for (const auto& c : rr) {
+ if (msec == -1) {
+ for (const auto& c : qr) {
bool nmmatch = true;
bool dnmatch = true;
- bool msecmatch = true;
if (nm) {
nmmatch = nm->match(c.requestor);
}
dnmatch = c.name.isPartOf(*dn);
}
}
- if (msec != -1) {
- msecmatch = (c.usec/1000 > (unsigned int)msec);
- }
-
- if (nmmatch && dnmatch && msecmatch) {
+ if (nmmatch && dnmatch) {
QType qt(c.qtype);
- if (!c.dh.rcode) {
- extra = ". " +std::to_string(htons(c.dh.ancount)) + " answers";
- }
- else {
- extra.clear();
- }
-
- std::string server = c.ds.toStringWithPort();
- std::string protocol = dnsdist::Protocol(c.protocol).toString();
- if (server == "0.0.0.0:0") {
- server = "Cache";
- protocol = "-";
- }
- if (c.usec != std::numeric_limits<decltype(c.usec)>::max()) {
- out.emplace(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % protocol % server % htons(c.dh.id) % c.name.toString() % qt.toString() % (c.usec / 1000.0) % (c.dh.tc ? "TC" : "") % (c.dh.rd ? "RD" : "") % (c.dh.aa ? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str());
- }
- else {
- out.emplace(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % protocol % server % htons(c.dh.id) % c.name.toString() % qt.toString() % "T.O" % (c.dh.tc ? "TC" : "") % (c.dh.rd ? "RD" : "") % (c.dh.aa ? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str());
+ std::string extra;
+ if (c.dh.opcode != 0) {
+ extra = " (" + Opcode::to_s(c.dh.opcode) + ")";
}
+ out.emplace(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % "" % htons(c.dh.id) % c.name.toString() % qt.toString() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd ? "RD" : "") % (c.dh.aa ? "AA" : "") % ("Question" + extra)).str());
if (limit && *limit == ++num) {
break;
}
}
}
+ }
+ num = 0;
- for (const auto& p : out) {
- if (!outputFile) {
- g_outputBuffer += p.second;
+ string extra;
+ for (const auto& c : rr) {
+ bool nmmatch = true;
+ bool dnmatch = true;
+ bool msecmatch = true;
+ if (nm) {
+ nmmatch = nm->match(c.requestor);
+ }
+ if (dn) {
+ if (c.name.empty()) {
+ dnmatch = false;
}
else {
- fprintf(outputFile.get(), "%s", p.second.c_str());
+ dnmatch = c.name.isPartOf(*dn);
}
}
- });
-
- luaCtx.writeFunction("showResponseLatency", []() {
- setLuaNoSideEffect();
- map<double, unsigned int> histo;
- double bin=100;
- for(int i=0; i < 15; ++i) {
- histo[bin];
- bin*=2;
+ if (msec != -1) {
+ msecmatch = (c.usec / 1000 > (unsigned int)msec);
}
- double totlat=0;
- unsigned int size=0;
- {
- for (const auto& shard : g_rings.d_shards) {
- auto rl = shard->respRing.lock();
- for(const auto& r : *rl) {
- /* skip actively discovered timeouts */
- if (r.usec == std::numeric_limits<unsigned int>::max())
- continue;
-
- ++size;
- auto iter = histo.lower_bound(r.usec);
- if(iter != histo.end())
- iter->second++;
- else
- histo.rbegin()++;
- totlat+=r.usec;
- }
+ if (nmmatch && dnmatch && msecmatch) {
+ QType qt(c.qtype);
+ if (!c.dh.rcode) {
+ extra = ". " + std::to_string(htons(c.dh.ancount)) + " answers";
+ }
+ else {
+ extra.clear();
+ }
+
+ std::string server = c.ds.toStringWithPort();
+ std::string protocol = dnsdist::Protocol(c.protocol).toString();
+ if (server == "0.0.0.0:0") {
+ server = "Cache";
+ protocol = "-";
+ }
+ if (c.usec != std::numeric_limits<decltype(c.usec)>::max()) {
+ out.emplace(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % protocol % server % htons(c.dh.id) % c.name.toString() % qt.toString() % (c.usec / 1000.0) % (c.dh.tc ? "TC" : "") % (c.dh.rd ? "RD" : "") % (c.dh.aa ? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str());
+ }
+ else {
+ out.emplace(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % protocol % server % htons(c.dh.id) % c.name.toString() % qt.toString() % "T.O" % (c.dh.tc ? "TC" : "") % (c.dh.rd ? "RD" : "") % (c.dh.aa ? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str());
+ }
+
+ if (limit && *limit == ++num) {
+ break;
}
}
+ }
- if (size == 0) {
- g_outputBuffer = "No traffic yet.\n";
- return;
+ for (const auto& p : out) {
+ if (!outputFile) {
+ g_outputBuffer += p.second;
+ }
+ else {
+ fprintf(outputFile.get(), "%s", p.second.c_str());
}
+ }
+ });
- g_outputBuffer = (boost::format("Average response latency: %.02f ms\n") % (0.001*totlat/size)).str();
- double highest=0;
+ luaCtx.writeFunction("showResponseLatency", []() {
+ setLuaNoSideEffect();
+ map<double, unsigned int> histo;
+ double bin = 100;
+ for (int i = 0; i < 15; ++i) {
+ histo[bin];
+ bin *= 2;
+ }
- for(auto iter = histo.cbegin(); iter != histo.cend(); ++iter) {
- highest=std::max(highest, iter->second*1.0);
- }
- boost::format fmt("%7.2f\t%s\n");
- g_outputBuffer += (fmt % "ms" % "").str();
+ double totlat = 0;
+ unsigned int size = 0;
+ {
+ for (const auto& shard : g_rings.d_shards) {
+ auto rl = shard->respRing.lock();
+ for (const auto& r : *rl) {
+ /* skip actively discovered timeouts */
+ if (r.usec == std::numeric_limits<unsigned int>::max())
+ continue;
- for(auto iter = histo.cbegin(); iter != histo.cend(); ++iter) {
- int stars = (70.0 * iter->second/highest);
- char c='*';
- if(!stars && iter->second) {
- stars=1; // you get 1 . to show something is there..
- if(70.0*iter->second/highest > 0.5)
- c=':';
- else
- c='.';
- }
- g_outputBuffer += (fmt % (iter->first/1000.0) % string(stars, c)).str();
+ ++size;
+ auto iter = histo.lower_bound(r.usec);
+ if (iter != histo.end())
+ iter->second++;
+ else
+ histo.rbegin()++;
+ totlat += r.usec;
+ }
}
- });
+ }
- luaCtx.writeFunction("showTCPStats", [] {
- setLuaNoSideEffect();
- ostringstream ret;
- boost::format fmt("%-12d %-12d %-12d %-12d");
- ret << (fmt % "Workers" % "Max Workers" % "Queued" % "Max Queued") << endl;
- ret << (fmt % g_tcpclientthreads->getThreadsCount() % (g_maxTCPClientThreads ? *g_maxTCPClientThreads : 0) % g_tcpclientthreads->getQueuedCount() % g_maxTCPQueuedConnections) << endl;
- ret << endl;
+ if (size == 0) {
+ g_outputBuffer = "No traffic yet.\n";
+ return;
+ }
- ret << "Frontends:" << endl;
- fmt = boost::format("%-3d %-20.20s %-20d %-20d %-20d %-25d %-20d %-20d %-20d %-20f %-20f %-20d %-20d %-25d %-25d %-15d %-15d %-15d %-15d %-15d");
- ret << (fmt % "#" % "Address" % "Connections" % "Max concurrent conn" % "Died reading query" % "Died sending response" % "Gave up" % "Client timeouts" % "Downstream timeouts" % "Avg queries/conn" % "Avg duration" % "TLS new sessions" % "TLS Resumptions" % "TLS unknown ticket keys" % "TLS inactive ticket keys" % "TLS 1.0" % "TLS 1.1" % "TLS 1.2" % "TLS 1.3" % "TLS other") << endl;
+ g_outputBuffer = (boost::format("Average response latency: %.02f ms\n") % (0.001 * totlat / size)).str();
+ double highest = 0;
- size_t counter = 0;
- for(const auto& f : g_frontends) {
- ret << (fmt % counter % f->local.toStringWithPort() % f->tcpCurrentConnections % f->tcpMaxConcurrentConnections % f->tcpDiedReadingQuery % f->tcpDiedSendingResponse % f->tcpGaveUp % f->tcpClientTimeouts % f->tcpDownstreamTimeouts % f->tcpAvgQueriesPerConnection % f->tcpAvgConnectionDuration % f->tlsNewSessions % f->tlsResumptions % f->tlsUnknownTicketKey % f->tlsInactiveTicketKey % f->tls10queries % f->tls11queries % f->tls12queries % f->tls13queries % f->tlsUnknownqueries) << endl;
- ++counter;
- }
- ret << endl;
+ for (auto iter = histo.cbegin(); iter != histo.cend(); ++iter) {
+ highest = std::max(highest, iter->second * 1.0);
+ }
+ boost::format fmt("%7.2f\t%s\n");
+ g_outputBuffer += (fmt % "ms" % "").str();
+
+ for (auto iter = histo.cbegin(); iter != histo.cend(); ++iter) {
+ int stars = (70.0 * iter->second / highest);
+ char c = '*';
+ if (!stars && iter->second) {
+ stars = 1; // you get 1 . to show something is there..
+ if (70.0 * iter->second / highest > 0.5)
+ c = ':';
+ else
+ c = '.';
+ }
+ g_outputBuffer += (fmt % (iter->first / 1000.0) % string(stars, c)).str();
+ }
+ });
- ret << "Backends:" << endl;
- fmt = boost::format("%-3d %-20.20s %-20.20s %-20d %-20d %-25d %-25d %-20d %-20d %-20d %-20d %-20d %-20d %-20d %-20d %-20f %-20f");
- ret << (fmt % "#" % "Name" % "Address" % "Connections" % "Max concurrent conn" % "Died sending query" % "Died reading response" % "Gave up" % "Read timeouts" % "Write timeouts" % "Connect timeouts" % "Too many conn" % "Total connections" % "Reused connections" % "TLS resumptions" % "Avg queries/conn" % "Avg duration") << endl;
+ luaCtx.writeFunction("showTCPStats", [] {
+ setLuaNoSideEffect();
+ ostringstream ret;
+ boost::format fmt("%-12d %-12d %-12d %-12d");
+ ret << (fmt % "Workers" % "Max Workers" % "Queued" % "Max Queued") << endl;
+ ret << (fmt % g_tcpclientthreads->getThreadsCount() % (g_maxTCPClientThreads ? *g_maxTCPClientThreads : 0) % g_tcpclientthreads->getQueuedCount() % g_maxTCPQueuedConnections) << endl;
+ ret << endl;
+
+ ret << "Frontends:" << endl;
+ fmt = boost::format("%-3d %-20.20s %-20d %-20d %-20d %-25d %-20d %-20d %-20d %-20f %-20f %-20d %-20d %-25d %-25d %-15d %-15d %-15d %-15d %-15d");
+ ret << (fmt % "#" % "Address" % "Connections" % "Max concurrent conn" % "Died reading query" % "Died sending response" % "Gave up" % "Client timeouts" % "Downstream timeouts" % "Avg queries/conn" % "Avg duration" % "TLS new sessions" % "TLS Resumptions" % "TLS unknown ticket keys" % "TLS inactive ticket keys" % "TLS 1.0" % "TLS 1.1" % "TLS 1.2" % "TLS 1.3" % "TLS other") << endl;
+
+ size_t counter = 0;
+ for (const auto& f : g_frontends) {
+ ret << (fmt % counter % f->local.toStringWithPort() % f->tcpCurrentConnections % f->tcpMaxConcurrentConnections % f->tcpDiedReadingQuery % f->tcpDiedSendingResponse % f->tcpGaveUp % f->tcpClientTimeouts % f->tcpDownstreamTimeouts % f->tcpAvgQueriesPerConnection % f->tcpAvgConnectionDuration % f->tlsNewSessions % f->tlsResumptions % f->tlsUnknownTicketKey % f->tlsInactiveTicketKey % f->tls10queries % f->tls11queries % f->tls12queries % f->tls13queries % f->tlsUnknownqueries) << endl;
+ ++counter;
+ }
+ ret << endl;
- auto states = g_dstates.getLocal();
- counter = 0;
- for(const auto& s : *states) {
- ret << (fmt % counter % s->getName() % s->d_config.remote.toStringWithPort() % s->tcpCurrentConnections % s->tcpMaxConcurrentConnections % s->tcpDiedSendingQuery % s->tcpDiedReadingResponse % s->tcpGaveUp % s->tcpReadTimeouts % s->tcpWriteTimeouts % s->tcpConnectTimeouts % s->tcpTooManyConcurrentConnections % s->tcpNewConnections % s->tcpReusedConnections % s->tlsResumptions % s->tcpAvgQueriesPerConnection % s->tcpAvgConnectionDuration) << endl;
- ++counter;
- }
+ ret << "Backends:" << endl;
+ fmt = boost::format("%-3d %-20.20s %-20.20s %-20d %-20d %-25d %-25d %-20d %-20d %-20d %-20d %-20d %-20d %-20d %-20d %-20f %-20f");
+ ret << (fmt % "#" % "Name" % "Address" % "Connections" % "Max concurrent conn" % "Died sending query" % "Died reading response" % "Gave up" % "Read timeouts" % "Write timeouts" % "Connect timeouts" % "Too many conn" % "Total connections" % "Reused connections" % "TLS resumptions" % "Avg queries/conn" % "Avg duration") << endl;
- g_outputBuffer=ret.str();
- });
+ auto states = g_dstates.getLocal();
+ counter = 0;
+ for (const auto& s : *states) {
+ ret << (fmt % counter % s->getName() % s->d_config.remote.toStringWithPort() % s->tcpCurrentConnections % s->tcpMaxConcurrentConnections % s->tcpDiedSendingQuery % s->tcpDiedReadingResponse % s->tcpGaveUp % s->tcpReadTimeouts % s->tcpWriteTimeouts % s->tcpConnectTimeouts % s->tcpTooManyConcurrentConnections % s->tcpNewConnections % s->tcpReusedConnections % s->tlsResumptions % s->tcpAvgQueriesPerConnection % s->tcpAvgConnectionDuration) << endl;
+ ++counter;
+ }
+
+ g_outputBuffer = ret.str();
+ });
luaCtx.writeFunction("showTLSErrorCounters", [] {
- setLuaNoSideEffect();
- ostringstream ret;
- boost::format fmt("%-3d %-20.20s %-23d %-23d %-23d %-23d %-23d %-23d %-23d %-23d");
+ setLuaNoSideEffect();
+ ostringstream ret;
+ boost::format fmt("%-3d %-20.20s %-23d %-23d %-23d %-23d %-23d %-23d %-23d %-23d");
- ret << (fmt % "#" % "Address" % "DH key too small" % "Inappropriate fallback" % "No shared cipher" % "Unknown cipher type" % "Unknown exchange type" % "Unknown protocol" % "Unsupported EC" % "Unsupported protocol") << endl;
+ ret << (fmt % "#" % "Address" % "DH key too small" % "Inappropriate fallback" % "No shared cipher" % "Unknown cipher type" % "Unknown exchange type" % "Unknown protocol" % "Unsupported EC" % "Unsupported protocol") << endl;
- size_t counter = 0;
- for(const auto& f : g_frontends) {
- if (!f->hasTLS()) {
- continue;
- }
- const TLSErrorCounters* errorCounters = nullptr;
- if (f->tlsFrontend != nullptr) {
- errorCounters = &f->tlsFrontend->d_tlsCounters;
- }
- else if (f->dohFrontend != nullptr) {
- errorCounters = &f->dohFrontend->d_tlsContext.d_tlsCounters;
- }
- if (errorCounters == nullptr) {
- continue;
- }
-
- ret << (fmt % counter % f->local.toStringWithPort() % errorCounters->d_dhKeyTooSmall % errorCounters->d_inappropriateFallBack % errorCounters->d_noSharedCipher % errorCounters->d_unknownCipherType % errorCounters->d_unknownKeyExchangeType % errorCounters->d_unknownProtocol % errorCounters->d_unsupportedEC % errorCounters->d_unsupportedProtocol) << endl;
- ++counter;
+ size_t counter = 0;
+ for (const auto& f : g_frontends) {
+ if (!f->hasTLS()) {
+ continue;
+ }
+ const TLSErrorCounters* errorCounters = nullptr;
+ if (f->tlsFrontend != nullptr) {
+ errorCounters = &f->tlsFrontend->d_tlsCounters;
+ }
+ else if (f->dohFrontend != nullptr) {
+ errorCounters = &f->dohFrontend->d_tlsContext.d_tlsCounters;
+ }
+ if (errorCounters == nullptr) {
+ continue;
}
- ret << endl;
- g_outputBuffer=ret.str();
- });
+ ret << (fmt % counter % f->local.toStringWithPort() % errorCounters->d_dhKeyTooSmall % errorCounters->d_inappropriateFallBack % errorCounters->d_noSharedCipher % errorCounters->d_unknownCipherType % errorCounters->d_unknownKeyExchangeType % errorCounters->d_unknownProtocol % errorCounters->d_unsupportedEC % errorCounters->d_unsupportedProtocol) << endl;
+ ++counter;
+ }
+ ret << endl;
+
+ g_outputBuffer = ret.str();
+ });
luaCtx.writeFunction("requestTCPStatesDump", [] {
setLuaNoSideEffect();
});
luaCtx.writeFunction("dumpStats", [] {
- setLuaNoSideEffect();
- vector<string> leftcolumn, rightcolumn;
-
- boost::format fmt("%-35s\t%+11s");
- g_outputBuffer.clear();
- auto entries = *dnsdist::metrics::g_stats.entries.read_lock();
- sort(entries.begin(), entries.end(),
- [](const decltype(entries)::value_type& a, const decltype(entries)::value_type& b) {
- return a.d_name < b.d_name;
- });
- boost::format flt(" %9.1f");
- for (const auto& entry : entries) {
- string second;
- if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
- second = std::to_string((*val)->load());
- }
- else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&entry.d_value)) {
- second = (flt % (*adval)->load()).str();
- }
- else if (const auto& dval = std::get_if<double*>(&entry.d_value)) {
- second = (flt % (**dval)).str();
- }
- else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&entry.d_value)) {
- second = std::to_string((*func)(entry.d_name));
- }
+ setLuaNoSideEffect();
+ vector<string> leftcolumn, rightcolumn;
- if (leftcolumn.size() < entries.size() / 2) {
- leftcolumn.push_back((fmt % entry.d_name % second).str());
- }
- else {
- rightcolumn.push_back((fmt % entry.d_name % second).str());
- }
+ boost::format fmt("%-35s\t%+11s");
+ g_outputBuffer.clear();
+ auto entries = *dnsdist::metrics::g_stats.entries.read_lock();
+ sort(entries.begin(), entries.end(),
+ [](const decltype(entries)::value_type& a, const decltype(entries)::value_type& b) {
+ return a.d_name < b.d_name;
+ });
+ boost::format flt(" %9.1f");
+ for (const auto& entry : entries) {
+ string second;
+ if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
+ second = std::to_string((*val)->load());
+ }
+ else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&entry.d_value)) {
+ second = (flt % (*adval)->load()).str();
+ }
+ else if (const auto& dval = std::get_if<double*>(&entry.d_value)) {
+ second = (flt % (**dval)).str();
+ }
+ else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&entry.d_value)) {
+ second = std::to_string((*func)(entry.d_name));
+ }
+
+ if (leftcolumn.size() < entries.size() / 2) {
+ leftcolumn.push_back((fmt % entry.d_name % second).str());
+ }
+ else {
+ rightcolumn.push_back((fmt % entry.d_name % second).str());
}
+ }
- auto leftiter=leftcolumn.begin(), rightiter=rightcolumn.begin();
- boost::format clmn("%|0t|%1% %|51t|%2%\n");
+ auto leftiter = leftcolumn.begin(), rightiter = rightcolumn.begin();
+ boost::format clmn("%|0t|%1% %|51t|%2%\n");
- for(;leftiter != leftcolumn.end() || rightiter != rightcolumn.end();) {
- string lentry, rentry;
- if(leftiter!= leftcolumn.end()) {
- lentry = *leftiter;
- leftiter++;
- }
- if(rightiter!= rightcolumn.end()) {
- rentry = *rightiter;
- rightiter++;
- }
- g_outputBuffer += (clmn % lentry % rentry).str();
+ for (; leftiter != leftcolumn.end() || rightiter != rightcolumn.end();) {
+ string lentry, rentry;
+ if (leftiter != leftcolumn.end()) {
+ lentry = *leftiter;
+ leftiter++;
}
- });
+ if (rightiter != rightcolumn.end()) {
+ rentry = *rightiter;
+ rightiter++;
+ }
+ g_outputBuffer += (clmn % lentry % rentry).str();
+ }
+ });
#ifndef DISABLE_DYNBLOCKS
#ifndef DISABLE_DEPRECATED_DYNBLOCK
luaCtx.writeFunction("exceedServFails", [](unsigned int rate, int seconds) {
- setLuaNoSideEffect();
- return exceedRCode(rate, seconds, RCode::ServFail);
- });
+ setLuaNoSideEffect();
+ return exceedRCode(rate, seconds, RCode::ServFail);
+ });
luaCtx.writeFunction("exceedNXDOMAINs", [](unsigned int rate, int seconds) {
- setLuaNoSideEffect();
- return exceedRCode(rate, seconds, RCode::NXDomain);
- });
+ setLuaNoSideEffect();
+ return exceedRCode(rate, seconds, RCode::NXDomain);
+ });
luaCtx.writeFunction("exceedRespByterate", [](unsigned int rate, int seconds) {
- setLuaNoSideEffect();
- return exceedRespByterate(rate, seconds);
- });
+ setLuaNoSideEffect();
+ return exceedRespByterate(rate, seconds);
+ });
luaCtx.writeFunction("exceedQTypeRate", [](uint16_t type, unsigned int rate, int seconds) {
- setLuaNoSideEffect();
- return exceedQueryGen(rate, seconds, [type](counts_t& counts, const Rings::Query& q) {
- if(q.qtype==type)
- counts[q.requestor]++;
- });
+ setLuaNoSideEffect();
+ return exceedQueryGen(rate, seconds, [type](counts_t& counts, const Rings::Query& q) {
+ if (q.qtype == type)
+ counts[q.requestor]++;
});
+ });
luaCtx.writeFunction("exceedQRate", [](unsigned int rate, int seconds) {
- setLuaNoSideEffect();
- return exceedQueryGen(rate, seconds, [](counts_t& counts, const Rings::Query& q) {
- counts[q.requestor]++;
- });
+ setLuaNoSideEffect();
+ return exceedQueryGen(rate, seconds, [](counts_t& counts, const Rings::Query& q) {
+ counts[q.requestor]++;
});
+ });
luaCtx.writeFunction("getRespRing", getRespRing);
/* StatNode */
- luaCtx.registerFunction<unsigned int(StatNode::*)()const>("numChildren",
- [](const StatNode& sn) -> unsigned int {
- return sn.children.size();
- } );
+ luaCtx.registerFunction<unsigned int (StatNode::*)() const>("numChildren",
+ [](const StatNode& sn) -> unsigned int {
+ return sn.children.size();
+ });
luaCtx.registerMember("fullname", &StatNode::fullname);
luaCtx.registerMember("labelsCount", &StatNode::labelsCount);
luaCtx.registerMember("servfails", &StatNode::Stat::servfails);
luaCtx.registerMember("hits", &StatNode::Stat::hits);
luaCtx.writeFunction("statNodeRespRing", [](statvisitor_t visitor, boost::optional<uint64_t> seconds) {
- statNodeRespRing(std::move(visitor), seconds ? *seconds : 0U);
- });
+ statNodeRespRing(std::move(visitor), seconds ? *seconds : 0U);
+ });
#endif /* DISABLE_DEPRECATED_DYNBLOCK */
/* DynBlockRulesGroup */
luaCtx.writeFunction("dynBlockRulesGroup", []() { return std::make_shared<DynBlockRulesGroup>(); });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(unsigned int, unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, boost::optional<unsigned int>)>("setQueryRate", [](std::shared_ptr<DynBlockRulesGroup>& group, unsigned int rate, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, boost::optional<unsigned int> warningRate) {
- if (group) {
- group->setQueryRate(rate, warningRate ? *warningRate : 0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None);
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(unsigned int, unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, boost::optional<unsigned int>)>("setResponseByteRate", [](std::shared_ptr<DynBlockRulesGroup>& group, unsigned int rate, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, boost::optional<unsigned int> warningRate) {
- if (group) {
- group->setResponseByteRate(rate, warningRate ? *warningRate : 0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None);
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, DynBlockRulesGroup::smtVisitor_t)>("setSuffixMatchRule", [](std::shared_ptr<DynBlockRulesGroup>& group, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, DynBlockRulesGroup::smtVisitor_t visitor) {
- if (group) {
- group->setSuffixMatchRule(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, std::move(visitor));
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, dnsdist_ffi_stat_node_visitor_t)>("setSuffixMatchRuleFFI", [](std::shared_ptr<DynBlockRulesGroup>& group, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, dnsdist_ffi_stat_node_visitor_t visitor) {
- if (group) {
- group->setSuffixMatchRuleFFI(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, std::move(visitor));
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(const dnsdist_ffi_dynamic_block_inserted_hook&)>("setNewBlockInsertedHook", [](std::shared_ptr<DynBlockRulesGroup>& group, const dnsdist_ffi_dynamic_block_inserted_hook& hook) {
- if (group) {
- group->setNewBlockHook(hook);
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(uint8_t, unsigned int, unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, boost::optional<unsigned int>)>("setRCodeRate", [](std::shared_ptr<DynBlockRulesGroup>& group, uint8_t rcode, unsigned int rate, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, boost::optional<unsigned int> warningRate) {
- if (group) {
- group->setRCodeRate(rcode, rate, warningRate ? *warningRate : 0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None);
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(uint8_t, double, unsigned int, const std::string&, unsigned int, size_t, boost::optional<DNSAction::Action>, boost::optional<double>)>("setRCodeRatio", [](std::shared_ptr<DynBlockRulesGroup>& group, uint8_t rcode, double ratio, unsigned int seconds, const std::string& reason, unsigned int blockDuration, size_t minimumNumberOfResponses, boost::optional<DNSAction::Action> action, boost::optional<double> warningRatio) {
- if (group) {
- group->setRCodeRatio(rcode, ratio, warningRatio ? *warningRatio : 0.0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, minimumNumberOfResponses);
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(uint16_t, unsigned int, unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, boost::optional<unsigned int>)>("setQTypeRate", [](std::shared_ptr<DynBlockRulesGroup>& group, uint16_t qtype, unsigned int rate, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, boost::optional<unsigned int> warningRate) {
- if (group) {
- group->setQTypeRate(qtype, rate, warningRate ? *warningRate : 0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None);
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(double, unsigned int, const std::string&, unsigned int, size_t, double, boost::optional<DNSAction::Action>, boost::optional<double>)>("setCacheMissRatio", [](std::shared_ptr<DynBlockRulesGroup>& group, double ratio, unsigned int seconds, const std::string& reason, unsigned int blockDuration, size_t minimumNumberOfResponses, double minimumGlobalCacheHitRatio, boost::optional<DNSAction::Action> action, boost::optional<double> warningRatio) {
- if (group) {
- group->setCacheMissRatio(ratio, warningRatio ? *warningRatio : 0.0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, minimumNumberOfResponses, minimumGlobalCacheHitRatio);
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(uint8_t, uint8_t, uint8_t)>("setMasks", [](std::shared_ptr<DynBlockRulesGroup>& group, uint8_t v4, uint8_t v6, uint8_t port) {
- if (group) {
- if (v4 > 32) {
- throw std::runtime_error("Trying to set an invalid IPv4 mask (" + std::to_string(v4) + ") to a Dynamic Block object");
- }
- if (v6 > 128) {
- throw std::runtime_error("Trying to set an invalid IPv6 mask (" + std::to_string(v6) + ") to a Dynamic Block object");
- }
- if (port > 16) {
- throw std::runtime_error("Trying to set an invalid port mask (" + std::to_string(port) + ") to a Dynamic Block object");
- }
- if (port > 0 && v4 != 32) {
- throw std::runtime_error("Setting a non-zero port mask for Dynamic Blocks while only considering parts of IPv4 addresses does not make sense");
- }
- group->setMasks(v4, v6, port);
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(boost::variant<std::string, LuaArray<std::string>, NetmaskGroup>)>("excludeRange", [](std::shared_ptr<DynBlockRulesGroup>& group, boost::variant<std::string, LuaArray<std::string>, NetmaskGroup> ranges) {
- if (ranges.type() == typeid(LuaArray<std::string>)) {
- for (const auto& range : *boost::get<LuaArray<std::string>>(&ranges)) {
- group->excludeRange(Netmask(range.second));
- }
- }
- else if (ranges.type() == typeid(NetmaskGroup)) {
- group->excludeRange(*boost::get<NetmaskGroup>(&ranges));
- }
- else {
- group->excludeRange(Netmask(*boost::get<std::string>(&ranges)));
- }
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(boost::variant<std::string, LuaArray<std::string>, NetmaskGroup>)>("includeRange", [](std::shared_ptr<DynBlockRulesGroup>& group, boost::variant<std::string, LuaArray<std::string>, NetmaskGroup> ranges) {
- if (ranges.type() == typeid(LuaArray<std::string>)) {
- for (const auto& range : *boost::get<LuaArray<std::string>>(&ranges)) {
- group->includeRange(Netmask(range.second));
- }
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(unsigned int, unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, boost::optional<unsigned int>)>("setQueryRate", [](std::shared_ptr<DynBlockRulesGroup>& group, unsigned int rate, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, boost::optional<unsigned int> warningRate) {
+ if (group) {
+ group->setQueryRate(rate, warningRate ? *warningRate : 0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None);
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(unsigned int, unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, boost::optional<unsigned int>)>("setResponseByteRate", [](std::shared_ptr<DynBlockRulesGroup>& group, unsigned int rate, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, boost::optional<unsigned int> warningRate) {
+ if (group) {
+ group->setResponseByteRate(rate, warningRate ? *warningRate : 0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None);
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, DynBlockRulesGroup::smtVisitor_t)>("setSuffixMatchRule", [](std::shared_ptr<DynBlockRulesGroup>& group, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, DynBlockRulesGroup::smtVisitor_t visitor) {
+ if (group) {
+ group->setSuffixMatchRule(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, std::move(visitor));
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, dnsdist_ffi_stat_node_visitor_t)>("setSuffixMatchRuleFFI", [](std::shared_ptr<DynBlockRulesGroup>& group, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, dnsdist_ffi_stat_node_visitor_t visitor) {
+ if (group) {
+ group->setSuffixMatchRuleFFI(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, std::move(visitor));
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(const dnsdist_ffi_dynamic_block_inserted_hook&)>("setNewBlockInsertedHook", [](std::shared_ptr<DynBlockRulesGroup>& group, const dnsdist_ffi_dynamic_block_inserted_hook& hook) {
+ if (group) {
+ group->setNewBlockHook(hook);
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(uint8_t, unsigned int, unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, boost::optional<unsigned int>)>("setRCodeRate", [](std::shared_ptr<DynBlockRulesGroup>& group, uint8_t rcode, unsigned int rate, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, boost::optional<unsigned int> warningRate) {
+ if (group) {
+ group->setRCodeRate(rcode, rate, warningRate ? *warningRate : 0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None);
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(uint8_t, double, unsigned int, const std::string&, unsigned int, size_t, boost::optional<DNSAction::Action>, boost::optional<double>)>("setRCodeRatio", [](std::shared_ptr<DynBlockRulesGroup>& group, uint8_t rcode, double ratio, unsigned int seconds, const std::string& reason, unsigned int blockDuration, size_t minimumNumberOfResponses, boost::optional<DNSAction::Action> action, boost::optional<double> warningRatio) {
+ if (group) {
+ group->setRCodeRatio(rcode, ratio, warningRatio ? *warningRatio : 0.0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, minimumNumberOfResponses);
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(uint16_t, unsigned int, unsigned int, const std::string&, unsigned int, boost::optional<DNSAction::Action>, boost::optional<unsigned int>)>("setQTypeRate", [](std::shared_ptr<DynBlockRulesGroup>& group, uint16_t qtype, unsigned int rate, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional<DNSAction::Action> action, boost::optional<unsigned int> warningRate) {
+ if (group) {
+ group->setQTypeRate(qtype, rate, warningRate ? *warningRate : 0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None);
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(double, unsigned int, const std::string&, unsigned int, size_t, double, boost::optional<DNSAction::Action>, boost::optional<double>)>("setCacheMissRatio", [](std::shared_ptr<DynBlockRulesGroup>& group, double ratio, unsigned int seconds, const std::string& reason, unsigned int blockDuration, size_t minimumNumberOfResponses, double minimumGlobalCacheHitRatio, boost::optional<DNSAction::Action> action, boost::optional<double> warningRatio) {
+ if (group) {
+ group->setCacheMissRatio(ratio, warningRatio ? *warningRatio : 0.0, seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, minimumNumberOfResponses, minimumGlobalCacheHitRatio);
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(uint8_t, uint8_t, uint8_t)>("setMasks", [](std::shared_ptr<DynBlockRulesGroup>& group, uint8_t v4, uint8_t v6, uint8_t port) {
+ if (group) {
+ if (v4 > 32) {
+ throw std::runtime_error("Trying to set an invalid IPv4 mask (" + std::to_string(v4) + ") to a Dynamic Block object");
}
- else if (ranges.type() == typeid(NetmaskGroup)) {
- group->includeRange(*boost::get<NetmaskGroup>(&ranges));
+ if (v6 > 128) {
+ throw std::runtime_error("Trying to set an invalid IPv6 mask (" + std::to_string(v6) + ") to a Dynamic Block object");
}
- else {
- group->includeRange(Netmask(*boost::get<std::string>(&ranges)));
+ if (port > 16) {
+ throw std::runtime_error("Trying to set an invalid port mask (" + std::to_string(port) + ") to a Dynamic Block object");
}
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(boost::variant<std::string, LuaArray<std::string>, NetmaskGroup>)>("removeRange", [](std::shared_ptr<DynBlockRulesGroup>& group, boost::variant<std::string, LuaArray<std::string>, NetmaskGroup> ranges) {
- if (ranges.type() == typeid(LuaArray<std::string>)) {
- for (const auto& range : *boost::get<LuaArray<std::string>>(&ranges)) {
- group->removeRange(Netmask(range.second));
- }
+ if (port > 0 && v4 != 32) {
+ throw std::runtime_error("Setting a non-zero port mask for Dynamic Blocks while only considering parts of IPv4 addresses does not make sense");
}
- else if (ranges.type() == typeid(NetmaskGroup)) {
- group->removeRange(*boost::get<NetmaskGroup>(&ranges));
+ group->setMasks(v4, v6, port);
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(boost::variant<std::string, LuaArray<std::string>, NetmaskGroup>)>("excludeRange", [](std::shared_ptr<DynBlockRulesGroup>& group, boost::variant<std::string, LuaArray<std::string>, NetmaskGroup> ranges) {
+ if (ranges.type() == typeid(LuaArray<std::string>)) {
+ for (const auto& range : *boost::get<LuaArray<std::string>>(&ranges)) {
+ group->excludeRange(Netmask(range.second));
}
- else {
- group->removeRange(Netmask(*boost::get<std::string>(&ranges)));
+ }
+ else if (ranges.type() == typeid(NetmaskGroup)) {
+ group->excludeRange(*boost::get<NetmaskGroup>(&ranges));
+ }
+ else {
+ group->excludeRange(Netmask(*boost::get<std::string>(&ranges)));
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(boost::variant<std::string, LuaArray<std::string>, NetmaskGroup>)>("includeRange", [](std::shared_ptr<DynBlockRulesGroup>& group, boost::variant<std::string, LuaArray<std::string>, NetmaskGroup> ranges) {
+ if (ranges.type() == typeid(LuaArray<std::string>)) {
+ for (const auto& range : *boost::get<LuaArray<std::string>>(&ranges)) {
+ group->includeRange(Netmask(range.second));
}
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)(LuaTypeOrArrayOf<std::string>)>("excludeDomains", [](std::shared_ptr<DynBlockRulesGroup>& group, LuaTypeOrArrayOf<std::string> domains) {
- if (domains.type() == typeid(LuaArray<std::string>)) {
- for (const auto& range : *boost::get<LuaArray<std::string>>(&domains)) {
- group->excludeDomain(DNSName(range.second));
- }
+ }
+ else if (ranges.type() == typeid(NetmaskGroup)) {
+ group->includeRange(*boost::get<NetmaskGroup>(&ranges));
+ }
+ else {
+ group->includeRange(Netmask(*boost::get<std::string>(&ranges)));
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(boost::variant<std::string, LuaArray<std::string>, NetmaskGroup>)>("removeRange", [](std::shared_ptr<DynBlockRulesGroup>& group, boost::variant<std::string, LuaArray<std::string>, NetmaskGroup> ranges) {
+ if (ranges.type() == typeid(LuaArray<std::string>)) {
+ for (const auto& range : *boost::get<LuaArray<std::string>>(&ranges)) {
+ group->removeRange(Netmask(range.second));
}
- else {
- group->excludeDomain(DNSName(*boost::get<std::string>(&domains)));
+ }
+ else if (ranges.type() == typeid(NetmaskGroup)) {
+ group->removeRange(*boost::get<NetmaskGroup>(&ranges));
+ }
+ else {
+ group->removeRange(Netmask(*boost::get<std::string>(&ranges)));
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)(LuaTypeOrArrayOf<std::string>)>("excludeDomains", [](std::shared_ptr<DynBlockRulesGroup>& group, LuaTypeOrArrayOf<std::string> domains) {
+ if (domains.type() == typeid(LuaArray<std::string>)) {
+ for (const auto& range : *boost::get<LuaArray<std::string>>(&domains)) {
+ group->excludeDomain(DNSName(range.second));
}
- });
- luaCtx.registerFunction<void(std::shared_ptr<DynBlockRulesGroup>::*)()>("apply", [](std::shared_ptr<DynBlockRulesGroup>& group) {
+ }
+ else {
+ group->excludeDomain(DNSName(*boost::get<std::string>(&domains)));
+ }
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<DynBlockRulesGroup>::*)()>("apply", [](std::shared_ptr<DynBlockRulesGroup>& group) {
group->apply();
});
luaCtx.registerFunction("setQuiet", &DynBlockRulesGroup::setQuiet);
luaCtx.registerMember("reason", &DynBlock::reason);
luaCtx.registerMember("domain", &DynBlock::domain);
luaCtx.registerMember("until", &DynBlock::until);
- luaCtx.registerMember<DynBlock, unsigned int>("blocks", [](const DynBlock& block) { return block.blocks.load(); }, [](DynBlock& block, [[maybe_unused]] unsigned int blocks) { });
+ luaCtx.registerMember<DynBlock, unsigned int>(
+ "blocks", [](const DynBlock& block) { return block.blocks.load(); }, [](DynBlock& block, [[maybe_unused]] unsigned int blocks) {});
luaCtx.registerMember("action", &DynBlock::action);
luaCtx.registerMember("warning", &DynBlock::warning);
luaCtx.registerMember("bpf", &DynBlock::bpf);
auto add = [&nmg, &smn, &suffixSeen](const string& src) {
try {
nmg.addMask(src); // need to try mask first, all masks are domain names!
- } catch (...) {
+ }
+ catch (...) {
suffixSeen = true;
smn.add(DNSName(src));
}
creationOrder = s_creationOrder++;
}
-typedef LuaAssociativeTable<boost::variant<bool, int, std::string, LuaArray<int> > > ruleparams_t;
+typedef LuaAssociativeTable<boost::variant<bool, int, std::string, LuaArray<int>>> ruleparams_t;
-template<typename T>
+template <typename T>
static std::string rulesToString(const std::vector<T>& rules, boost::optional<ruleparams_t>& vars)
{
int num = 0;
if (showUUIDs) {
boost::format fmt("%-3d %-30s %-38s %9d %9d %-56s %s\n");
result += (fmt % "#" % "Name" % "UUID" % "Cr. Order" % "Matches" % "Rule" % "Action").str();
- for(const auto& lim : rules) {
+ for (const auto& lim : rules) {
string desc = lim.d_rule->toString().substr(0, truncateRuleWidth);
result += (fmt % num % lim.d_name % boost::uuids::to_string(lim.d_id) % lim.d_creationOrder % lim.d_rule->d_matches % desc % lim.d_action->toString()).str();
++num;
else {
boost::format fmt("%-3d %-30s %9d %-56s %s\n");
result += (fmt % "#" % "Name" % "Matches" % "Rule" % "Action").str();
- for(const auto& lim : rules) {
+ for (const auto& lim : rules) {
string desc = lim.d_rule->toString().substr(0, truncateRuleWidth);
- result += (fmt % num % lim.d_name % lim.d_rule->d_matches % desc % lim.d_action->toString()).str();
+ result += (fmt % num % lim.d_name % lim.d_rule->d_matches % desc % lim.d_action->toString()).str();
++num;
}
}
return result;
}
-template<typename T>
-static void showRules(GlobalStateHolder<vector<T> > *someRuleActions, boost::optional<ruleparams_t>& vars) {
+template <typename T>
+static void showRules(GlobalStateHolder<vector<T>>* someRuleActions, boost::optional<ruleparams_t>& vars)
+{
setLuaNoSideEffect();
auto rules = someRuleActions->getLocal();
g_outputBuffer += rulesToString(*rules, vars);
}
-template<typename T>
-static void rmRule(GlobalStateHolder<vector<T> > *someRuleActions, const boost::variant<unsigned int, std::string>& id) {
+template <typename T>
+static void rmRule(GlobalStateHolder<vector<T>>* someRuleActions, const boost::variant<unsigned int, std::string>& id)
+{
setLuaSideEffect();
auto rules = someRuleActions->getCopy();
if (auto str = boost::get<std::string>(&id)) {
g_outputBuffer = "Error: attempt to delete non-existing rule\n";
return;
}
- rules.erase(rules.begin()+*pos);
+ rules.erase(rules.begin() + *pos);
}
someRuleActions->setState(std::move(rules));
}
-template<typename T>
-static void moveRuleToTop(GlobalStateHolder<vector<T> > *someRuleActions) {
+template <typename T>
+static void moveRuleToTop(GlobalStateHolder<vector<T>>* someRuleActions)
+{
setLuaSideEffect();
auto rules = someRuleActions->getCopy();
- if(rules.empty())
+ if (rules.empty())
return;
auto subject = *rules.rbegin();
rules.erase(std::prev(rules.end()));
someRuleActions->setState(std::move(rules));
}
-template<typename T>
-static void mvRule(GlobalStateHolder<vector<T> > *someRespRuleActions, unsigned int from, unsigned int to) {
+template <typename T>
+static void mvRule(GlobalStateHolder<vector<T>>* someRespRuleActions, unsigned int from, unsigned int to)
+{
setLuaSideEffect();
auto rules = someRespRuleActions->getCopy();
- if(from >= rules.size() || to > rules.size()) {
+ if (from >= rules.size() || to > rules.size()) {
g_outputBuffer = "Error: attempt to move rules from/to invalid index\n";
return;
}
auto subject = rules[from];
- rules.erase(rules.begin()+from);
- if(to > rules.size())
+ rules.erase(rules.begin() + from);
+ if (to > rules.size())
rules.push_back(subject);
else {
- if(from < to)
+ if (from < to)
--to;
- rules.insert(rules.begin()+to, subject);
+ rules.insert(rules.begin() + to, subject);
}
someRespRuleActions->setState(std::move(rules));
}
-template<typename T>
+template <typename T>
static std::vector<T> getTopRules(const std::vector<T>& rules, unsigned int top)
{
std::vector<std::pair<size_t, size_t>> counts;
pos++;
}
- sort(counts.begin(), counts.end(), [](const decltype(counts)::value_type& a,
- const decltype(counts)::value_type& b) {
+ sort(counts.begin(), counts.end(), [](const decltype(counts)::value_type& a, const decltype(counts)::value_type& b) {
return b.first < a.first;
});
return results;
}
-template<typename T>
+template <typename T>
static LuaArray<T> toLuaArray(std::vector<T>&& rules)
{
LuaArray<T> results;
return makeRule(var, "makeRule");
});
- luaCtx.registerFunction<string(std::shared_ptr<DNSRule>::*)()const>("toString", [](const std::shared_ptr<DNSRule>& rule) { return rule->toString(); });
+ luaCtx.registerFunction<string (std::shared_ptr<DNSRule>::*)() const>("toString", [](const std::shared_ptr<DNSRule>& rule) { return rule->toString(); });
- luaCtx.registerFunction<uint64_t(std::shared_ptr<DNSRule>::*)()const>("getMatches", [](const std::shared_ptr<DNSRule>& rule) { return rule->d_matches.load(); });
+ luaCtx.registerFunction<uint64_t (std::shared_ptr<DNSRule>::*)() const>("getMatches", [](const std::shared_ptr<DNSRule>& rule) { return rule->d_matches.load(); });
- luaCtx.registerFunction<std::shared_ptr<DNSRule>(DNSDistRuleAction::*)()const>("getSelector", [](const DNSDistRuleAction& rule) { return rule.d_rule; });
+ luaCtx.registerFunction<std::shared_ptr<DNSRule> (DNSDistRuleAction::*)() const>("getSelector", [](const DNSDistRuleAction& rule) { return rule.d_rule; });
- luaCtx.registerFunction<std::shared_ptr<DNSAction>(DNSDistRuleAction::*)()const>("getAction", [](const DNSDistRuleAction& rule) { return rule.d_action; });
+ luaCtx.registerFunction<std::shared_ptr<DNSAction> (DNSDistRuleAction::*)() const>("getAction", [](const DNSDistRuleAction& rule) { return rule.d_action; });
- luaCtx.registerFunction<std::shared_ptr<DNSRule>(DNSDistResponseRuleAction::*)()const>("getSelector", [](const DNSDistResponseRuleAction& rule) { return rule.d_rule; });
+ luaCtx.registerFunction<std::shared_ptr<DNSRule> (DNSDistResponseRuleAction::*)() const>("getSelector", [](const DNSDistResponseRuleAction& rule) { return rule.d_rule; });
- luaCtx.registerFunction<std::shared_ptr<DNSResponseAction>(DNSDistResponseRuleAction::*)()const>("getAction", [](const DNSDistResponseRuleAction& rule) { return rule.d_action; });
+ luaCtx.registerFunction<std::shared_ptr<DNSResponseAction> (DNSDistResponseRuleAction::*)() const>("getAction", [](const DNSDistResponseRuleAction& rule) { return rule.d_action; });
luaCtx.writeFunction("showResponseRules", [](boost::optional<ruleparams_t> vars) {
- showRules(&g_respruleactions, vars);
- });
+ showRules(&g_respruleactions, vars);
+ });
luaCtx.writeFunction("rmResponseRule", [](boost::variant<unsigned int, std::string> id) {
- rmRule(&g_respruleactions, id);
- });
+ rmRule(&g_respruleactions, id);
+ });
luaCtx.writeFunction("mvResponseRuleToTop", []() {
- moveRuleToTop(&g_respruleactions);
- });
+ moveRuleToTop(&g_respruleactions);
+ });
luaCtx.writeFunction("mvResponseRule", [](unsigned int from, unsigned int to) {
- mvRule(&g_respruleactions, from, to);
- });
+ mvRule(&g_respruleactions, from, to);
+ });
luaCtx.writeFunction("showCacheHitResponseRules", [](boost::optional<ruleparams_t> vars) {
- showRules(&g_cachehitrespruleactions, vars);
- });
+ showRules(&g_cachehitrespruleactions, vars);
+ });
luaCtx.writeFunction("rmCacheHitResponseRule", [](boost::variant<unsigned int, std::string> id) {
- rmRule(&g_cachehitrespruleactions, id);
- });
+ rmRule(&g_cachehitrespruleactions, id);
+ });
luaCtx.writeFunction("mvCacheHitResponseRuleToTop", []() {
- moveRuleToTop(&g_cachehitrespruleactions);
- });
+ moveRuleToTop(&g_cachehitrespruleactions);
+ });
luaCtx.writeFunction("mvCacheHitResponseRule", [](unsigned int from, unsigned int to) {
- mvRule(&g_cachehitrespruleactions, from, to);
- });
+ mvRule(&g_cachehitrespruleactions, from, to);
+ });
luaCtx.writeFunction("showCacheInsertedResponseRules", [](boost::optional<ruleparams_t> vars) {
showRules(&g_cacheInsertedRespRuleActions, vars);
});
luaCtx.writeFunction("showSelfAnsweredResponseRules", [](boost::optional<ruleparams_t> vars) {
- showRules(&g_selfansweredrespruleactions, vars);
- });
+ showRules(&g_selfansweredrespruleactions, vars);
+ });
luaCtx.writeFunction("rmSelfAnsweredResponseRule", [](boost::variant<unsigned int, std::string> id) {
- rmRule(&g_selfansweredrespruleactions, id);
- });
+ rmRule(&g_selfansweredrespruleactions, id);
+ });
luaCtx.writeFunction("mvSelfAnsweredResponseRuleToTop", []() {
- moveRuleToTop(&g_selfansweredrespruleactions);
- });
+ moveRuleToTop(&g_selfansweredrespruleactions);
+ });
luaCtx.writeFunction("mvSelfAnsweredResponseRule", [](unsigned int from, unsigned int to) {
- mvRule(&g_selfansweredrespruleactions, from, to);
- });
+ mvRule(&g_selfansweredrespruleactions, from, to);
+ });
luaCtx.writeFunction("rmRule", [](boost::variant<unsigned int, std::string> id) {
- rmRule(&g_ruleactions, id);
- });
+ rmRule(&g_ruleactions, id);
+ });
luaCtx.writeFunction("mvRuleToTop", []() {
- moveRuleToTop(&g_ruleactions);
- });
+ moveRuleToTop(&g_ruleactions);
+ });
luaCtx.writeFunction("mvRule", [](unsigned int from, unsigned int to) {
- mvRule(&g_ruleactions, from, to);
- });
+ mvRule(&g_ruleactions, from, to);
+ });
luaCtx.writeFunction("clearRules", []() {
- setLuaSideEffect();
- g_ruleactions.modify([](decltype(g_ruleactions)::value_type& ruleactions) {
- ruleactions.clear();
- });
+ setLuaSideEffect();
+ g_ruleactions.modify([](decltype(g_ruleactions)::value_type& ruleactions) {
+ ruleactions.clear();
});
+ });
luaCtx.writeFunction("setRules", [](const LuaArray<std::shared_ptr<DNSDistRuleAction>>& newruleactions) {
- setLuaSideEffect();
- g_ruleactions.modify([newruleactions](decltype(g_ruleactions)::value_type& gruleactions) {
- gruleactions.clear();
- for (const auto& pair : newruleactions) {
- const auto& newruleaction = pair.second;
- if (newruleaction->d_action) {
- auto rule = newruleaction->d_rule;
- gruleactions.push_back({std::move(rule), newruleaction->d_action, newruleaction->d_name, newruleaction->d_id, newruleaction->d_creationOrder});
- }
- }
- });
+ setLuaSideEffect();
+ g_ruleactions.modify([newruleactions](decltype(g_ruleactions)::value_type& gruleactions) {
+ gruleactions.clear();
+ for (const auto& pair : newruleactions) {
+ const auto& newruleaction = pair.second;
+ if (newruleaction->d_action) {
+ auto rule = newruleaction->d_rule;
+ gruleactions.push_back({std::move(rule), newruleaction->d_action, newruleaction->d_name, newruleaction->d_id, newruleaction->d_creationOrder});
+ }
+ }
});
+ });
luaCtx.writeFunction("getRule", [](boost::variant<int, std::string> selector) -> boost::optional<DNSDistRuleAction> {
auto rules = g_ruleactions.getLocal();
luaCtx.writeFunction("MaxQPSIPRule", [](unsigned int qps, boost::optional<unsigned int> ipv4trunc, boost::optional<unsigned int> ipv6trunc, boost::optional<unsigned int> burst, boost::optional<unsigned int> expiration, boost::optional<unsigned int> cleanupDelay, boost::optional<unsigned int> scanFraction, boost::optional<unsigned int> shards) {
return std::shared_ptr<DNSRule>(new MaxQPSIPRule(qps, (burst ? *burst : qps), (ipv4trunc ? *ipv4trunc : 32), (ipv6trunc ? *ipv6trunc : 64), (expiration ? *expiration : 300), (cleanupDelay ? *cleanupDelay : 60), (scanFraction ? *scanFraction : 10), (shards ? *shards : 10)));
- });
+ });
luaCtx.writeFunction("MaxQPSRule", [](unsigned int qps, boost::optional<unsigned int> burst) {
- if(!burst)
- return std::shared_ptr<DNSRule>(new MaxQPSRule(qps));
- else
- return std::shared_ptr<DNSRule>(new MaxQPSRule(qps, *burst));
- });
+ if (!burst)
+ return std::shared_ptr<DNSRule>(new MaxQPSRule(qps));
+ else
+ return std::shared_ptr<DNSRule>(new MaxQPSRule(qps, *burst));
+ });
luaCtx.writeFunction("RegexRule", [](const std::string& str) {
- return std::shared_ptr<DNSRule>(new RegexRule(str));
- });
+ return std::shared_ptr<DNSRule>(new RegexRule(str));
+ });
#ifdef HAVE_DNS_OVER_HTTPS
luaCtx.writeFunction("HTTPHeaderRule", [](const std::string& header, const std::string& regex) {
- return std::shared_ptr<DNSRule>(new HTTPHeaderRule(header, regex));
- });
+ return std::shared_ptr<DNSRule>(new HTTPHeaderRule(header, regex));
+ });
luaCtx.writeFunction("HTTPPathRule", [](const std::string& path) {
- return std::shared_ptr<DNSRule>(new HTTPPathRule(path));
- });
+ return std::shared_ptr<DNSRule>(new HTTPPathRule(path));
+ });
luaCtx.writeFunction("HTTPPathRegexRule", [](const std::string& regex) {
- return std::shared_ptr<DNSRule>(new HTTPPathRegexRule(regex));
- });
+ return std::shared_ptr<DNSRule>(new HTTPPathRegexRule(regex));
+ });
#endif
#ifdef HAVE_RE2
luaCtx.writeFunction("RE2Rule", [](const std::string& str) {
- return std::shared_ptr<DNSRule>(new RE2Rule(str));
- });
+ return std::shared_ptr<DNSRule>(new RE2Rule(str));
+ });
#endif
luaCtx.writeFunction("SNIRule", [](const std::string& name) {
- return std::shared_ptr<DNSRule>(new SNIRule(name));
+ return std::shared_ptr<DNSRule>(new SNIRule(name));
});
luaCtx.writeFunction("SuffixMatchNodeRule", qnameSuffixRule);
return std::shared_ptr<DNSRule>(new NetmaskGroupRule(nmg, src ? *src : true, quiet ? *quiet : false));
});
- luaCtx.writeFunction("benchRule", [](std::shared_ptr<DNSRule> rule, boost::optional<unsigned int> times_, boost::optional<string> suffix_) {
- setLuaNoSideEffect();
- unsigned int times = times_ ? *times_ : 100000;
- DNSName suffix(suffix_ ? *suffix_ : "powerdns.com");
- struct item {
- PacketBuffer packet;
- InternalQueryState ids;
- };
- vector<item> items;
- items.reserve(1000);
- for (int n = 0; n < 1000; ++n) {
- struct item i;
- i.ids.qname = DNSName(std::to_string(dns_random_uint32()));
- i.ids.qname += suffix;
- i.ids.qtype = dns_random(0xff);
- i.ids.qclass = QClass::IN;
- i.ids.protocol = dnsdist::Protocol::DoUDP;
- i.ids.origRemote = ComboAddress("127.0.0.1");
- i.ids.origRemote.sin4.sin_addr.s_addr = random();
- i.ids.queryRealTime.start();
- GenericDNSPacketWriter<PacketBuffer> pw(i.packet, i.ids.qname, i.ids.qtype);
- items.push_back(std::move(i));
- }
+ luaCtx.writeFunction("benchRule", [](std::shared_ptr<DNSRule> rule, boost::optional<unsigned int> times_, boost::optional<string> suffix_) {
+ setLuaNoSideEffect();
+ unsigned int times = times_ ? *times_ : 100000;
+ DNSName suffix(suffix_ ? *suffix_ : "powerdns.com");
+ struct item
+ {
+ PacketBuffer packet;
+ InternalQueryState ids;
+ };
+ vector<item> items;
+ items.reserve(1000);
+ for (int n = 0; n < 1000; ++n) {
+ struct item i;
+ i.ids.qname = DNSName(std::to_string(dns_random_uint32()));
+ i.ids.qname += suffix;
+ i.ids.qtype = dns_random(0xff);
+ i.ids.qclass = QClass::IN;
+ i.ids.protocol = dnsdist::Protocol::DoUDP;
+ i.ids.origRemote = ComboAddress("127.0.0.1");
+ i.ids.origRemote.sin4.sin_addr.s_addr = random();
+ i.ids.queryRealTime.start();
+ GenericDNSPacketWriter<PacketBuffer> pw(i.packet, i.ids.qname, i.ids.qtype);
+ items.push_back(std::move(i));
+ }
- int matches = 0;
- ComboAddress dummy("127.0.0.1");
- StopWatch sw;
- sw.start();
- for (unsigned int n = 0; n < times; ++n) {
- item& i = items[n % items.size()];
- DNSQuestion dq(i.ids, i.packet);
+ int matches = 0;
+ ComboAddress dummy("127.0.0.1");
+ StopWatch sw;
+ sw.start();
+ for (unsigned int n = 0; n < times; ++n) {
+ item& i = items[n % items.size()];
+ DNSQuestion dq(i.ids, i.packet);
- if (rule->matches(&dq)) {
- matches++;
- }
+ if (rule->matches(&dq)) {
+ matches++;
}
- double udiff = sw.udiff();
- g_outputBuffer=(boost::format("Had %d matches out of %d, %.1f qps, in %.1f us\n") % matches % times % (1000000*(1.0*times/udiff)) % udiff).str();
-
- });
+ }
+ double udiff = sw.udiff();
+ g_outputBuffer = (boost::format("Had %d matches out of %d, %.1f qps, in %.1f us\n") % matches % times % (1000000 * (1.0 * times / udiff)) % udiff).str();
+ });
luaCtx.writeFunction("AllRule", []() {
- return std::shared_ptr<DNSRule>(new AllRule());
- });
+ return std::shared_ptr<DNSRule>(new AllRule());
+ });
luaCtx.writeFunction("ProbaRule", [](double proba) {
- return std::shared_ptr<DNSRule>(new ProbaRule(proba));
- });
+ return std::shared_ptr<DNSRule>(new ProbaRule(proba));
+ });
luaCtx.writeFunction("QNameRule", [](const std::string& qname) {
- return std::shared_ptr<DNSRule>(new QNameRule(DNSName(qname)));
- });
+ return std::shared_ptr<DNSRule>(new QNameRule(DNSName(qname)));
+ });
luaCtx.writeFunction("QNameSuffixRule", qnameSuffixRule);
luaCtx.writeFunction("QTypeRule", [](boost::variant<unsigned int, std::string> str) {
- uint16_t qtype;
- if (auto dir = boost::get<unsigned int>(&str)) {
- qtype = *dir;
- }
- else {
- string val = boost::get<string>(str);
- qtype = QType::chartocode(val.c_str());
- if (!qtype) {
- throw std::runtime_error("Unable to convert '"+val+"' to a DNS type");
- }
+ uint16_t qtype;
+ if (auto dir = boost::get<unsigned int>(&str)) {
+ qtype = *dir;
+ }
+ else {
+ string val = boost::get<string>(str);
+ qtype = QType::chartocode(val.c_str());
+ if (!qtype) {
+ throw std::runtime_error("Unable to convert '" + val + "' to a DNS type");
}
- return std::shared_ptr<DNSRule>(new QTypeRule(qtype));
- });
+ }
+ return std::shared_ptr<DNSRule>(new QTypeRule(qtype));
+ });
luaCtx.writeFunction("QClassRule", [](uint64_t c) {
- checkParameterBound("QClassRule", c, std::numeric_limits<uint16_t>::max());
- return std::shared_ptr<DNSRule>(new QClassRule(c));
- });
+ checkParameterBound("QClassRule", c, std::numeric_limits<uint16_t>::max());
+ return std::shared_ptr<DNSRule>(new QClassRule(c));
+ });
luaCtx.writeFunction("OpcodeRule", [](uint64_t code) {
- checkParameterBound("OpcodeRule", code, std::numeric_limits<uint8_t>::max());
- return std::shared_ptr<DNSRule>(new OpcodeRule(code));
- });
+ checkParameterBound("OpcodeRule", code, std::numeric_limits<uint8_t>::max());
+ return std::shared_ptr<DNSRule>(new OpcodeRule(code));
+ });
luaCtx.writeFunction("AndRule", [](const LuaArray<std::shared_ptr<DNSRule>>& a) {
- return std::shared_ptr<DNSRule>(new AndRule(a));
- });
+ return std::shared_ptr<DNSRule>(new AndRule(a));
+ });
luaCtx.writeFunction("OrRule", [](const LuaArray<std::shared_ptr<DNSRule>>& a) {
- return std::shared_ptr<DNSRule>(new OrRule(a));
- });
+ return std::shared_ptr<DNSRule>(new OrRule(a));
+ });
luaCtx.writeFunction("DSTPortRule", [](uint64_t port) {
- checkParameterBound("DSTPortRule", port, std::numeric_limits<uint16_t>::max());
- return std::shared_ptr<DNSRule>(new DSTPortRule(port));
- });
+ checkParameterBound("DSTPortRule", port, std::numeric_limits<uint16_t>::max());
+ return std::shared_ptr<DNSRule>(new DSTPortRule(port));
+ });
luaCtx.writeFunction("TCPRule", [](bool tcp) {
- return std::shared_ptr<DNSRule>(new TCPRule(tcp));
- });
+ return std::shared_ptr<DNSRule>(new TCPRule(tcp));
+ });
luaCtx.writeFunction("DNSSECRule", []() {
- return std::shared_ptr<DNSRule>(new DNSSECRule());
- });
+ return std::shared_ptr<DNSRule>(new DNSSECRule());
+ });
luaCtx.writeFunction("NotRule", [](const std::shared_ptr<DNSRule>& rule) {
- return std::shared_ptr<DNSRule>(new NotRule(rule));
- });
+ return std::shared_ptr<DNSRule>(new NotRule(rule));
+ });
luaCtx.writeFunction("RecordsCountRule", [](uint64_t section, uint64_t minCount, uint64_t maxCount) {
- checkParameterBound("RecordsCountRule", section, std::numeric_limits<uint8_t>::max());
- checkParameterBound("RecordsCountRule", minCount, std::numeric_limits<uint16_t>::max());
- checkParameterBound("RecordsCountRule", maxCount, std::numeric_limits<uint16_t>::max());
- return std::shared_ptr<DNSRule>(new RecordsCountRule(section, minCount, maxCount));
- });
+ checkParameterBound("RecordsCountRule", section, std::numeric_limits<uint8_t>::max());
+ checkParameterBound("RecordsCountRule", minCount, std::numeric_limits<uint16_t>::max());
+ checkParameterBound("RecordsCountRule", maxCount, std::numeric_limits<uint16_t>::max());
+ return std::shared_ptr<DNSRule>(new RecordsCountRule(section, minCount, maxCount));
+ });
luaCtx.writeFunction("RecordsTypeCountRule", [](uint64_t section, uint64_t type, uint64_t minCount, uint64_t maxCount) {
- checkParameterBound("RecordsTypeCountRule", section, std::numeric_limits<uint8_t>::max());
- checkParameterBound("RecordsTypeCountRule", type, std::numeric_limits<uint16_t>::max());
- checkParameterBound("RecordsTypeCountRule", minCount, std::numeric_limits<uint16_t>::max());
- checkParameterBound("RecordsTypeCountRule", maxCount, std::numeric_limits<uint16_t>::max());
- return std::shared_ptr<DNSRule>(new RecordsTypeCountRule(section, type, minCount, maxCount));
- });
+ checkParameterBound("RecordsTypeCountRule", section, std::numeric_limits<uint8_t>::max());
+ checkParameterBound("RecordsTypeCountRule", type, std::numeric_limits<uint16_t>::max());
+ checkParameterBound("RecordsTypeCountRule", minCount, std::numeric_limits<uint16_t>::max());
+ checkParameterBound("RecordsTypeCountRule", maxCount, std::numeric_limits<uint16_t>::max());
+ return std::shared_ptr<DNSRule>(new RecordsTypeCountRule(section, type, minCount, maxCount));
+ });
luaCtx.writeFunction("TrailingDataRule", []() {
- return std::shared_ptr<DNSRule>(new TrailingDataRule());
- });
+ return std::shared_ptr<DNSRule>(new TrailingDataRule());
+ });
luaCtx.writeFunction("QNameLabelsCountRule", [](uint64_t minLabelsCount, uint64_t maxLabelsCount) {
- checkParameterBound("QNameLabelsCountRule", minLabelsCount, std::numeric_limits<unsigned int>::max());
- checkParameterBound("QNameLabelsCountRule", maxLabelsCount, std::numeric_limits<unsigned int>::max());
- return std::shared_ptr<DNSRule>(new QNameLabelsCountRule(minLabelsCount, maxLabelsCount));
- });
+ checkParameterBound("QNameLabelsCountRule", minLabelsCount, std::numeric_limits<unsigned int>::max());
+ checkParameterBound("QNameLabelsCountRule", maxLabelsCount, std::numeric_limits<unsigned int>::max());
+ return std::shared_ptr<DNSRule>(new QNameLabelsCountRule(minLabelsCount, maxLabelsCount));
+ });
luaCtx.writeFunction("QNameWireLengthRule", [](uint64_t min, uint64_t max) {
- return std::shared_ptr<DNSRule>(new QNameWireLengthRule(min, max));
- });
+ return std::shared_ptr<DNSRule>(new QNameWireLengthRule(min, max));
+ });
luaCtx.writeFunction("RCodeRule", [](uint64_t rcode) {
- checkParameterBound("RCodeRule", rcode, std::numeric_limits<uint8_t>::max());
- return std::shared_ptr<DNSRule>(new RCodeRule(rcode));
- });
+ checkParameterBound("RCodeRule", rcode, std::numeric_limits<uint8_t>::max());
+ return std::shared_ptr<DNSRule>(new RCodeRule(rcode));
+ });
luaCtx.writeFunction("ERCodeRule", [](uint64_t rcode) {
- checkParameterBound("ERCodeRule", rcode, std::numeric_limits<uint8_t>::max());
- return std::shared_ptr<DNSRule>(new ERCodeRule(rcode));
- });
+ checkParameterBound("ERCodeRule", rcode, std::numeric_limits<uint8_t>::max());
+ return std::shared_ptr<DNSRule>(new ERCodeRule(rcode));
+ });
luaCtx.writeFunction("EDNSVersionRule", [](uint64_t version) {
- checkParameterBound("EDNSVersionRule", version, std::numeric_limits<uint8_t>::max());
- return std::shared_ptr<DNSRule>(new EDNSVersionRule(version));
- });
+ checkParameterBound("EDNSVersionRule", version, std::numeric_limits<uint8_t>::max());
+ return std::shared_ptr<DNSRule>(new EDNSVersionRule(version));
+ });
luaCtx.writeFunction("EDNSOptionRule", [](uint64_t optcode) {
- checkParameterBound("EDNSOptionRule", optcode, std::numeric_limits<uint16_t>::max());
- return std::shared_ptr<DNSRule>(new EDNSOptionRule(optcode));
- });
+ checkParameterBound("EDNSOptionRule", optcode, std::numeric_limits<uint16_t>::max());
+ return std::shared_ptr<DNSRule>(new EDNSOptionRule(optcode));
+ });
luaCtx.writeFunction("showRules", [](boost::optional<ruleparams_t> vars) {
- showRules(&g_ruleactions, vars);
- });
+ showRules(&g_ruleactions, vars);
+ });
luaCtx.writeFunction("RDRule", []() {
- return std::shared_ptr<DNSRule>(new RDRule());
- });
+ return std::shared_ptr<DNSRule>(new RDRule());
+ });
luaCtx.writeFunction("TagRule", [](const std::string& tag, boost::optional<std::string> value) {
- return std::shared_ptr<DNSRule>(new TagRule(tag, std::move(value)));
- });
+ return std::shared_ptr<DNSRule>(new TagRule(tag, std::move(value)));
+ });
luaCtx.writeFunction("TimedIPSetRule", []() {
- return std::shared_ptr<TimedIPSetRule>(new TimedIPSetRule());
- });
+ return std::shared_ptr<TimedIPSetRule>(new TimedIPSetRule());
+ });
luaCtx.writeFunction("PoolAvailableRule", [](const std::string& poolname) {
return std::shared_ptr<DNSRule>(new PoolAvailableRule(poolname));
return std::shared_ptr<DNSRule>(new PoolOutstandingRule(poolname, limit));
});
- luaCtx.registerFunction<void(std::shared_ptr<TimedIPSetRule>::*)()>("clear", [](std::shared_ptr<TimedIPSetRule> tisr) {
- tisr->clear();
- });
+ luaCtx.registerFunction<void (std::shared_ptr<TimedIPSetRule>::*)()>("clear", [](std::shared_ptr<TimedIPSetRule> tisr) {
+ tisr->clear();
+ });
- luaCtx.registerFunction<void(std::shared_ptr<TimedIPSetRule>::*)()>("cleanup", [](std::shared_ptr<TimedIPSetRule> tisr) {
- tisr->cleanup();
- });
+ luaCtx.registerFunction<void (std::shared_ptr<TimedIPSetRule>::*)()>("cleanup", [](std::shared_ptr<TimedIPSetRule> tisr) {
+ tisr->cleanup();
+ });
- luaCtx.registerFunction<void(std::shared_ptr<TimedIPSetRule>::*)(const ComboAddress& ca, int t)>("add", [](std::shared_ptr<TimedIPSetRule> tisr, const ComboAddress& ca, int t) {
- tisr->add(ca, time(0)+t);
- });
+ luaCtx.registerFunction<void (std::shared_ptr<TimedIPSetRule>::*)(const ComboAddress& ca, int t)>("add", [](std::shared_ptr<TimedIPSetRule> tisr, const ComboAddress& ca, int t) {
+ tisr->add(ca, time(0) + t);
+ });
- luaCtx.registerFunction<std::shared_ptr<DNSRule>(std::shared_ptr<TimedIPSetRule>::*)()>("slice", [](std::shared_ptr<TimedIPSetRule> tisr) {
- return std::dynamic_pointer_cast<DNSRule>(tisr);
- });
- luaCtx.registerFunction<void(std::shared_ptr<TimedIPSetRule>::*)()>("__tostring", [](std::shared_ptr<TimedIPSetRule> tisr) {
- tisr->toString();
- });
+ luaCtx.registerFunction<std::shared_ptr<DNSRule> (std::shared_ptr<TimedIPSetRule>::*)()>("slice", [](std::shared_ptr<TimedIPSetRule> tisr) {
+ return std::dynamic_pointer_cast<DNSRule>(tisr);
+ });
+ luaCtx.registerFunction<void (std::shared_ptr<TimedIPSetRule>::*)()>("__tostring", [](std::shared_ptr<TimedIPSetRule> tisr) {
+ tisr->toString();
+ });
luaCtx.writeFunction("QNameSetRule", [](const DNSNameSet& names) {
- return std::shared_ptr<DNSRule>(new QNameSetRule(names));
- });
+ return std::shared_ptr<DNSRule>(new QNameSetRule(names));
+ });
#if defined(HAVE_LMDB) || defined(HAVE_CDB)
luaCtx.writeFunction("KeyValueStoreLookupRule", [](std::shared_ptr<KeyValueStore>& kvs, std::shared_ptr<KeyValueLookupKey>& lookupKey) {
- return std::shared_ptr<DNSRule>(new KeyValueStoreLookupRule(kvs, lookupKey));
- });
+ return std::shared_ptr<DNSRule>(new KeyValueStoreLookupRule(kvs, lookupKey));
+ });
luaCtx.writeFunction("KeyValueStoreRangeLookupRule", [](std::shared_ptr<KeyValueStore>& kvs, std::shared_ptr<KeyValueLookupKey>& lookupKey) {
- return std::shared_ptr<DNSRule>(new KeyValueStoreRangeLookupRule(kvs, lookupKey));
- });
+ return std::shared_ptr<DNSRule>(new KeyValueStoreRangeLookupRule(kvs, lookupKey));
+ });
#endif /* defined(HAVE_LMDB) || defined(HAVE_CDB) */
luaCtx.writeFunction("LuaRule", [](LuaRule::func_t func) {
- return std::shared_ptr<DNSRule>(new LuaRule(func));
- });
+ return std::shared_ptr<DNSRule>(new LuaRule(func));
+ });
luaCtx.writeFunction("LuaFFIRule", [](LuaFFIRule::func_t func) {
- return std::shared_ptr<DNSRule>(new LuaFFIRule(func));
- });
+ return std::shared_ptr<DNSRule>(new LuaFFIRule(func));
+ });
luaCtx.writeFunction("LuaFFIPerThreadRule", [](const std::string& code) {
- return std::shared_ptr<DNSRule>(new LuaFFIPerThreadRule(code));
- });
+ return std::shared_ptr<DNSRule>(new LuaFFIPerThreadRule(code));
+ });
luaCtx.writeFunction("ProxyProtocolValueRule", [](uint8_t type, boost::optional<std::string> value) {
- return std::shared_ptr<DNSRule>(new ProxyProtocolValueRule(type, std::move(value)));
- });
+ return std::shared_ptr<DNSRule>(new ProxyProtocolValueRule(type, std::move(value)));
+ });
luaCtx.writeFunction("PayloadSizeRule", [](const std::string& comparison, uint16_t size) {
return std::shared_ptr<DNSRule>(new PayloadSizeRule(comparison, size));
- });
+ });
}
#include "dnsdist-lua.hh"
#include "ednsoptions.hh"
-#undef BADSIG // signal.h SIG_ERR
+#undef BADSIG // signal.h SIG_ERR
void setupLuaVars(LuaContext& luaCtx)
{
- luaCtx.writeVariable("DNSAction", LuaAssociativeTable<int>{
- {"Drop", (int)DNSAction::Action::Drop},
- {"Nxdomain", (int)DNSAction::Action::Nxdomain},
- {"Refused", (int)DNSAction::Action::Refused},
- {"Spoof", (int)DNSAction::Action::Spoof},
- {"SpoofPacket", (int)DNSAction::Action::SpoofPacket},
- {"SpoofRaw", (int)DNSAction::Action::SpoofRaw},
- {"Allow", (int)DNSAction::Action::Allow},
- {"HeaderModify", (int)DNSAction::Action::HeaderModify},
- {"Pool", (int)DNSAction::Action::Pool},
- {"None",(int)DNSAction::Action::None},
- {"NoOp",(int)DNSAction::Action::NoOp},
- {"Delay", (int)DNSAction::Action::Delay},
- {"Truncate", (int)DNSAction::Action::Truncate},
- {"ServFail", (int)DNSAction::Action::ServFail},
- {"NoRecurse", (int)DNSAction::Action::NoRecurse}
- });
+ luaCtx.writeVariable("DNSAction", LuaAssociativeTable<int>{{"Drop", (int)DNSAction::Action::Drop}, {"Nxdomain", (int)DNSAction::Action::Nxdomain}, {"Refused", (int)DNSAction::Action::Refused}, {"Spoof", (int)DNSAction::Action::Spoof}, {"SpoofPacket", (int)DNSAction::Action::SpoofPacket}, {"SpoofRaw", (int)DNSAction::Action::SpoofRaw}, {"Allow", (int)DNSAction::Action::Allow}, {"HeaderModify", (int)DNSAction::Action::HeaderModify}, {"Pool", (int)DNSAction::Action::Pool}, {"None", (int)DNSAction::Action::None}, {"NoOp", (int)DNSAction::Action::NoOp}, {"Delay", (int)DNSAction::Action::Delay}, {"Truncate", (int)DNSAction::Action::Truncate}, {"ServFail", (int)DNSAction::Action::ServFail}, {"NoRecurse", (int)DNSAction::Action::NoRecurse}});
- luaCtx.writeVariable("DNSResponseAction", LuaAssociativeTable<int>{
- {"Allow", (int)DNSResponseAction::Action::Allow },
- {"Delay", (int)DNSResponseAction::Action::Delay },
- {"Drop", (int)DNSResponseAction::Action::Drop },
- {"HeaderModify", (int)DNSResponseAction::Action::HeaderModify },
- {"ServFail", (int)DNSResponseAction::Action::ServFail },
- {"Truncate", (int)DNSResponseAction::Action::Truncate },
- {"None", (int)DNSResponseAction::Action::None }
- });
+ luaCtx.writeVariable("DNSResponseAction", LuaAssociativeTable<int>{{"Allow", (int)DNSResponseAction::Action::Allow}, {"Delay", (int)DNSResponseAction::Action::Delay}, {"Drop", (int)DNSResponseAction::Action::Drop}, {"HeaderModify", (int)DNSResponseAction::Action::HeaderModify}, {"ServFail", (int)DNSResponseAction::Action::ServFail}, {"Truncate", (int)DNSResponseAction::Action::Truncate}, {"None", (int)DNSResponseAction::Action::None}});
- luaCtx.writeVariable("DNSClass", LuaAssociativeTable<int>{
- {"IN", QClass::IN },
- {"CHAOS", QClass::CHAOS },
- {"NONE", QClass::NONE },
- {"ANY", QClass::ANY }
- });
+ luaCtx.writeVariable("DNSClass", LuaAssociativeTable<int>{{"IN", QClass::IN}, {"CHAOS", QClass::CHAOS}, {"NONE", QClass::NONE}, {"ANY", QClass::ANY}});
- luaCtx.writeVariable("DNSOpcode", LuaAssociativeTable<int>{
- {"Query", Opcode::Query },
- {"IQuery", Opcode::IQuery },
- {"Status", Opcode::Status },
- {"Notify", Opcode::Notify },
- {"Update", Opcode::Update }
- });
+ luaCtx.writeVariable("DNSOpcode", LuaAssociativeTable<int>{{"Query", Opcode::Query}, {"IQuery", Opcode::IQuery}, {"Status", Opcode::Status}, {"Notify", Opcode::Notify}, {"Update", Opcode::Update}});
- luaCtx.writeVariable("DNSSection", LuaAssociativeTable<int>{
- {"Question", 0 },
- {"Answer", 1 },
- {"Authority", 2 },
- {"Additional",3 }
- });
+ luaCtx.writeVariable("DNSSection", LuaAssociativeTable<int>{{"Question", 0}, {"Answer", 1}, {"Authority", 2}, {"Additional", 3}});
- luaCtx.writeVariable("EDNSOptionCode", LuaAssociativeTable<int>{
- {"NSID", EDNSOptionCode::NSID },
- {"DAU", EDNSOptionCode::DAU },
- {"DHU", EDNSOptionCode::DHU },
- {"N3U", EDNSOptionCode::N3U },
- {"ECS", EDNSOptionCode::ECS },
- {"EXPIRE", EDNSOptionCode::EXPIRE },
- {"COOKIE", EDNSOptionCode::COOKIE },
- {"TCPKEEPALIVE", EDNSOptionCode::TCPKEEPALIVE },
- {"PADDING", EDNSOptionCode::PADDING },
- {"CHAIN", EDNSOptionCode::CHAIN },
- {"KEYTAG", EDNSOptionCode::KEYTAG }
- });
+ luaCtx.writeVariable("EDNSOptionCode", LuaAssociativeTable<int>{{"NSID", EDNSOptionCode::NSID}, {"DAU", EDNSOptionCode::DAU}, {"DHU", EDNSOptionCode::DHU}, {"N3U", EDNSOptionCode::N3U}, {"ECS", EDNSOptionCode::ECS}, {"EXPIRE", EDNSOptionCode::EXPIRE}, {"COOKIE", EDNSOptionCode::COOKIE}, {"TCPKEEPALIVE", EDNSOptionCode::TCPKEEPALIVE}, {"PADDING", EDNSOptionCode::PADDING}, {"CHAIN", EDNSOptionCode::CHAIN}, {"KEYTAG", EDNSOptionCode::KEYTAG}});
- luaCtx.writeVariable("DNSRCode", LuaAssociativeTable<int>{
- {"NOERROR", RCode::NoError },
- {"FORMERR", RCode::FormErr },
- {"SERVFAIL", RCode::ServFail },
- {"NXDOMAIN", RCode::NXDomain },
- {"NOTIMP", RCode::NotImp },
- {"REFUSED", RCode::Refused },
- {"YXDOMAIN", RCode::YXDomain },
- {"YXRRSET", RCode::YXRRSet },
- {"NXRRSET", RCode::NXRRSet },
- {"NOTAUTH", RCode::NotAuth },
- {"NOTZONE", RCode::NotZone },
- {"BADVERS", ERCode::BADVERS },
- {"BADSIG", ERCode::BADSIG },
- {"BADKEY", ERCode::BADKEY },
- {"BADTIME", ERCode::BADTIME },
- {"BADMODE", ERCode::BADMODE },
- {"BADNAME", ERCode::BADNAME },
- {"BADALG", ERCode::BADALG },
- {"BADTRUNC", ERCode::BADTRUNC },
- {"BADCOOKIE",ERCode::BADCOOKIE }
- });
+ luaCtx.writeVariable("DNSRCode", LuaAssociativeTable<int>{{"NOERROR", RCode::NoError}, {"FORMERR", RCode::FormErr}, {"SERVFAIL", RCode::ServFail}, {"NXDOMAIN", RCode::NXDomain}, {"NOTIMP", RCode::NotImp}, {"REFUSED", RCode::Refused}, {"YXDOMAIN", RCode::YXDomain}, {"YXRRSET", RCode::YXRRSet}, {"NXRRSET", RCode::NXRRSet}, {"NOTAUTH", RCode::NotAuth}, {"NOTZONE", RCode::NotZone}, {"BADVERS", ERCode::BADVERS}, {"BADSIG", ERCode::BADSIG}, {"BADKEY", ERCode::BADKEY}, {"BADTIME", ERCode::BADTIME}, {"BADMODE", ERCode::BADMODE}, {"BADNAME", ERCode::BADNAME}, {"BADALG", ERCode::BADALG}, {"BADTRUNC", ERCode::BADTRUNC}, {"BADCOOKIE", ERCode::BADCOOKIE}});
LuaAssociativeTable<int> dd;
for (const auto& n : QType::names) {
luaCtx.writeVariable("DNSQType", dd);
#ifdef HAVE_DNSCRYPT
- luaCtx.writeVariable("DNSCryptExchangeVersion", LuaAssociativeTable<int>{
- { "VERSION1", DNSCryptExchangeVersion::VERSION1 },
- { "VERSION2", DNSCryptExchangeVersion::VERSION2 },
- });
+ luaCtx.writeVariable("DNSCryptExchangeVersion", LuaAssociativeTable<int>{
+ {"VERSION1", DNSCryptExchangeVersion::VERSION1},
+ {"VERSION2", DNSCryptExchangeVersion::VERSION2},
+ });
#endif
}
class SpoofAction : public DNSAction
{
public:
- SpoofAction(const vector<ComboAddress>& addrs): d_addrs(addrs)
+ SpoofAction(const vector<ComboAddress>& addrs) :
+ d_addrs(addrs)
{
for (const auto& addr : d_addrs) {
if (addr.isIPv4()) {
}
}
- SpoofAction(const DNSName& cname): d_cname(cname)
+ SpoofAction(const DNSName& cname) :
+ d_cname(cname)
{
}
- SpoofAction(const char* rawresponse, size_t len): d_raw(rawresponse, rawresponse + len)
+ SpoofAction(const char* rawresponse, size_t len) :
+ d_raw(rawresponse, rawresponse + len)
{
}
- SpoofAction(const vector<std::string>& raws, std::optional<uint16_t> typeForAny): d_rawResponses(raws), d_rawTypeForAny(typeForAny)
+ SpoofAction(const vector<std::string>& raws, std::optional<uint16_t> typeForAny) :
+ d_rawResponses(raws), d_rawTypeForAny(typeForAny)
{
}
ret += "raw bytes ";
}
else {
- for(const auto& a : d_addrs)
- ret += a.toString()+" ";
+ for (const auto& a : d_addrs)
+ ret += a.toString() + " ";
}
return ret;
}
public:
LimitTTLResponseAction() {}
- LimitTTLResponseAction(uint32_t min, uint32_t max = std::numeric_limits<uint32_t>::max(), const std::unordered_set<QType>& types = {}) : d_types(types), d_min(min), d_max(max)
+ LimitTTLResponseAction(uint32_t min, uint32_t max = std::numeric_limits<uint32_t>::max(), const std::unordered_set<QType>& types = {}) :
+ d_types(types), d_min(min), d_max(max)
{
}
}
return ttl;
};
- editDNSPacketTTL(reinterpret_cast<char *>(dr->getMutableData().data()), dr->getData().size(), visitor);
+ editDNSPacketTTL(reinterpret_cast<char*>(dr->getMutableData().data()), dr->getData().size(), visitor);
return DNSResponseAction::Action::None;
}
}
result += "]";
}
- result += + ")";
+ result += +")";
return result;
}
uint32_t d_max{std::numeric_limits<uint32_t>::max()};
};
-template <class T> using LuaArray = std::vector<std::pair<int, T>>;
-template <class T> using LuaAssociativeTable = std::unordered_map<std::string, T>;
-template <class T> using LuaTypeOrArrayOf = boost::variant<T, LuaArray<T>>;
+template <class T>
+using LuaArray = std::vector<std::pair<int, T>>;
+template <class T>
+using LuaAssociativeTable = std::unordered_map<std::string, T>;
+template <class T>
+using LuaTypeOrArrayOf = boost::variant<T, LuaArray<T>>;
using luaruleparams_t = LuaAssociativeTable<std::string>;
using nmts_t = NetmaskTree<DynBlock, AddressAndPortRange>;
*
* returns: -1 if type wasn't compatible, 0 if not found or number of element(s) found
*/
-template<class G, class T, class V>
-static inline int getOptionalValue(boost::optional<V>& vars, const std::string& key, T& value, bool warnOnWrongType = true) {
+template <class G, class T, class V>
+static inline int getOptionalValue(boost::optional<V>& vars, const std::string& key, T& value, bool warnOnWrongType = true)
+{
/* nothing found, nothing to return */
if (!vars) {
return 0;
if (vars->count(key)) {
try {
value = boost::get<G>((*vars)[key]);
- } catch (const boost::bad_get& e) {
+ }
+ catch (const boost::bad_get& e) {
/* key is there but isn't compatible */
if (warnOnWrongType) {
warnlog("Invalid type for key '%s' - ignored", key);
return vars->erase(key);
}
-template<class T, class V>
-static inline int getOptionalIntegerValue(const std::string& func, boost::optional<V>& vars, const std::string& key, T& value) {
+template <class T, class V>
+static inline int getOptionalIntegerValue(const std::string& func, boost::optional<V>& vars, const std::string& key, T& value)
+{
std::string valueStr;
auto ret = getOptionalValue<std::string>(vars, key, valueStr, true);
if (ret == 1) {
return ret;
}
-template<class V>
-static inline void checkAllParametersConsumed(const std::string& func, const boost::optional<V>& vars) {
+template <class V>
+static inline void checkAllParametersConsumed(const std::string& func, const boost::optional<V>& vars)
+{
/* no vars */
if (!vars) {
return;
{
if (d_numberOfShards <= 1) {
d_nbLockTries = 0;
- } else {
+ }
+ else {
d_nbLockTries = retries;
}
}
return s.size();
}
-std::unordered_map<int, vector<boost::variant<string,double>>> Rings::getTopBandwidth(unsigned int numentries)
+std::unordered_map<int, vector<boost::variant<string, double>>> Rings::getTopBandwidth(unsigned int numentries)
{
map<ComboAddress, unsigned int, ComboAddress::addressOnlyLessThan> counts;
- uint64_t total=0;
+ uint64_t total = 0;
for (const auto& shard : d_shards) {
{
auto rl = shard->queryRing.lock();
- for(const auto& q : *rl) {
+ for (const auto& q : *rl) {
counts[q.requestor] += q.size;
- total+=q.size;
+ total += q.size;
}
}
{
auto rl = shard->respRing.lock();
- for(const auto& r : *rl) {
+ for (const auto& r : *rl) {
counts[r.requestor] += r.size;
- total+=r.size;
+ total += r.size;
}
}
}
typedef vector<pair<unsigned int, ComboAddress>> ret_t;
ret_t rcounts;
rcounts.reserve(counts.size());
- for(const auto& p : counts)
+ for (const auto& p : counts)
rcounts.push_back({p.second, p.first});
numentries = rcounts.size() < numentries ? rcounts.size() : numentries;
- partial_sort(rcounts.begin(), rcounts.begin()+numentries, rcounts.end(), [](const ret_t::value_type&a, const ret_t::value_type&b)
- {
- return(b.first < a.first);
- });
- std::unordered_map<int, vector<boost::variant<string,double>>> ret;
+ partial_sort(rcounts.begin(), rcounts.begin() + numentries, rcounts.end(), [](const ret_t::value_type& a, const ret_t::value_type& b) {
+ return (b.first < a.first);
+ });
+ std::unordered_map<int, vector<boost::variant<string, double>>> ret;
uint64_t rest = 0;
int count = 1;
- for(const auto& rc : rcounts) {
+ for (const auto& rc : rcounts) {
if (count == static_cast<int>(numentries + 1)) {
- rest+=rc.first;
+ rest += rc.first;
}
else {
- ret.insert({count++, {rc.second.toString(), rc.first, 100.0*rc.first/total}});
+ ret.insert({count++, {rc.second.toString(), rc.first, 100.0 * rc.first / total}});
}
}
if (total > 0) {
- ret.insert({count, {"Rest", rest, 100.0*rest/total}});
+ ret.insert({count, {"Rest", rest, 100.0 * rest / total}});
}
else {
- ret.insert({count, {"Rest", rest, 100.0 }});
+ ret.insert({count, {"Rest", rest, 100.0}});
}
return ret;
isResponse = true;
}
else {
- cerr<<"skipping line with "<<parts.size()<<"parts: "<<line<<endl;
+ cerr << "skipping line with " << parts.size() << "parts: " << line << endl;
continue;
}
vector<string> timeStr;
stringtok(timeStr, parts.at(idx++), ".");
if (timeStr.size() != 2) {
- cerr<<"skipping invalid time "<<parts.at(0)<<endl;
+ cerr << "skipping invalid time " << parts.at(0) << endl;
continue;
}
when.tv_nsec = now.tv_nsec + std::stoi(timeStr.at(1)) * 100 * 1000 * 1000;
}
catch (const std::exception& e) {
- cerr<<"error parsing time "<<parts.at(idx-1)<<" from line "<<line<<endl;
+ cerr << "error parsing time " << parts.at(idx - 1) << " from line " << line << endl;
continue;
}
#include "dnsdist-protocols.hh"
#include "dnsdist-mac-address.hh"
-struct Rings {
+struct Rings
+{
struct Query
{
ComboAddress requestor;
LockGuarded<boost::circular_buffer<Response>> respRing;
};
- Rings(size_t capacity=10000, size_t numberOfShards=10, size_t nbLockTries=5, bool keepLockingStats=false): d_blockingQueryInserts(0), d_blockingResponseInserts(0), d_deferredQueryInserts(0), d_deferredResponseInserts(0), d_nbQueryEntries(0), d_nbResponseEntries(0), d_currentShardId(0), d_capacity(capacity), d_numberOfShards(numberOfShards), d_nbLockTries(nbLockTries), d_keepLockingStats(keepLockingStats)
+ Rings(size_t capacity = 10000, size_t numberOfShards = 10, size_t nbLockTries = 5, bool keepLockingStats = false) :
+ d_blockingQueryInserts(0), d_blockingResponseInserts(0), d_deferredQueryInserts(0), d_deferredResponseInserts(0), d_nbQueryEntries(0), d_nbResponseEntries(0), d_currentShardId(0), d_capacity(capacity), d_numberOfShards(numberOfShards), d_nbLockTries(nbLockTries), d_keepLockingStats(keepLockingStats)
{
}
- std::unordered_map<int, vector<boost::variant<string,double> > > getTopBandwidth(unsigned int numentries);
+ std::unordered_map<int, vector<boost::variant<string, double>>> getTopBandwidth(unsigned int numentries);
size_t numDistinctRequestors();
/* this function should not be called after init() has been called */
void setCapacity(size_t newCapacity, size_t numberOfShards);
return d_recordResponses;
}
- std::vector<std::unique_ptr<Shard> > d_shards;
+ std::vector<std::unique_ptr<Shard>> d_shards;
pdns::stat_t d_blockingQueryInserts;
pdns::stat_t d_blockingResponseInserts;
pdns::stat_t d_deferredQueryInserts;
#define DNSDIST_TRAPS_OID DNSDIST_OID, 10, 0
#define DNSDIST_TRAP_OBJECTS_OID DNSDIST_OID, 11
-static const oid queriesOID[] = { DNSDIST_STATS_OID, 1 };
-static const oid responsesOID[] = { DNSDIST_STATS_OID, 2 };
-static const oid servfailResponsesOID[] = { DNSDIST_STATS_OID, 3 };
-static const oid aclDropsOID[] = { DNSDIST_STATS_OID, 4 };
+static const oid queriesOID[] = {DNSDIST_STATS_OID, 1};
+static const oid responsesOID[] = {DNSDIST_STATS_OID, 2};
+static const oid servfailResponsesOID[] = {DNSDIST_STATS_OID, 3};
+static const oid aclDropsOID[] = {DNSDIST_STATS_OID, 4};
// 5 was BlockFilter, removed in 1.2.0
-static const oid ruleDropOID[] = { DNSDIST_STATS_OID, 6 };
-static const oid ruleNXDomainOID[] = { DNSDIST_STATS_OID, 7 };
-static const oid ruleRefusedOID[] = { DNSDIST_STATS_OID, 8 };
-static const oid selfAnsweredOID[] = { DNSDIST_STATS_OID, 9 };
-static const oid downstreamTimeoutsOID[] = { DNSDIST_STATS_OID, 10 };
-static const oid downstreamSendErrorsOID[] = { DNSDIST_STATS_OID, 11 };
-static const oid truncFailOID[] = { DNSDIST_STATS_OID, 12 };
-static const oid noPolicyOID[] = { DNSDIST_STATS_OID, 13 };
-static const oid latency0_1OID[] = { DNSDIST_STATS_OID, 14 };
-static const oid latency1_10OID[] = { DNSDIST_STATS_OID, 15 };
-static const oid latency10_50OID[] = { DNSDIST_STATS_OID, 16 };
-static const oid latency50_100OID[] = { DNSDIST_STATS_OID, 17 };
-static const oid latency100_1000OID[] = { DNSDIST_STATS_OID, 18 };
-static const oid latencySlowOID[] = { DNSDIST_STATS_OID, 19 };
-static const oid latencyAvg100OID[] = { DNSDIST_STATS_OID, 20 };
-static const oid latencyAvg1000OID[] = { DNSDIST_STATS_OID, 21 };
-static const oid latencyAvg10000OID[] = { DNSDIST_STATS_OID, 22 };
-static const oid latencyAvg1000000OID[] = { DNSDIST_STATS_OID, 23 };
-static const oid uptimeOID[] = { DNSDIST_STATS_OID, 24 };
-static const oid realMemoryUsageOID[] = { DNSDIST_STATS_OID, 25 };
-static const oid nonCompliantQueriesOID[] = { DNSDIST_STATS_OID, 26 };
-static const oid nonCompliantResponsesOID[] = { DNSDIST_STATS_OID, 27 };
-static const oid rdQueriesOID[] = { DNSDIST_STATS_OID, 28 };
-static const oid emptyQueriesOID[] = { DNSDIST_STATS_OID, 29 };
-static const oid cacheHitsOID[] = { DNSDIST_STATS_OID, 30 };
-static const oid cacheMissesOID[] = { DNSDIST_STATS_OID, 31 };
-static const oid cpuUserMSecOID[] = { DNSDIST_STATS_OID, 32 };
-static const oid cpuSysMSecOID[] = { DNSDIST_STATS_OID, 33 };
-static const oid fdUsageOID[] = { DNSDIST_STATS_OID, 34 };
-static const oid dynBlockedOID[] = { DNSDIST_STATS_OID, 35 };
-static const oid dynBlockedNMGSizeOID[] = { DNSDIST_STATS_OID, 36 };
-static const oid ruleServFailOID[] = { DNSDIST_STATS_OID, 37 };
-static const oid securityStatusOID[] = { DNSDIST_STATS_OID, 38 };
-static const oid specialMemoryUsageOID[] = { DNSDIST_STATS_OID, 39 };
-static const oid ruleTruncatedOID[] = { DNSDIST_STATS_OID, 40 };
+static const oid ruleDropOID[] = {DNSDIST_STATS_OID, 6};
+static const oid ruleNXDomainOID[] = {DNSDIST_STATS_OID, 7};
+static const oid ruleRefusedOID[] = {DNSDIST_STATS_OID, 8};
+static const oid selfAnsweredOID[] = {DNSDIST_STATS_OID, 9};
+static const oid downstreamTimeoutsOID[] = {DNSDIST_STATS_OID, 10};
+static const oid downstreamSendErrorsOID[] = {DNSDIST_STATS_OID, 11};
+static const oid truncFailOID[] = {DNSDIST_STATS_OID, 12};
+static const oid noPolicyOID[] = {DNSDIST_STATS_OID, 13};
+static const oid latency0_1OID[] = {DNSDIST_STATS_OID, 14};
+static const oid latency1_10OID[] = {DNSDIST_STATS_OID, 15};
+static const oid latency10_50OID[] = {DNSDIST_STATS_OID, 16};
+static const oid latency50_100OID[] = {DNSDIST_STATS_OID, 17};
+static const oid latency100_1000OID[] = {DNSDIST_STATS_OID, 18};
+static const oid latencySlowOID[] = {DNSDIST_STATS_OID, 19};
+static const oid latencyAvg100OID[] = {DNSDIST_STATS_OID, 20};
+static const oid latencyAvg1000OID[] = {DNSDIST_STATS_OID, 21};
+static const oid latencyAvg10000OID[] = {DNSDIST_STATS_OID, 22};
+static const oid latencyAvg1000000OID[] = {DNSDIST_STATS_OID, 23};
+static const oid uptimeOID[] = {DNSDIST_STATS_OID, 24};
+static const oid realMemoryUsageOID[] = {DNSDIST_STATS_OID, 25};
+static const oid nonCompliantQueriesOID[] = {DNSDIST_STATS_OID, 26};
+static const oid nonCompliantResponsesOID[] = {DNSDIST_STATS_OID, 27};
+static const oid rdQueriesOID[] = {DNSDIST_STATS_OID, 28};
+static const oid emptyQueriesOID[] = {DNSDIST_STATS_OID, 29};
+static const oid cacheHitsOID[] = {DNSDIST_STATS_OID, 30};
+static const oid cacheMissesOID[] = {DNSDIST_STATS_OID, 31};
+static const oid cpuUserMSecOID[] = {DNSDIST_STATS_OID, 32};
+static const oid cpuSysMSecOID[] = {DNSDIST_STATS_OID, 33};
+static const oid fdUsageOID[] = {DNSDIST_STATS_OID, 34};
+static const oid dynBlockedOID[] = {DNSDIST_STATS_OID, 35};
+static const oid dynBlockedNMGSizeOID[] = {DNSDIST_STATS_OID, 36};
+static const oid ruleServFailOID[] = {DNSDIST_STATS_OID, 37};
+static const oid securityStatusOID[] = {DNSDIST_STATS_OID, 38};
+static const oid specialMemoryUsageOID[] = {DNSDIST_STATS_OID, 39};
+static const oid ruleTruncatedOID[] = {DNSDIST_STATS_OID, 40};
static std::unordered_map<oid, dnsdist::metrics::Stats::entry_t> s_statsMap;
}
/* column number definitions for table backendStatTable */
-#define COLUMN_BACKENDID 1
-#define COLUMN_BACKENDNAME 2
-#define COLUMN_BACKENDLATENCY 3
-#define COLUMN_BACKENDWEIGHT 4
-#define COLUMN_BACKENDOUTSTANDING 5
-#define COLUMN_BACKENDQPSLIMIT 6
-#define COLUMN_BACKENDREUSED 7
-#define COLUMN_BACKENDSTATE 8
-#define COLUMN_BACKENDADDRESS 9
-#define COLUMN_BACKENDPOOLS 10
-#define COLUMN_BACKENDQPS 11
-#define COLUMN_BACKENDQUERIES 12
-#define COLUMN_BACKENDORDER 13
-
-static const oid backendStatTableOID[] = { DNSDIST_STATS_TABLE_OID };
-static const oid backendNameOID[] = { DNSDIST_STATS_TABLE_OID, 1, 2 };
-static const oid backendStateOID[] = { DNSDIST_STATS_TABLE_OID, 1, 8};
-static const oid backendAddressOID[] = { DNSDIST_STATS_TABLE_OID, 1, 9};
-
-static const oid socketFamilyOID[] = { DNSDIST_TRAP_OBJECTS_OID, 1, 0 };
-static const oid socketProtocolOID[] = { DNSDIST_TRAP_OBJECTS_OID, 2, 0 };
-static const oid fromAddressOID[] = { DNSDIST_TRAP_OBJECTS_OID, 3, 0 };
-static const oid toAddressOID[] = { DNSDIST_TRAP_OBJECTS_OID, 4, 0 };
-static const oid queryTypeOID[] = { DNSDIST_TRAP_OBJECTS_OID, 5, 0 };
-static const oid querySizeOID[] = { DNSDIST_TRAP_OBJECTS_OID, 6, 0 };
-static const oid queryIDOID[] = { DNSDIST_TRAP_OBJECTS_OID, 7, 0 };
-static const oid qNameOID[] = { DNSDIST_TRAP_OBJECTS_OID, 8, 0 };
-static const oid qClassOID[] = { DNSDIST_TRAP_OBJECTS_OID, 9, 0 };
-static const oid qTypeOID[] = { DNSDIST_TRAP_OBJECTS_OID, 10, 0 };
-static const oid trapReasonOID[] = { DNSDIST_TRAP_OBJECTS_OID, 11, 0 };
-
-static const oid backendStatusChangeTrapOID[] = { DNSDIST_TRAPS_OID, 1 };
-static const oid actionTrapOID[] = { DNSDIST_TRAPS_OID, 2 };
-static const oid customTrapOID[] = { DNSDIST_TRAPS_OID, 3 };
+#define COLUMN_BACKENDID 1
+#define COLUMN_BACKENDNAME 2
+#define COLUMN_BACKENDLATENCY 3
+#define COLUMN_BACKENDWEIGHT 4
+#define COLUMN_BACKENDOUTSTANDING 5
+#define COLUMN_BACKENDQPSLIMIT 6
+#define COLUMN_BACKENDREUSED 7
+#define COLUMN_BACKENDSTATE 8
+#define COLUMN_BACKENDADDRESS 9
+#define COLUMN_BACKENDPOOLS 10
+#define COLUMN_BACKENDQPS 11
+#define COLUMN_BACKENDQUERIES 12
+#define COLUMN_BACKENDORDER 13
+
+static const oid backendStatTableOID[] = {DNSDIST_STATS_TABLE_OID};
+static const oid backendNameOID[] = {DNSDIST_STATS_TABLE_OID, 1, 2};
+static const oid backendStateOID[] = {DNSDIST_STATS_TABLE_OID, 1, 8};
+static const oid backendAddressOID[] = {DNSDIST_STATS_TABLE_OID, 1, 9};
+
+static const oid socketFamilyOID[] = {DNSDIST_TRAP_OBJECTS_OID, 1, 0};
+static const oid socketProtocolOID[] = {DNSDIST_TRAP_OBJECTS_OID, 2, 0};
+static const oid fromAddressOID[] = {DNSDIST_TRAP_OBJECTS_OID, 3, 0};
+static const oid toAddressOID[] = {DNSDIST_TRAP_OBJECTS_OID, 4, 0};
+static const oid queryTypeOID[] = {DNSDIST_TRAP_OBJECTS_OID, 5, 0};
+static const oid querySizeOID[] = {DNSDIST_TRAP_OBJECTS_OID, 6, 0};
+static const oid queryIDOID[] = {DNSDIST_TRAP_OBJECTS_OID, 7, 0};
+static const oid qNameOID[] = {DNSDIST_TRAP_OBJECTS_OID, 8, 0};
+static const oid qClassOID[] = {DNSDIST_TRAP_OBJECTS_OID, 9, 0};
+static const oid qTypeOID[] = {DNSDIST_TRAP_OBJECTS_OID, 10, 0};
+static const oid trapReasonOID[] = {DNSDIST_TRAP_OBJECTS_OID, 11, 0};
+
+static const oid backendStatusChangeTrapOID[] = {DNSDIST_TRAPS_OID, 1};
+static const oid actionTrapOID[] = {DNSDIST_TRAPS_OID, 2};
+static const oid customTrapOID[] = {DNSDIST_TRAPS_OID, 3};
static servers_t s_servers;
static size_t s_currentServerIdx = 0;
return NULL;
}
- *my_data_context = (void*) (s_servers[s_currentServerIdx]).get();
+ *my_data_context = (void*)(s_servers[s_currentServerIdx]).get();
snmp_set_var_typed_integer(put_index_data, ASN_UNSIGNED, s_currentServerIdx);
s_currentServerIdx++;
case MODE_GET:
for (request = requests; request; request = request->next) {
netsnmp_table_request_info* table_info = netsnmp_extract_table_info(request);
- const DownstreamState* server = (const DownstreamState*) netsnmp_extract_iterator_context(request);
+ const DownstreamState* server = (const DownstreamState*)netsnmp_extract_iterator_context(request);
if (!server) {
continue;
case COLUMN_BACKENDREUSED:
DNSDistSNMPAgent::setCounter64Value(request, server->reuseds.load());
break;
- case COLUMN_BACKENDSTATE:
- {
+ case COLUMN_BACKENDSTATE: {
std::string state(server->getStatus());
snmp_set_var_typed_value(request->requestvb,
ASN_OCTET_STR,
state.size());
break;
}
- case COLUMN_BACKENDADDRESS:
- {
+ case COLUMN_BACKENDADDRESS: {
std::string addr(server->d_config.remote.toStringWithPort());
snmp_set_var_typed_value(request->requestvb,
ASN_OCTET_STR,
addr.size());
break;
}
- case COLUMN_BACKENDPOOLS:
- {
+ case COLUMN_BACKENDPOOLS: {
std::string pools;
for (const auto& p : server->d_config.pools) {
if (!pools.empty()) {
- pools+=" ";
+ pools += " ";
}
pools += p;
}
snmpTrapOID.size(),
ASN_OBJECT_ID,
backendStatusChangeTrapOID,
- OID_LENGTH(backendStatusChangeTrapOID) * sizeof(oid));
-
+ OID_LENGTH(backendStatusChangeTrapOID) * sizeof(oid));
snmp_varlist_add_variable(&varList,
backendNameOID,
snmpTrapOID.size(),
ASN_OBJECT_ID,
customTrapOID,
- OID_LENGTH(customTrapOID) * sizeof(oid));
+ OID_LENGTH(customTrapOID) * sizeof(oid));
snmp_varlist_add_variable(&varList,
trapReasonOID,
const uint32_t socketFamily = dq.ids.origRemote.isIPv4() ? 1 : 2;
const uint32_t socketProtocol = dq.overTCP() ? 2 : 1;
const uint32_t queryType = dq.getHeader()->qr ? 2 : 1;
- const uint32_t querySize = (uint32_t) dq.getData().size();
- const uint32_t queryID = (uint32_t) ntohs(dq.getHeader()->id);
- const uint32_t qType = (uint32_t) dq.ids.qtype;
- const uint32_t qClass = (uint32_t) dq.ids.qclass;
+ const uint32_t querySize = (uint32_t)dq.getData().size();
+ const uint32_t queryID = (uint32_t)ntohs(dq.getHeader()->id);
+ const uint32_t qType = (uint32_t)dq.ids.qtype;
+ const uint32_t qClass = (uint32_t)dq.ids.qclass;
netsnmp_variable_list* varList = nullptr;
snmpTrapOID.size(),
ASN_OBJECT_ID,
actionTrapOID,
- OID_LENGTH(actionTrapOID) * sizeof(oid));
+ OID_LENGTH(actionTrapOID) * sizeof(oid));
snmp_varlist_add_variable(&varList,
socketFamilyOID,
#endif /* HAVE_NET_SNMP */
}
-DNSDistSNMPAgent::DNSDistSNMPAgent(const std::string& name, const std::string& daemonSocket): SNMPAgent(name, daemonSocket)
+DNSDistSNMPAgent::DNSDistSNMPAgent(const std::string& name, const std::string& daemonSocket) :
+ SNMPAgent(name, daemonSocket)
{
#ifdef HAVE_NET_SNMP
registerGauge64Stat("securityStatus", securityStatusOID, OID_LENGTH(securityStatusOID), [](const std::string&) { return dnsdist::metrics::g_stats.securityStatus.load(); });
registerGauge64Stat("realMemoryUsage", realMemoryUsageOID, OID_LENGTH(realMemoryUsageOID), &getRealMemoryUsage);
-
netsnmp_table_registration_info* table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
netsnmp_table_helper_add_indexes(table_info,
- ASN_GAUGE, /* index: backendId */
+ ASN_GAUGE, /* index: backendId */
0);
table_info->min_column = COLUMN_BACKENDNAME;
table_info->max_column = COLUMN_BACKENDORDER;
#include "dnsdist.hh"
-class DNSDistSNMPAgent: public SNMPAgent
+class DNSDistSNMPAgent : public SNMPAgent
{
public:
DNSDistSNMPAgent(const std::string& name, const std::string& daemonSocket);
bool sendBackendStatusChangeTrap(const DownstreamState&);
bool sendCustomTrap(const std::string& reason);
- bool sendDNSTrap(const DNSQuestion&, const std::string& reason="");
+ bool sendDNSTrap(const DNSQuestion&, const std::string& reason = "");
};
NetmaskGroup acl;
std::unique_ptr<CredentialsHolder> password;
std::unique_ptr<CredentialsHolder> apiKey;
- boost::optional<std::unordered_map<std::string, std::string> > customHeaders;
+ boost::optional<std::unordered_map<std::string, std::string>> customHeaders;
bool apiRequiresAuthentication{true};
bool dashboardRequiresAuthentication{true};
bool statsRequireAuthentication{true};
class WebClientConnection
{
public:
- WebClientConnection(const ComboAddress& client, int fd): d_client(client), d_socket(fd)
+ WebClientConnection(const ComboAddress& client, int fd) :
+ d_client(client), d_socket(fd)
{
if (!s_connManager.registerConnection()) {
throw std::runtime_error("Too many concurrent web client connections");
}
}
- WebClientConnection(WebClientConnection&& rhs): d_client(rhs.d_client), d_socket(std::move(rhs.d_socket))
+ WebClientConnection(WebClientConnection&& rhs) :
+ d_client(rhs.d_client), d_socket(std::move(rhs.d_socket))
{
}
static MetricDefinitionStorage s_metricDefinitions;
std::map<std::string, MetricDefinition> MetricDefinitionStorage::metrics{
- { "responses", MetricDefinition(PrometheusMetricType::counter, "Number of responses received from backends") },
- { "servfail-responses", MetricDefinition(PrometheusMetricType::counter, "Number of SERVFAIL answers received from backends") },
- { "queries", MetricDefinition(PrometheusMetricType::counter, "Number of received queries")},
- { "frontend-nxdomain", MetricDefinition(PrometheusMetricType::counter, "Number of NXDomain answers sent to clients")},
- { "frontend-servfail", MetricDefinition(PrometheusMetricType::counter, "Number of SERVFAIL answers sent to clients")},
- { "frontend-noerror", MetricDefinition(PrometheusMetricType::counter, "Number of NoError answers sent to clients")},
- { "acl-drops", MetricDefinition(PrometheusMetricType::counter, "Number of packets dropped because of the ACL")},
- { "rule-drop", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped because of a rule")},
- { "rule-nxdomain", MetricDefinition(PrometheusMetricType::counter, "Number of NXDomain answers returned because of a rule")},
- { "rule-refused", MetricDefinition(PrometheusMetricType::counter, "Number of Refused answers returned because of a rule")},
- { "rule-servfail", MetricDefinition(PrometheusMetricType::counter, "Number of SERVFAIL answers received because of a rule")},
- { "rule-truncated", MetricDefinition(PrometheusMetricType::counter, "Number of truncated answers returned because of a rule")},
- { "self-answered", MetricDefinition(PrometheusMetricType::counter, "Number of self-answered responses")},
- { "downstream-timeouts", MetricDefinition(PrometheusMetricType::counter, "Number of queries not answered in time by a backend")},
- { "downstream-send-errors", MetricDefinition(PrometheusMetricType::counter, "Number of errors when sending a query to a backend")},
- { "trunc-failures", MetricDefinition(PrometheusMetricType::counter, "Number of errors encountered while truncating an answer")},
- { "no-policy", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped because no server was available")},
- { "latency0-1", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in less than 1ms")},
- { "latency1-10", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in 1-10 ms")},
- { "latency10-50", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in 10-50 ms")},
- { "latency50-100", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in 50-100 ms")},
- { "latency100-1000", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in 100-1000 ms")},
- { "latency-slow", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in more than 1 second")},
- { "latency-avg100", MetricDefinition(PrometheusMetricType::gauge, "Average response latency in microseconds of the last 100 packets")},
- { "latency-avg1000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency in microseconds of the last 1000 packets")},
- { "latency-avg10000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency in microseconds of the last 10000 packets")},
- { "latency-avg1000000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency in microseconds of the last 1000000 packets")},
- { "latency-tcp-avg100", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 100 packets received over TCP")},
- { "latency-tcp-avg1000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000 packets received over TCP")},
- { "latency-tcp-avg10000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 10000 packets received over TCP")},
- { "latency-tcp-avg1000000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000000 packets received over TCP")},
- { "latency-dot-avg100", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 100 packets received over DoT")},
- { "latency-dot-avg1000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000 packets received over DoT")},
- { "latency-dot-avg10000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 10000 packets received over DoT")},
- { "latency-dot-avg1000000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000000 packets received over DoT")},
- { "latency-doh-avg100", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 100 packets received over DoH")},
- { "latency-doh-avg1000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000 packets received over DoH")},
- { "latency-doh-avg10000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 10000 packets received over DoH")},
- { "latency-doh-avg1000000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000000 packets received over DoH")},
- { "latency-doq-avg100", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 100 packets received over DoQ")},
- { "latency-doq-avg1000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000 packets received over DoQ")},
- { "latency-doq-avg10000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 10000 packets received over DoQ")},
- { "latency-doq-avg1000000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000000 packets received over DoQ")},
- { "uptime", MetricDefinition(PrometheusMetricType::gauge, "Uptime of the dnsdist process in seconds")},
- { "real-memory-usage", MetricDefinition(PrometheusMetricType::gauge, "Current memory usage in bytes")},
- { "noncompliant-queries", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped as non-compliant")},
- { "noncompliant-responses", MetricDefinition(PrometheusMetricType::counter, "Number of answers from a backend dropped as non-compliant")},
- { "rdqueries", MetricDefinition(PrometheusMetricType::counter, "Number of received queries with the recursion desired bit set")},
- { "empty-queries", MetricDefinition(PrometheusMetricType::counter, "Number of empty queries received from clients")},
- { "cache-hits", MetricDefinition(PrometheusMetricType::counter, "Number of times an answer was retrieved from cache")},
- { "cache-misses", MetricDefinition(PrometheusMetricType::counter, "Number of times an answer not found in the cache")},
- { "cpu-iowait", MetricDefinition(PrometheusMetricType::counter, "Time waiting for I/O to complete by the whole system, in units of USER_HZ")},
- { "cpu-user-msec", MetricDefinition(PrometheusMetricType::counter, "Milliseconds spent by dnsdist in the user state")},
- { "cpu-steal", MetricDefinition(PrometheusMetricType::counter, "Stolen time, which is the time spent by the whole system in other operating systems when running in a virtualized environment, in units of USER_HZ")},
- { "cpu-sys-msec", MetricDefinition(PrometheusMetricType::counter, "Milliseconds spent by dnsdist in the system state")},
- { "fd-usage", MetricDefinition(PrometheusMetricType::gauge, "Number of currently used file descriptors")},
- { "dyn-blocked", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped because of a dynamic block")},
- { "dyn-block-nmg-size", MetricDefinition(PrometheusMetricType::gauge, "Number of dynamic blocks entries") },
- { "security-status", MetricDefinition(PrometheusMetricType::gauge, "Security status of this software. 0=unknown, 1=OK, 2=upgrade recommended, 3=upgrade mandatory") },
- { "doh-query-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of DoH queries dropped because the internal pipe used to distribute queries was full") },
- { "doh-response-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of DoH responses dropped because the internal pipe used to distribute responses was full") },
- { "outgoing-doh-query-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of outgoing DoH queries dropped because the internal pipe used to distribute queries was full") },
- { "tcp-query-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of TCP queries dropped because the internal pipe used to distribute queries was full") },
- { "tcp-cross-protocol-query-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of TCP cross-protocol queries dropped because the internal pipe used to distribute queries was full") },
- { "tcp-cross-protocol-response-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of TCP cross-protocol responses dropped because the internal pipe used to distribute queries was full") },
- { "udp-in-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp InErrors") },
- { "udp-noport-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp NoPorts") },
- { "udp-recvbuf-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp RcvbufErrors") },
- { "udp-sndbuf-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp SndbufErrors") },
- { "udp-in-csum-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp InCsumErrors") },
- { "udp6-in-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp6 Udp6InErrors") },
- { "udp6-recvbuf-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp6 Udp6RcvbufErrors") },
- { "udp6-sndbuf-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp6 Udp6SndbufErrors") },
- { "udp6-noport-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp6 Udp6NoPorts") },
- { "udp6-in-csum-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp6 Udp6InCsumErrors") },
- { "tcp-listen-overflows", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/netstat ListenOverflows") },
- { "proxy-protocol-invalid", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped because of an invalid Proxy Protocol header") },
+ {"responses", MetricDefinition(PrometheusMetricType::counter, "Number of responses received from backends")},
+ {"servfail-responses", MetricDefinition(PrometheusMetricType::counter, "Number of SERVFAIL answers received from backends")},
+ {"queries", MetricDefinition(PrometheusMetricType::counter, "Number of received queries")},
+ {"frontend-nxdomain", MetricDefinition(PrometheusMetricType::counter, "Number of NXDomain answers sent to clients")},
+ {"frontend-servfail", MetricDefinition(PrometheusMetricType::counter, "Number of SERVFAIL answers sent to clients")},
+ {"frontend-noerror", MetricDefinition(PrometheusMetricType::counter, "Number of NoError answers sent to clients")},
+ {"acl-drops", MetricDefinition(PrometheusMetricType::counter, "Number of packets dropped because of the ACL")},
+ {"rule-drop", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped because of a rule")},
+ {"rule-nxdomain", MetricDefinition(PrometheusMetricType::counter, "Number of NXDomain answers returned because of a rule")},
+ {"rule-refused", MetricDefinition(PrometheusMetricType::counter, "Number of Refused answers returned because of a rule")},
+ {"rule-servfail", MetricDefinition(PrometheusMetricType::counter, "Number of SERVFAIL answers received because of a rule")},
+ {"rule-truncated", MetricDefinition(PrometheusMetricType::counter, "Number of truncated answers returned because of a rule")},
+ {"self-answered", MetricDefinition(PrometheusMetricType::counter, "Number of self-answered responses")},
+ {"downstream-timeouts", MetricDefinition(PrometheusMetricType::counter, "Number of queries not answered in time by a backend")},
+ {"downstream-send-errors", MetricDefinition(PrometheusMetricType::counter, "Number of errors when sending a query to a backend")},
+ {"trunc-failures", MetricDefinition(PrometheusMetricType::counter, "Number of errors encountered while truncating an answer")},
+ {"no-policy", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped because no server was available")},
+ {"latency0-1", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in less than 1ms")},
+ {"latency1-10", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in 1-10 ms")},
+ {"latency10-50", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in 10-50 ms")},
+ {"latency50-100", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in 50-100 ms")},
+ {"latency100-1000", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in 100-1000 ms")},
+ {"latency-slow", MetricDefinition(PrometheusMetricType::counter, "Number of queries answered in more than 1 second")},
+ {"latency-avg100", MetricDefinition(PrometheusMetricType::gauge, "Average response latency in microseconds of the last 100 packets")},
+ {"latency-avg1000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency in microseconds of the last 1000 packets")},
+ {"latency-avg10000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency in microseconds of the last 10000 packets")},
+ {"latency-avg1000000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency in microseconds of the last 1000000 packets")},
+ {"latency-tcp-avg100", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 100 packets received over TCP")},
+ {"latency-tcp-avg1000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000 packets received over TCP")},
+ {"latency-tcp-avg10000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 10000 packets received over TCP")},
+ {"latency-tcp-avg1000000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000000 packets received over TCP")},
+ {"latency-dot-avg100", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 100 packets received over DoT")},
+ {"latency-dot-avg1000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000 packets received over DoT")},
+ {"latency-dot-avg10000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 10000 packets received over DoT")},
+ {"latency-dot-avg1000000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000000 packets received over DoT")},
+ {"latency-doh-avg100", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 100 packets received over DoH")},
+ {"latency-doh-avg1000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000 packets received over DoH")},
+ {"latency-doh-avg10000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 10000 packets received over DoH")},
+ {"latency-doh-avg1000000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000000 packets received over DoH")},
+ {"latency-doq-avg100", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 100 packets received over DoQ")},
+ {"latency-doq-avg1000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000 packets received over DoQ")},
+ {"latency-doq-avg10000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 10000 packets received over DoQ")},
+ {"latency-doq-avg1000000", MetricDefinition(PrometheusMetricType::gauge, "Average response latency, in microseconds, of the last 1000000 packets received over DoQ")},
+ {"uptime", MetricDefinition(PrometheusMetricType::gauge, "Uptime of the dnsdist process in seconds")},
+ {"real-memory-usage", MetricDefinition(PrometheusMetricType::gauge, "Current memory usage in bytes")},
+ {"noncompliant-queries", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped as non-compliant")},
+ {"noncompliant-responses", MetricDefinition(PrometheusMetricType::counter, "Number of answers from a backend dropped as non-compliant")},
+ {"rdqueries", MetricDefinition(PrometheusMetricType::counter, "Number of received queries with the recursion desired bit set")},
+ {"empty-queries", MetricDefinition(PrometheusMetricType::counter, "Number of empty queries received from clients")},
+ {"cache-hits", MetricDefinition(PrometheusMetricType::counter, "Number of times an answer was retrieved from cache")},
+ {"cache-misses", MetricDefinition(PrometheusMetricType::counter, "Number of times an answer not found in the cache")},
+ {"cpu-iowait", MetricDefinition(PrometheusMetricType::counter, "Time waiting for I/O to complete by the whole system, in units of USER_HZ")},
+ {"cpu-user-msec", MetricDefinition(PrometheusMetricType::counter, "Milliseconds spent by dnsdist in the user state")},
+ {"cpu-steal", MetricDefinition(PrometheusMetricType::counter, "Stolen time, which is the time spent by the whole system in other operating systems when running in a virtualized environment, in units of USER_HZ")},
+ {"cpu-sys-msec", MetricDefinition(PrometheusMetricType::counter, "Milliseconds spent by dnsdist in the system state")},
+ {"fd-usage", MetricDefinition(PrometheusMetricType::gauge, "Number of currently used file descriptors")},
+ {"dyn-blocked", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped because of a dynamic block")},
+ {"dyn-block-nmg-size", MetricDefinition(PrometheusMetricType::gauge, "Number of dynamic blocks entries")},
+ {"security-status", MetricDefinition(PrometheusMetricType::gauge, "Security status of this software. 0=unknown, 1=OK, 2=upgrade recommended, 3=upgrade mandatory")},
+ {"doh-query-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of DoH queries dropped because the internal pipe used to distribute queries was full")},
+ {"doh-response-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of DoH responses dropped because the internal pipe used to distribute responses was full")},
+ {"outgoing-doh-query-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of outgoing DoH queries dropped because the internal pipe used to distribute queries was full")},
+ {"tcp-query-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of TCP queries dropped because the internal pipe used to distribute queries was full")},
+ {"tcp-cross-protocol-query-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of TCP cross-protocol queries dropped because the internal pipe used to distribute queries was full")},
+ {"tcp-cross-protocol-response-pipe-full", MetricDefinition(PrometheusMetricType::counter, "Number of TCP cross-protocol responses dropped because the internal pipe used to distribute queries was full")},
+ {"udp-in-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp InErrors")},
+ {"udp-noport-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp NoPorts")},
+ {"udp-recvbuf-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp RcvbufErrors")},
+ {"udp-sndbuf-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp SndbufErrors")},
+ {"udp-in-csum-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp InCsumErrors")},
+ {"udp6-in-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp6 Udp6InErrors")},
+ {"udp6-recvbuf-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp6 Udp6RcvbufErrors")},
+ {"udp6-sndbuf-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp6 Udp6SndbufErrors")},
+ {"udp6-noport-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp6 Udp6NoPorts")},
+ {"udp6-in-csum-errors", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/snmp6 Udp6InCsumErrors")},
+ {"tcp-listen-overflows", MetricDefinition(PrometheusMetricType::counter, "From /proc/net/netstat ListenOverflows")},
+ {"proxy-protocol-invalid", MetricDefinition(PrometheusMetricType::counter, "Number of queries dropped because of an invalid Proxy Protocol header")},
};
#endif /* DISABLE_PROMETHEUS */
-bool addMetricDefinition(const dnsdist::prometheus::PrometheusMetricDefinition& def) {
+bool addMetricDefinition(const dnsdist::prometheus::PrometheusMetricDefinition& def)
+{
#ifndef DISABLE_PROMETHEUS
return MetricDefinitionStorage::addMetricDefinition(def);
#else
if (isAnAPIRequest(req)) {
/* Access to the API requires a valid API key */
- if (!config->apiRequiresAuthentication || checkAPIKey(req, config->apiKey)) {
+ if (!config->apiRequiresAuthentication || checkAPIKey(req, config->apiKey)) {
return true;
}
}
}
-static void addSecurityHeaders(YaHTTP::Response& resp, const boost::optional<std::unordered_map<std::string, std::string> >& customHeaders)
+static void addSecurityHeaders(YaHTTP::Response& resp, const boost::optional<std::unordered_map<std::string, std::string>>& customHeaders)
{
- static const std::vector<std::pair<std::string, std::string> > headers = {
- { "X-Content-Type-Options", "nosniff" },
- { "X-Frame-Options", "deny" },
- { "X-Permitted-Cross-Domain-Policies", "none" },
- { "X-XSS-Protection", "1; mode=block" },
- { "Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'" },
+ static const std::vector<std::pair<std::string, std::string>> headers = {
+ {"X-Content-Type-Options", "nosniff"},
+ {"X-Frame-Options", "deny"},
+ {"X-Permitted-Cross-Domain-Policies", "none"},
+ {"X-XSS-Protection", "1; mode=block"},
+ {"Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'"},
};
for (const auto& h : headers) {
}
}
-static void addCustomHeaders(YaHTTP::Response& resp, const boost::optional<std::unordered_map<std::string, std::string> >& customHeaders)
+static void addCustomHeaders(YaHTTP::Response& resp, const boost::optional<std::unordered_map<std::string, std::string>>& customHeaders)
{
if (!customHeaders)
return;
}
}
-template<typename T>
+template <typename T>
static json11::Json::array someResponseRulesToJson(GlobalStateHolder<vector<T>>* someResponseRules)
{
using namespace json11;
Json::array responseRules;
- int num=0;
+ int num = 0;
auto localResponseRules = someResponseRules->getLocal();
responseRules.reserve(localResponseRules->size());
for (const auto& a : *localResponseRules) {
responseRules.push_back(Json::object{
- {"id", num++},
- {"creationOrder", (double)a.d_creationOrder},
- {"uuid", boost::uuids::to_string(a.d_id)},
- {"name", a.d_name},
- {"matches", (double)a.d_rule->d_matches},
- {"rule", a.d_rule->toString()},
- {"action", a.d_action->toString()},
- });
+ {"id", num++},
+ {"creationOrder", (double)a.d_creationOrder},
+ {"uuid", boost::uuids::to_string(a.d_id)},
+ {"name", a.d_name},
+ {"matches", (double)a.d_rule->d_matches},
+ {"rule", a.d_rule->toString()},
+ {"action", a.d_action->toString()},
+ });
}
return responseRules;
}
#ifndef DISABLE_PROMETHEUS
-template<typename T>
-static void addRulesToPrometheusOutput(std::ostringstream& output, GlobalStateHolder<vector<T> >& rules)
+template <typename T>
+static void addRulesToPrometheusOutput(std::ostringstream& output, GlobalStateHolder<vector<T>>& rules)
{
auto localRules = rules.getLocal();
for (const auto& entry : *localRules) {
resp.status = 200;
std::ostringstream output;
- static const std::set<std::string> metricBlacklist = { "special-memory-usage", "latency-count", "latency-sum" };
+ static const std::set<std::string> metricBlacklist = {"special-memory-usage", "latency-count", "latency-sum"};
{
auto entries = dnsdist::metrics::g_stats.entries.read_lock();
for (const auto& entry : *entries) {
// for these we have the help and types encoded in the sources
// but we need to be careful about labels in custom metrics
std::string helpName = prometheusMetricName.substr(0, prometheusMetricName.find('{'));
- output << "# HELP " << helpName << " " << metricDetails.description << "\n";
+ output << "# HELP " << helpName << " " << metricDetails.description << "\n";
output << "# TYPE " << helpName << " " << prometheusTypeName << "\n";
output << prometheusMetricName << " ";
auto states = g_dstates.getLocal();
const string statesbase = "dnsdist_server_";
+ // clang-format off
output << "# HELP " << statesbase << "status " << "Whether this backend is up (1) or down (0)" << "\n";
output << "# TYPE " << statesbase << "status " << "gauge" << "\n";
output << "# HELP " << statesbase << "queries " << "Amount of queries relayed to server" << "\n";
resp.body = output.str();
resp.headers["Content-Type"] = "text/plain";
+ // clang-format on
}
#endif /* DISABLE_PROMETHEUS */
}
if (const auto& val = std::get_if<pdns::stat_t*>(&entry.d_value)) {
obj.emplace(entry.d_name, (double)(*val)->load());
- } else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&entry.d_value)) {
+ }
+ else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&entry.d_value)) {
obj.emplace(entry.d_name, (*adval)->load());
- } else if (const auto& dval = std::get_if<double*>(&entry.d_value)) {
+ }
+ else if (const auto& dval = std::get_if<double*>(&entry.d_value)) {
obj.emplace(entry.d_name, (**dval));
- } else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&entry.d_value)) {
+ }
+ else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&entry.d_value)) {
obj.emplace(entry.d_name, (double)(*func)(entry.d_name));
}
}
const string& command = req.getvars.at("command");
if (command == "stats") {
- auto obj=Json::object {
- { "packetcache-hits", 0},
- { "packetcache-misses", 0},
- { "over-capacity-drops", 0 },
- { "too-old-drops", 0 },
- { "server-policy", g_policy.getLocal()->getName()}
- };
+ auto obj = Json::object{
+ {"packetcache-hits", 0},
+ {"packetcache-misses", 0},
+ {"over-capacity-drops", 0},
+ {"too-old-drops", 0},
+ {"server-policy", g_policy.getLocal()->getName()}};
addStatsToJSONObject(obj);
auto nmg = g_dynblockNMG.getLocal();
struct timespec now;
gettime(&now);
- for (const auto& entry: *nmg) {
+ for (const auto& entry : *nmg) {
if (!(now < entry.second.until)) {
continue;
}
{"blocks", static_cast<double>(counter)},
{"action", DNSAction::typeToString(entry.second.action != DNSAction::Action::None ? entry.second.action : g_dynBlockAction)},
{"warning", entry.second.warning},
- {"ebpf", entry.second.bpf}
- };
+ {"ebpf", entry.second.bpf}};
obj.emplace(entry.first.toString(), thing);
}
auto smt = g_dynblockSMT.getLocal();
- smt->visit([&now,&obj](const SuffixMatchTree<DynBlock>& node) {
+ smt->visit([&now, &obj](const SuffixMatchTree<DynBlock>& node) {
if (!(now < node.d_value.until)) {
return;
}
{"seconds", static_cast<double>(node.d_value.until.tv_sec - now.tv_sec)},
{"blocks", static_cast<double>(node.d_value.blocks)},
{"action", DNSAction::typeToString(node.d_value.action != DNSAction::Action::None ? node.d_value.action : g_dynBlockAction)},
- {"ebpf", node.d_value.bpf}
- };
+ {"ebpf", node.d_value.bpf}};
obj.emplace(dom, thing);
});
#endif /* DISABLE_DYNBLOCKS */
struct timespec now;
gettime(&now);
for (const auto& dynbpf : g_dynBPFFilters) {
- std::vector<std::tuple<ComboAddress, uint64_t, struct timespec> > addrStats = dynbpf->getAddrStats();
+ std::vector<std::tuple<ComboAddress, uint64_t, struct timespec>> addrStats = dynbpf->getAddrStats();
for (const auto& entry : addrStats) {
- Json::object thing
- {
- {"seconds", (double)(std::get<2>(entry).tv_sec - now.tv_sec)},
- {"blocks", (double)(std::get<1>(entry))}
- };
- obj.emplace(std::get<0>(entry).toString(), thing );
+ Json::object thing{
+ {"seconds", (double)(std::get<2>(entry).tv_sec - now.tv_sec)},
+ {"blocks", (double)(std::get<1>(entry))}};
+ obj.emplace(std::get<0>(entry).toString(), thing);
}
}
if (g_defaultBPFFilter) {
auto nmg = g_dynblockNMG.getLocal();
- for (const auto& entry: *nmg) {
+ for (const auto& entry : *nmg) {
if (!(now < entry.second.until) || !entry.second.bpf) {
continue;
}
Json::array pools;
pools.reserve(a->d_config.pools.size());
- for (const auto& p: a->d_config.pools) {
+ for (const auto& p : a->d_config.pools) {
pools.push_back(p);
}
- Json::object server {
+ Json::object server{
{"id", id},
{"name", a->getName()},
{"address", a->d_config.remote.toStringWithPort()},
{"weight", (double)a->d_config.d_weight},
{"order", (double)a->d_config.order},
{"pools", std::move(pools)},
- {"latency", (double)(a->latencyUsec/1000.0)},
+ {"latency", (double)(a->latencyUsec / 1000.0)},
{"queries", (double)a->queries},
{"responses", (double)a->responses},
{"nonCompliantResponses", (double)a->nonCompliantResponses},
{"tcpAvgQueriesPerConnection", (double)a->tcpAvgQueriesPerConnection},
{"tcpAvgConnectionDuration", (double)a->tcpAvgConnectionDuration},
{"tlsResumptions", (double)a->tlsResumptions},
- {"tcpLatency", (double)(a->latencyUsecTCP/1000.0)},
+ {"tcpLatency", (double)(a->latencyUsecTCP / 1000.0)},
{"healthCheckFailures", (double)(a->d_healthCheckMetrics.d_failures)},
{"healthCheckFailuresParsing", (double)(a->d_healthCheckMetrics.d_parseErrors)},
{"healthCheckFailuresTimeout", (double)(a->d_healthCheckMetrics.d_timeOuts)},
{"healthCheckFailuresNetwork", (double)(a->d_healthCheckMetrics.d_networkErrors)},
{"healthCheckFailuresMismatch", (double)(a->d_healthCheckMetrics.d_mismatchErrors)},
{"healthCheckFailuresInvalid", (double)(a->d_healthCheckMetrics.d_invalidResponseErrors)},
- {"dropRate", (double)a->dropRate}
- };
+ {"dropRate", (double)a->dropRate}};
/* sending a latency for a DOWN server doesn't make sense */
if (a->d_config.availability == DownstreamState::Availability::Down) {
for (const auto& front : g_frontends) {
if (front->udpFD == -1 && front->tcpFD == -1)
continue;
- Json::object frontend {
- { "id", num++ },
- { "address", front->local.toStringWithPort() },
- { "udp", front->udpFD >= 0 },
- { "tcp", front->tcpFD >= 0 },
- { "type", front->getType() },
- { "queries", (double) front->queries.load() },
- { "nonCompliantQueries", (double) front->nonCompliantQueries.load() },
- { "responses", (double) front->responses.load() },
- { "tcpDiedReadingQuery", (double) front->tcpDiedReadingQuery.load() },
- { "tcpDiedSendingResponse", (double) front->tcpDiedSendingResponse.load() },
- { "tcpGaveUp", (double) front->tcpGaveUp.load() },
- { "tcpClientTimeouts", (double) front->tcpClientTimeouts },
- { "tcpDownstreamTimeouts", (double) front->tcpDownstreamTimeouts },
- { "tcpCurrentConnections", (double) front->tcpCurrentConnections },
- { "tcpMaxConcurrentConnections", (double) front->tcpMaxConcurrentConnections },
- { "tcpAvgQueriesPerConnection", (double) front->tcpAvgQueriesPerConnection },
- { "tcpAvgConnectionDuration", (double) front->tcpAvgConnectionDuration },
- { "tlsNewSessions", (double) front->tlsNewSessions },
- { "tlsResumptions", (double) front->tlsResumptions },
- { "tlsUnknownTicketKey", (double) front->tlsUnknownTicketKey },
- { "tlsInactiveTicketKey", (double) front->tlsInactiveTicketKey },
- { "tls10Queries", (double) front->tls10queries },
- { "tls11Queries", (double) front->tls11queries },
- { "tls12Queries", (double) front->tls12queries },
- { "tls13Queries", (double) front->tls13queries },
- { "tlsUnknownQueries", (double) front->tlsUnknownqueries },
+ Json::object frontend{
+ {"id", num++},
+ {"address", front->local.toStringWithPort()},
+ {"udp", front->udpFD >= 0},
+ {"tcp", front->tcpFD >= 0},
+ {"type", front->getType()},
+ {"queries", (double)front->queries.load()},
+ {"nonCompliantQueries", (double)front->nonCompliantQueries.load()},
+ {"responses", (double)front->responses.load()},
+ {"tcpDiedReadingQuery", (double)front->tcpDiedReadingQuery.load()},
+ {"tcpDiedSendingResponse", (double)front->tcpDiedSendingResponse.load()},
+ {"tcpGaveUp", (double)front->tcpGaveUp.load()},
+ {"tcpClientTimeouts", (double)front->tcpClientTimeouts},
+ {"tcpDownstreamTimeouts", (double)front->tcpDownstreamTimeouts},
+ {"tcpCurrentConnections", (double)front->tcpCurrentConnections},
+ {"tcpMaxConcurrentConnections", (double)front->tcpMaxConcurrentConnections},
+ {"tcpAvgQueriesPerConnection", (double)front->tcpAvgQueriesPerConnection},
+ {"tcpAvgConnectionDuration", (double)front->tcpAvgConnectionDuration},
+ {"tlsNewSessions", (double)front->tlsNewSessions},
+ {"tlsResumptions", (double)front->tlsResumptions},
+ {"tlsUnknownTicketKey", (double)front->tlsUnknownTicketKey},
+ {"tlsInactiveTicketKey", (double)front->tlsInactiveTicketKey},
+ {"tls10Queries", (double)front->tls10queries},
+ {"tls11Queries", (double)front->tls11queries},
+ {"tls12Queries", (double)front->tls12queries},
+ {"tls13Queries", (double)front->tls13queries},
+ {"tlsUnknownQueries", (double)front->tlsUnknownqueries},
};
const TLSErrorCounters* errorCounters = nullptr;
if (front->tlsFrontend != nullptr) {
num = 0;
for (const auto& doh : g_dohlocals) {
dohs.emplace_back(Json::object{
- { "id", num++ },
- { "address", doh->d_tlsContext.d_addr.toStringWithPort() },
- { "http-connects", (double) doh->d_httpconnects },
- { "http1-queries", (double) doh->d_http1Stats.d_nbQueries },
- { "http2-queries", (double) doh->d_http2Stats.d_nbQueries },
- { "http1-200-responses", (double) doh->d_http1Stats.d_nb200Responses },
- { "http2-200-responses", (double) doh->d_http2Stats.d_nb200Responses },
- { "http1-400-responses", (double) doh->d_http1Stats.d_nb400Responses },
- { "http2-400-responses", (double) doh->d_http2Stats.d_nb400Responses },
- { "http1-403-responses", (double) doh->d_http1Stats.d_nb403Responses },
- { "http2-403-responses", (double) doh->d_http2Stats.d_nb403Responses },
- { "http1-500-responses", (double) doh->d_http1Stats.d_nb500Responses },
- { "http2-500-responses", (double) doh->d_http2Stats.d_nb500Responses },
- { "http1-502-responses", (double) doh->d_http1Stats.d_nb502Responses },
- { "http2-502-responses", (double) doh->d_http2Stats.d_nb502Responses },
- { "http1-other-responses", (double) doh->d_http1Stats.d_nbOtherResponses },
- { "http2-other-responses", (double) doh->d_http2Stats.d_nbOtherResponses },
- { "get-queries", (double) doh->d_getqueries },
- { "post-queries", (double) doh->d_postqueries },
- { "bad-requests", (double) doh->d_badrequests },
- { "error-responses", (double) doh->d_errorresponses },
- { "redirect-responses", (double) doh->d_redirectresponses },
- { "valid-responses", (double) doh->d_validresponses }
- });
+ {"id", num++},
+ {"address", doh->d_tlsContext.d_addr.toStringWithPort()},
+ {"http-connects", (double)doh->d_httpconnects},
+ {"http1-queries", (double)doh->d_http1Stats.d_nbQueries},
+ {"http2-queries", (double)doh->d_http2Stats.d_nbQueries},
+ {"http1-200-responses", (double)doh->d_http1Stats.d_nb200Responses},
+ {"http2-200-responses", (double)doh->d_http2Stats.d_nb200Responses},
+ {"http1-400-responses", (double)doh->d_http1Stats.d_nb400Responses},
+ {"http2-400-responses", (double)doh->d_http2Stats.d_nb400Responses},
+ {"http1-403-responses", (double)doh->d_http1Stats.d_nb403Responses},
+ {"http2-403-responses", (double)doh->d_http2Stats.d_nb403Responses},
+ {"http1-500-responses", (double)doh->d_http1Stats.d_nb500Responses},
+ {"http2-500-responses", (double)doh->d_http2Stats.d_nb500Responses},
+ {"http1-502-responses", (double)doh->d_http1Stats.d_nb502Responses},
+ {"http2-502-responses", (double)doh->d_http2Stats.d_nb502Responses},
+ {"http1-other-responses", (double)doh->d_http1Stats.d_nbOtherResponses},
+ {"http2-other-responses", (double)doh->d_http2Stats.d_nbOtherResponses},
+ {"get-queries", (double)doh->d_getqueries},
+ {"post-queries", (double)doh->d_postqueries},
+ {"bad-requests", (double)doh->d_badrequests},
+ {"error-responses", (double)doh->d_errorresponses},
+ {"redirect-responses", (double)doh->d_redirectresponses},
+ {"valid-responses", (double)doh->d_validresponses}});
}
}
#endif /* HAVE_DNS_OVER_HTTPS */
pools.reserve(localPools->size());
for (const auto& pool : *localPools) {
const auto& cache = pool.second->packetCache;
- Json::object entry {
- { "id", num++ },
- { "name", pool.first },
- { "serversCount", (double) pool.second->countServers(false) },
- { "cacheSize", (double) (cache ? cache->getMaxEntries() : 0) },
- { "cacheEntries", (double) (cache ? cache->getEntriesCount() : 0) },
- { "cacheHits", (double) (cache ? cache->getHits() : 0) },
- { "cacheMisses", (double) (cache ? cache->getMisses() : 0) },
- { "cacheDeferredInserts", (double) (cache ? cache->getDeferredInserts() : 0) },
- { "cacheDeferredLookups", (double) (cache ? cache->getDeferredLookups() : 0) },
- { "cacheLookupCollisions", (double) (cache ? cache->getLookupCollisions() : 0) },
- { "cacheInsertCollisions", (double) (cache ? cache->getInsertCollisions() : 0) },
- { "cacheTTLTooShorts", (double) (cache ? cache->getTTLTooShorts() : 0) },
- { "cacheCleanupCount", (double) (cache ? cache->getCleanupCount() : 0) }
- };
+ Json::object entry{
+ {"id", num++},
+ {"name", pool.first},
+ {"serversCount", (double)pool.second->countServers(false)},
+ {"cacheSize", (double)(cache ? cache->getMaxEntries() : 0)},
+ {"cacheEntries", (double)(cache ? cache->getEntriesCount() : 0)},
+ {"cacheHits", (double)(cache ? cache->getHits() : 0)},
+ {"cacheMisses", (double)(cache ? cache->getMisses() : 0)},
+ {"cacheDeferredInserts", (double)(cache ? cache->getDeferredInserts() : 0)},
+ {"cacheDeferredLookups", (double)(cache ? cache->getDeferredLookups() : 0)},
+ {"cacheLookupCollisions", (double)(cache ? cache->getLookupCollisions() : 0)},
+ {"cacheInsertCollisions", (double)(cache ? cache->getInsertCollisions() : 0)},
+ {"cacheTTLTooShorts", (double)(cache ? cache->getTTLTooShorts() : 0)},
+ {"cacheCleanupCount", (double)(cache ? cache->getCleanupCount() : 0)}};
pools.push_back(std::move(entry));
}
}
{"matches", (double)a.d_rule->d_matches},
{"rule", a.d_rule->toString()},
{"action", a.d_action->toString()},
- {"action-stats", a.d_action->getStats()}
- };
+ {"action-stats", a.d_action->getStats()}};
rules.push_back(std::move(rule));
}
}
Json::object stats;
addStatsToJSONObject(stats);
- Json responseObject(Json::object({
- { "daemon_type", "dnsdist" },
- { "version", VERSION },
- { "servers", std::move(servers) },
- { "frontends", std::move(frontends) },
- { "pools", std::move(pools) },
- { "rules", std::move(rules) },
- { "response-rules", std::move(responseRules) },
- { "cache-hit-response-rules", std::move(cacheHitResponseRules) },
- { "cache-inserted-response-rules", std::move(cacheInsertedResponseRules) },
- { "self-answered-response-rules", std::move(selfAnsweredResponseRules) },
- { "acl", std::move(acl) },
- { "local", std::move(localaddressesStr) },
- { "dohFrontends", std::move(dohs) },
- { "statistics", std::move(stats) }
- }));
+ Json responseObject(Json::object({{"daemon_type", "dnsdist"},
+ {"version", VERSION},
+ {"servers", std::move(servers)},
+ {"frontends", std::move(frontends)},
+ {"pools", std::move(pools)},
+ {"rules", std::move(rules)},
+ {"response-rules", std::move(responseRules)},
+ {"cache-hit-response-rules", std::move(cacheHitResponseRules)},
+ {"cache-inserted-response-rules", std::move(cacheInsertedResponseRules)},
+ {"self-answered-response-rules", std::move(selfAnsweredResponseRules)},
+ {"acl", std::move(acl)},
+ {"local", std::move(localaddressesStr)},
+ {"dohFrontends", std::move(dohs)},
+ {"statistics", std::move(stats)}}));
resp.headers["Content-Type"] = "application/json";
resp.body = responseObject.dump();
const auto& pool = poolIt->second;
const auto& cache = pool->packetCache;
- Json::object entry {
- { "name", poolName->second },
- { "serversCount", (double) pool->countServers(false) },
- { "cacheSize", (double) (cache ? cache->getMaxEntries() : 0) },
- { "cacheEntries", (double) (cache ? cache->getEntriesCount() : 0) },
- { "cacheHits", (double) (cache ? cache->getHits() : 0) },
- { "cacheMisses", (double) (cache ? cache->getMisses() : 0) },
- { "cacheDeferredInserts", (double) (cache ? cache->getDeferredInserts() : 0) },
- { "cacheDeferredLookups", (double) (cache ? cache->getDeferredLookups() : 0) },
- { "cacheLookupCollisions", (double) (cache ? cache->getLookupCollisions() : 0) },
- { "cacheInsertCollisions", (double) (cache ? cache->getInsertCollisions() : 0) },
- { "cacheTTLTooShorts", (double) (cache ? cache->getTTLTooShorts() : 0) },
- { "cacheCleanupCount", (double) (cache ? cache->getCleanupCount() : 0) }
- };
+ Json::object entry{
+ {"name", poolName->second},
+ {"serversCount", (double)pool->countServers(false)},
+ {"cacheSize", (double)(cache ? cache->getMaxEntries() : 0)},
+ {"cacheEntries", (double)(cache ? cache->getEntriesCount() : 0)},
+ {"cacheHits", (double)(cache ? cache->getHits() : 0)},
+ {"cacheMisses", (double)(cache ? cache->getMisses() : 0)},
+ {"cacheDeferredInserts", (double)(cache ? cache->getDeferredInserts() : 0)},
+ {"cacheDeferredLookups", (double)(cache ? cache->getDeferredLookups() : 0)},
+ {"cacheLookupCollisions", (double)(cache ? cache->getLookupCollisions() : 0)},
+ {"cacheInsertCollisions", (double)(cache ? cache->getInsertCollisions() : 0)},
+ {"cacheTTLTooShorts", (double)(cache ? cache->getTTLTooShorts() : 0)},
+ {"cacheCleanupCount", (double)(cache ? cache->getCleanupCount() : 0)}};
Json::array servers;
int num = 0;
}
resp.headers["Content-Type"] = "application/json";
- Json my_json = Json::object {
- { "stats", entry },
- { "servers", servers }
- };
+ Json my_json = Json::object{
+ {"stats", entry},
+ {"servers", servers}};
resp.body = my_json.dump();
}
}
if (const auto& val = std::get_if<pdns::stat_t*>(&item.d_value)) {
- doc.push_back(Json::object {
- { "type", "StatisticItem" },
- { "name", item.d_name },
- { "value", (double)(*val)->load() }
- });
+ doc.push_back(Json::object{
+ {"type", "StatisticItem"},
+ {"name", item.d_name},
+ {"value", (double)(*val)->load()}});
}
else if (const auto& adval = std::get_if<pdns::stat_t_trait<double>*>(&item.d_value)) {
- doc.push_back(Json::object {
- { "type", "StatisticItem" },
- { "name", item.d_name },
- { "value", (*adval)->load() }
- });
+ doc.push_back(Json::object{
+ {"type", "StatisticItem"},
+ {"name", item.d_name},
+ {"value", (*adval)->load()}});
}
else if (const auto& dval = std::get_if<double*>(&item.d_value)) {
- doc.push_back(Json::object {
- { "type", "StatisticItem" },
- { "name", item.d_name },
- { "value", (**dval) }
- });
+ doc.push_back(Json::object{
+ {"type", "StatisticItem"},
+ {"name", item.d_name},
+ {"value", (**dval)}});
}
else if (const auto& func = std::get_if<dnsdist::metrics::Stats::statfunction_t>(&item.d_value)) {
- doc.push_back(Json::object {
- { "type", "StatisticItem" },
- { "name", item.d_name },
- { "value", (double)(*func)(item.d_name) }
- });
+ doc.push_back(Json::object{
+ {"type", "StatisticItem"},
+ {"name", item.d_name},
+ {"value", (double)(*func)(item.d_name)}});
}
}
}
Json::array doc;
typedef boost::variant<bool, double, std::string> configentry_t;
- std::vector<std::pair<std::string, configentry_t> > configEntries {
- { "acl", g_ACL.getLocal()->toString() },
- { "allow-empty-response", g_allowEmptyResponse },
- { "control-socket", g_serverControl.toStringWithPort() },
- { "ecs-override", g_ECSOverride },
- { "ecs-source-prefix-v4", (double) g_ECSSourcePrefixV4 },
- { "ecs-source-prefix-v6", (double) g_ECSSourcePrefixV6 },
- { "fixup-case", g_fixupCase },
- { "max-outstanding", (double) g_maxOutstanding },
- { "server-policy", g_policy.getLocal()->getName() },
- { "stale-cache-entries-ttl", (double) g_staleCacheEntriesTTL },
- { "tcp-recv-timeout", (double) g_tcpRecvTimeout },
- { "tcp-send-timeout", (double) g_tcpSendTimeout },
- { "truncate-tc", g_truncateTC },
- { "verbose", g_verbose },
- { "verbose-health-checks", g_verboseHealthChecks }
- };
- for(const auto& item : configEntries) {
+ std::vector<std::pair<std::string, configentry_t>> configEntries{
+ {"acl", g_ACL.getLocal()->toString()},
+ {"allow-empty-response", g_allowEmptyResponse},
+ {"control-socket", g_serverControl.toStringWithPort()},
+ {"ecs-override", g_ECSOverride},
+ {"ecs-source-prefix-v4", (double)g_ECSSourcePrefixV4},
+ {"ecs-source-prefix-v6", (double)g_ECSSourcePrefixV6},
+ {"fixup-case", g_fixupCase},
+ {"max-outstanding", (double)g_maxOutstanding},
+ {"server-policy", g_policy.getLocal()->getName()},
+ {"stale-cache-entries-ttl", (double)g_staleCacheEntriesTTL},
+ {"tcp-recv-timeout", (double)g_tcpRecvTimeout},
+ {"tcp-send-timeout", (double)g_tcpSendTimeout},
+ {"truncate-tc", g_truncateTC},
+ {"verbose", g_verbose},
+ {"verbose-health-checks", g_verboseHealthChecks}};
+ for (const auto& item : configEntries) {
if (const auto& bval = boost::get<bool>(&item.second)) {
- doc.push_back(Json::object {
- { "type", "ConfigSetting" },
- { "name", item.first },
- { "value", *bval }
- });
+ doc.push_back(Json::object{
+ {"type", "ConfigSetting"},
+ {"name", item.first},
+ {"value", *bval}});
}
else if (const auto& sval = boost::get<string>(&item.second)) {
- doc.push_back(Json::object {
- { "type", "ConfigSetting" },
- { "name", item.first },
- { "value", *sval }
- });
+ doc.push_back(Json::object{
+ {"type", "ConfigSetting"},
+ {"name", item.first},
+ {"value", *sval}});
}
else if (const auto& dval = boost::get<double>(&item.second)) {
- doc.push_back(Json::object {
- { "type", "ConfigSetting" },
- { "name", item.first },
- { "value", *dval }
- });
+ doc.push_back(Json::object{
+ {"type", "ConfigSetting"},
+ {"name", item.first},
+ {"value", *dval}});
}
}
Json my_json = doc;
for (const auto& value : aclList.array_items()) {
try {
nmg.addMask(value.string_value());
- } catch (NetmaskException &e) {
+ }
+ catch (NetmaskException& e) {
resp.status = 400;
break;
}
auto aclEntries = g_ACL.getLocal()->toStringVector();
Json::object obj{
- { "type", "ConfigSetting" },
- { "name", "allow-from" },
- { "value", aclEntries }
- };
+ {"type", "ConfigSetting"},
+ {"name", "allow-from"},
+ {"value", aclEntries}};
Json my_json = obj;
resp.body = my_json.dump();
}
if (req.method != "DELETE") {
resp.status = 400;
Json::object obj{
- { "status", "denied" },
- { "error", "invalid method" }
- };
+ {"status", "denied"},
+ {"error", "invalid method"}};
resp.body = Json(obj).dump();
return;
}
if (poolName == req.getvars.end() || expungeName == req.getvars.end()) {
resp.status = 400;
Json::object obj{
- { "status", "denied" },
- { "error", "missing 'pool' or 'name' parameter" },
+ {"status", "denied"},
+ {"error", "missing 'pool' or 'name' parameter"},
};
resp.body = Json(obj).dump();
return;
catch (const std::exception& e) {
resp.status = 400;
Json::object obj{
- { "status", "error" },
- { "error", "unable to parse the requested name" },
+ {"status", "error"},
+ {"error", "unable to parse the requested name"},
};
resp.body = Json(obj).dump();
return;
catch (const std::exception& e) {
resp.status = 404;
Json::object obj{
- { "status", "not found" },
- { "error", "the requested pool does not exist" },
+ {"status", "not found"},
+ {"error", "the requested pool does not exist"},
};
resp.body = Json(obj).dump();
return;
if (cache == nullptr) {
resp.status = 404;
Json::object obj{
- { "status", "not found" },
- { "error", "there is no cache associated with the requested pool" },
+ {"status", "not found"},
+ {"error", "there is no cache associated with the requested pool"},
};
resp.body = Json(obj).dump();
return;
auto removed = cache->expungeByName(name, type.getCode(), suffix != req.getvars.end());
Json::object obj{
- { "status", "purged" },
- { "count", std::to_string(removed) }
- };
+ {"status", "purged"},
+ {"count", std::to_string(removed)}};
resp.body = Json(obj).dump();
}
#endif /* DISABLE_WEB_CACHE_MANAGEMENT */
-template<typename T> static void addRingEntryToList(const struct timespec& now, Json::array& list, const T& entry)
+template <typename T>
+static void addRingEntryToList(const struct timespec& now, Json::array& list, const T& entry)
{
constexpr bool response = std::is_same_v<T, Rings::Response>;
Json::object tmp{
- { "age", static_cast<double>(DiffTime(entry.when, now)) },
- { "id", ntohs(entry.dh.id) },
- { "name", entry.name.toString() },
- { "requestor", entry.requestor.toStringWithPort() },
- { "size", static_cast<int>(entry.size) },
- { "qtype", entry.qtype },
- { "protocol", entry.protocol.toString() },
- { "rd", static_cast<bool>(entry.dh.rd) },
+ {"age", static_cast<double>(DiffTime(entry.when, now))},
+ {"id", ntohs(entry.dh.id)},
+ {"name", entry.name.toString()},
+ {"requestor", entry.requestor.toStringWithPort()},
+ {"size", static_cast<int>(entry.size)},
+ {"qtype", entry.qtype},
+ {"protocol", entry.protocol.toString()},
+ {"rd", static_cast<bool>(entry.dh.rd)},
};
if constexpr (!response) {
#if defined(DNSDIST_RINGS_WITH_MACADDRESS)
static void handleBuiltInFiles(const YaHTTP::Request& req, YaHTTP::Response& resp)
{
- if (req.url.path.empty() || !s_urlmap.count(req.url.path.c_str()+1)) {
+ if (req.url.path.empty() || !s_urlmap.count(req.url.path.c_str() + 1)) {
resp.status = 404;
return;
}
- resp.body.assign(s_urlmap.at(req.url.path.c_str()+1));
+ resp.body.assign(s_urlmap.at(req.url.path.c_str() + 1));
vector<string> parts;
stringtok(parts, req.url.path, ".");
static const std::unordered_map<std::string, std::string> contentTypeMap = {
- { "html", "text/html" },
- { "css", "text/css" },
- { "js", "application/javascript" },
- { "png", "image/png" },
+ {"html", "text/html"},
+ {"css", "text/css"},
+ {"js", "application/javascript"},
+ {"png", "image/png"},
};
const auto& it = contentTypeMap.find(parts.back());
if (bytes > 0) {
string data = string(buf, bytes);
finished = yarl.feed(data);
- } else {
+ }
+ else {
// read error OR EOF
break;
}
if (apiKey) {
config->apiKey = std::move(apiKey);
- } else {
+ }
+ else {
config->apiKey.reset();
}
}
g_webserverConfig.lock()->acl = std::move(newACL);
}
-void setWebserverCustomHeaders(const boost::optional<std::unordered_map<std::string, std::string> > customHeaders)
+void setWebserverCustomHeaders(const boost::optional<std::unordered_map<std::string, std::string>> customHeaders)
{
g_webserverConfig.lock()->customHeaders = customHeaders;
}
pos += sizeof(drh);
memcpy(reinterpret_cast<char*>(&data.at(pos)), payload.data(), payload.size());
pos += payload.size();
- (void) pos;
+ (void)pos;
dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [](dnsheader& header) {
header.arcount = htons(ntohs(header.arcount) + 1);
#include "dnsdist.hh"
bool addXPF(DNSQuestion& dq, uint16_t optionCode);
-
#include <unistd.h>
#ifdef HAVE_LIBEDIT
-#if defined (__OpenBSD__) || defined(__NetBSD__)
+#if defined(__OpenBSD__) || defined(__NetBSD__)
// If this is not undeffed, __attribute__ wil be redefined by /usr/include/readline/rlstdc.h
#undef __STRICT_ANSI__
#include <readline/readline.h>
std::vector<std::shared_ptr<DNSCryptContext>> g_dnsCryptLocals;
shared_ptr<BPFFilter> g_defaultBPFFilter{nullptr};
-std::vector<std::shared_ptr<DynBPFFilter> > g_dynBPFFilters;
+std::vector<std::shared_ptr<DynBPFFilter>> g_dynBPFFilters;
std::vector<std::unique_ptr<ClientState>> g_frontends;
GlobalStateHolder<pools_t> g_pools;
IDs are assigned by atomic increments of the socket offset.
*/
-GlobalStateHolder<vector<DNSDistRuleAction> > g_ruleactions;
-GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_respruleactions;
-GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_cachehitrespruleactions;
-GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_cacheInsertedRespRuleActions;
-GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_selfansweredrespruleactions;
+GlobalStateHolder<vector<DNSDistRuleAction>> g_ruleactions;
+GlobalStateHolder<vector<DNSDistResponseRuleAction>> g_respruleactions;
+GlobalStateHolder<vector<DNSDistResponseRuleAction>> g_cachehitrespruleactions;
+GlobalStateHolder<vector<DNSDistResponseRuleAction>> g_cacheInsertedRespRuleActions;
+GlobalStateHolder<vector<DNSDistResponseRuleAction>> g_selfansweredrespruleactions;
Rings g_rings;
QueryCount g_qcount;
addCMsgSrcAddr(&msgh, &cbuf, &from, 0);
}
else {
- msgh.msg_control=nullptr;
+ msgh.msg_control = nullptr;
}
return sendmsg(sock, &msgh, flags);
}
static void truncateTC(PacketBuffer& packet, size_t maximumSize, unsigned int qnameWireLength)
{
- try
- {
+ try {
bool hadEDNS = false;
uint16_t payloadSize = 0;
uint16_t z = 0;
hadEDNS = getEDNSUDPPayloadSizeAndZ(reinterpret_cast<const char*>(packet.data()), packet.size(), &payloadSize, &z);
}
- packet.resize(static_cast<uint16_t>(sizeof(dnsheader)+qnameWireLength+DNS_TYPE_SIZE+DNS_CLASS_SIZE));
+ packet.resize(static_cast<uint16_t>(sizeof(dnsheader) + qnameWireLength + DNS_TYPE_SIZE + DNS_CLASS_SIZE));
dnsdist::PacketMangling::editDNSHeaderFromPacket(packet, [](dnsheader& header) {
header.ancount = 0;
header.arcount = 0;
addEDNS(packet, maximumSize, z & EDNS_HEADER_FLAG_DO, payloadSize, 0);
}
}
- catch(...)
- {
+ catch (...) {
++dnsdist::metrics::g_stats.truncFail;
}
}
static void doLatencyStats(dnsdist::Protocol protocol, double udiff)
{
constexpr auto doAvg = [](double& var, double n, double weight) {
- var = (weight -1) * var/weight + n/weight;
+ var = (weight - 1) * var / weight + n / weight;
};
if (protocol == dnsdist::Protocol::DoUDP || protocol == dnsdist::Protocol::DNSCryptUDP) {
dnsdist::metrics::g_stats.latencySum += udiff / 1000;
++dnsdist::metrics::g_stats.latencyCount;
- doAvg(dnsdist::metrics::g_stats.latencyAvg100, udiff, 100);
- doAvg(dnsdist::metrics::g_stats.latencyAvg1000, udiff, 1000);
- doAvg(dnsdist::metrics::g_stats.latencyAvg10000, udiff, 10000);
+ doAvg(dnsdist::metrics::g_stats.latencyAvg100, udiff, 100);
+ doAvg(dnsdist::metrics::g_stats.latencyAvg1000, udiff, 1000);
+ doAvg(dnsdist::metrics::g_stats.latencyAvg10000, udiff, 10000);
doAvg(dnsdist::metrics::g_stats.latencyAvg1000000, udiff, 1000000);
}
else if (protocol == dnsdist::Protocol::DoTCP || protocol == dnsdist::Protocol::DNSCryptTCP) {
- doAvg(dnsdist::metrics::g_stats.latencyTCPAvg100, udiff, 100);
- doAvg(dnsdist::metrics::g_stats.latencyTCPAvg1000, udiff, 1000);
- doAvg(dnsdist::metrics::g_stats.latencyTCPAvg10000, udiff, 10000);
+ doAvg(dnsdist::metrics::g_stats.latencyTCPAvg100, udiff, 100);
+ doAvg(dnsdist::metrics::g_stats.latencyTCPAvg1000, udiff, 1000);
+ doAvg(dnsdist::metrics::g_stats.latencyTCPAvg10000, udiff, 10000);
doAvg(dnsdist::metrics::g_stats.latencyTCPAvg1000000, udiff, 1000000);
}
else if (protocol == dnsdist::Protocol::DoT) {
- doAvg(dnsdist::metrics::g_stats.latencyDoTAvg100, udiff, 100);
- doAvg(dnsdist::metrics::g_stats.latencyDoTAvg1000, udiff, 1000);
- doAvg(dnsdist::metrics::g_stats.latencyDoTAvg10000, udiff, 10000);
+ doAvg(dnsdist::metrics::g_stats.latencyDoTAvg100, udiff, 100);
+ doAvg(dnsdist::metrics::g_stats.latencyDoTAvg1000, udiff, 1000);
+ doAvg(dnsdist::metrics::g_stats.latencyDoTAvg10000, udiff, 10000);
doAvg(dnsdist::metrics::g_stats.latencyDoTAvg1000000, udiff, 1000000);
}
else if (protocol == dnsdist::Protocol::DoH) {
- doAvg(dnsdist::metrics::g_stats.latencyDoHAvg100, udiff, 100);
- doAvg(dnsdist::metrics::g_stats.latencyDoHAvg1000, udiff, 1000);
- doAvg(dnsdist::metrics::g_stats.latencyDoHAvg10000, udiff, 10000);
+ doAvg(dnsdist::metrics::g_stats.latencyDoHAvg100, udiff, 100);
+ doAvg(dnsdist::metrics::g_stats.latencyDoHAvg1000, udiff, 1000);
+ doAvg(dnsdist::metrics::g_stats.latencyDoHAvg10000, udiff, 10000);
doAvg(dnsdist::metrics::g_stats.latencyDoHAvg1000000, udiff, 1000000);
}
else if (protocol == dnsdist::Protocol::DoQ) {
- doAvg(dnsdist::metrics::g_stats.latencyDoQAvg100, udiff, 100);
- doAvg(dnsdist::metrics::g_stats.latencyDoQAvg1000, udiff, 1000);
- doAvg(dnsdist::metrics::g_stats.latencyDoQAvg10000, udiff, 10000);
+ doAvg(dnsdist::metrics::g_stats.latencyDoQAvg100, udiff, 100);
+ doAvg(dnsdist::metrics::g_stats.latencyDoQAvg1000, udiff, 1000);
+ doAvg(dnsdist::metrics::g_stats.latencyDoQAvg10000, udiff, 10000);
doAvg(dnsdist::metrics::g_stats.latencyDoQAvg1000000, udiff, 1000000);
}
else if (protocol == dnsdist::Protocol::DoH3) {
- doAvg(dnsdist::metrics::g_stats.latencyDoH3Avg100, udiff, 100);
- doAvg(dnsdist::metrics::g_stats.latencyDoH3Avg1000, udiff, 1000);
- doAvg(dnsdist::metrics::g_stats.latencyDoH3Avg10000, udiff, 10000);
+ doAvg(dnsdist::metrics::g_stats.latencyDoH3Avg100, udiff, 100);
+ doAvg(dnsdist::metrics::g_stats.latencyDoH3Avg1000, udiff, 1000);
+ doAvg(dnsdist::metrics::g_stats.latencyDoH3Avg10000, udiff, 10000);
doAvg(dnsdist::metrics::g_stats.latencyDoH3Avg1000000, udiff, 1000000);
}
}
void responderThread(std::shared_ptr<DownstreamState> dss)
{
try {
- setThreadName("dnsdist/respond");
- auto localRespRuleActions = g_respruleactions.getLocal();
- auto localCacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal();
- const size_t initialBufferSize = getInitialUDPPacketBufferSize(false);
- /* allocate one more byte so we can detect truncation */
- PacketBuffer response(initialBufferSize + 1);
- uint16_t queryId = 0;
- std::vector<int> sockets;
- sockets.reserve(dss->sockets.size());
-
- for (;;) {
- try {
- if (dss->isStopped()) {
- break;
- }
-
- if (!dss->connected) {
- /* the sockets are not connected yet, likely because we detected a problem,
- tried to reconnect and it failed. We will try to reconnect after the next
- successful health-check (unless reconnectOnUp is false), or when trying
- to send in the UDP listener thread, but until then we simply need to wait. */
- dss->waitUntilConnected();
- continue;
- }
-
- dss->pickSocketsReadyForReceiving(sockets);
-
- /* check a second time here because we might have waited quite a bit
- since the first check */
- if (dss->isStopped()) {
- break;
- }
-
- for (const auto& fd : sockets) {
- /* allocate one more byte so we can detect truncation */
- // NOLINTNEXTLINE(bugprone-use-after-move): resizing a vector has no preconditions so it is valid to do so after moving it
- response.resize(initialBufferSize + 1);
- ssize_t got = recv(fd, response.data(), response.size(), 0);
-
- if (got == 0 && dss->isStopped()) {
+ setThreadName("dnsdist/respond");
+ auto localRespRuleActions = g_respruleactions.getLocal();
+ auto localCacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal();
+ const size_t initialBufferSize = getInitialUDPPacketBufferSize(false);
+ /* allocate one more byte so we can detect truncation */
+ PacketBuffer response(initialBufferSize + 1);
+ uint16_t queryId = 0;
+ std::vector<int> sockets;
+ sockets.reserve(dss->sockets.size());
+
+ for (;;) {
+ try {
+ if (dss->isStopped()) {
break;
}
- if (got < 0 || static_cast<size_t>(got) < sizeof(dnsheader) || static_cast<size_t>(got) == (initialBufferSize + 1)) {
+ if (!dss->connected) {
+ /* the sockets are not connected yet, likely because we detected a problem,
+ tried to reconnect and it failed. We will try to reconnect after the next
+ successful health-check (unless reconnectOnUp is false), or when trying
+ to send in the UDP listener thread, but until then we simply need to wait. */
+ dss->waitUntilConnected();
continue;
}
- response.resize(static_cast<size_t>(got));
- const dnsheader_aligned dnsHeader(response.data());
- queryId = dnsHeader->id;
+ dss->pickSocketsReadyForReceiving(sockets);
- auto ids = dss->getState(queryId);
- if (!ids) {
- continue;
+ /* check a second time here because we might have waited quite a bit
+ since the first check */
+ if (dss->isStopped()) {
+ break;
}
- if (!ids->isXSK() && fd != ids->backendFD) {
- dss->restoreState(queryId, std::move(*ids));
- continue;
- }
+ for (const auto& fd : sockets) {
+ /* allocate one more byte so we can detect truncation */
+ // NOLINTNEXTLINE(bugprone-use-after-move): resizing a vector has no preconditions so it is valid to do so after moving it
+ response.resize(initialBufferSize + 1);
+ ssize_t got = recv(fd, response.data(), response.size(), 0);
- if (processResponderPacket(dss, response, *localRespRuleActions, *localCacheInsertedRespRuleActions, std::move(*ids)) && ids->isXSK() && ids->cs->xskInfo) {
-#ifdef HAVE_XSK
- auto& xskInfo = ids->cs->xskInfo;
- auto xskPacket = xskInfo->getEmptyFrame();
- if (!xskPacket) {
+ if (got == 0 && dss->isStopped()) {
+ break;
+ }
+
+ if (got < 0 || static_cast<size_t>(got) < sizeof(dnsheader) || static_cast<size_t>(got) == (initialBufferSize + 1)) {
+ continue;
+ }
+
+ response.resize(static_cast<size_t>(got));
+ const dnsheader_aligned dnsHeader(response.data());
+ queryId = dnsHeader->id;
+
+ auto ids = dss->getState(queryId);
+ if (!ids) {
continue;
}
- xskPacket->setHeader(ids->xskPacketHeader);
- if (!xskPacket->setPayload(response)) {
- }
- if (ids->delayMsec > 0) {
- xskPacket->addDelay(ids->delayMsec);
+
+ if (!ids->isXSK() && fd != ids->backendFD) {
+ dss->restoreState(queryId, std::move(*ids));
+ continue;
}
- xskPacket->updatePacket();
- xskInfo->pushToSendQueue(*xskPacket);
- xskInfo->notifyXskSocket();
+
+ if (processResponderPacket(dss, response, *localRespRuleActions, *localCacheInsertedRespRuleActions, std::move(*ids)) && ids->isXSK() && ids->cs->xskInfo) {
+#ifdef HAVE_XSK
+ auto& xskInfo = ids->cs->xskInfo;
+ auto xskPacket = xskInfo->getEmptyFrame();
+ if (!xskPacket) {
+ continue;
+ }
+ xskPacket->setHeader(ids->xskPacketHeader);
+ if (!xskPacket->setPayload(response)) {
+ }
+ if (ids->delayMsec > 0) {
+ xskPacket->addDelay(ids->delayMsec);
+ }
+ xskPacket->updatePacket();
+ xskInfo->pushToSendQueue(*xskPacket);
+ xskInfo->notifyXskSocket();
#endif /* HAVE_XSK */
+ }
}
}
- }
- catch (const std::exception& e) {
- vinfolog("Got an error in UDP responder thread while parsing a response from %s, id %d: %s", dss->d_config.remote.toStringWithPort(), queryId, e.what());
+ catch (const std::exception& e) {
+ vinfolog("Got an error in UDP responder thread while parsing a response from %s, id %d: %s", dss->d_config.remote.toStringWithPort(), queryId, e.what());
+ }
}
}
-}
-catch (const std::exception& e) {
- errlog("UDP responder thread died because of exception: %s", e.what());
-}
-catch (const PDNSException& e) {
- errlog("UDP responder thread died because of PowerDNS exception: %s", e.reason);
-}
-catch (...) {
- errlog("UDP responder thread died because of an exception: %s", "unknown");
-}
+ catch (const std::exception& e) {
+ errlog("UDP responder thread died because of exception: %s", e.what());
+ }
+ catch (const PDNSException& e) {
+ errlog("UDP responder thread died because of PowerDNS exception: %s", e.reason);
+ }
+ catch (...) {
+ errlog("UDP responder thread died because of an exception: %s", "unknown");
+ }
}
LockGuarded<LuaContext> g_lua{LuaContext()};
ComboAddress g_serverControl{"127.0.0.1:5199"};
-
static void spoofResponseFromString(DNSQuestion& dq, const string& spoofContent, bool raw)
{
string result;
SpoofAction tempSpoofAction({spoofAddr});
tempSpoofAction(&dq, &result);
}
- catch(const PDNSException &e) {
+ catch (const PDNSException& e) {
DNSName cname(spoofContent);
SpoofAction tempSpoofAction(cname); // CNAME then
tempSpoofAction(&dq, &result);
}
- } else {
+ }
+ else {
std::vector<ComboAddress> cas;
for (const auto& addr : addrs) {
try {
return false;
}
-
static bool applyRulesToQuery(LocalHolders& holders, DNSQuestion& dq, const struct timespec& now)
{
if (g_rings.shouldRecordQueries()) {
bool countQuery{true};
if (g_qcount.filter) {
auto lock = g_lua.lock();
- std::tie (countQuery, qname) = g_qcount.filter(&dq);
+ std::tie(countQuery, qname) = g_qcount.filter(&dq);
}
if (countQuery) {
struct iovec iov;
cmsgbuf_aligned cbuf;
ComboAddress remote(ss->d_config.remote);
- fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), const_cast<char*>(reinterpret_cast<const char *>(request.data())), request.size(), &remote);
+ fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), const_cast<char*>(reinterpret_cast<const char*>(request.data())), request.size(), &remote);
addCMsgSrcAddr(&msgh, &cbuf, &ss->d_config.sourceAddr, ss->d_config.sourceItf);
result = sendmsg(sd, &msgh, 0);
}
bool checkQueryHeaders(const struct dnsheader& dnsHeader, ClientState& clientState)
{
- if (dnsHeader.qr) { // don't respond to responses
+ if (dnsHeader.qr) { // don't respond to responses
++dnsdist::metrics::g_stats.nonCompliantQueries;
++clientState.nonCompliantQueries;
return false;
static void queueResponse(const ClientState& cs, const PacketBuffer& response, const ComboAddress& dest, const ComboAddress& remote, struct mmsghdr& outMsg, struct iovec* iov, cmsgbuf_aligned* cbuf)
{
outMsg.msg_len = 0;
- fillMSGHdr(&outMsg.msg_hdr, iov, nullptr, 0, const_cast<char*>(reinterpret_cast<const char *>(&response.at(0))), response.size(), const_cast<ComboAddress*>(&remote));
+ fillMSGHdr(&outMsg.msg_hdr, iov, nullptr, 0, const_cast<char*>(reinterpret_cast<const char*>(&response.at(0))), response.size(), const_cast<ComboAddress*>(&remote));
if (dest.sin4.sin_family == 0) {
outMsg.msg_hdr.msg_control = nullptr;
yet, as we will do a second-lookup */
if (dq.ids.packetCache->get(dq, dq.getHeader()->id, &dq.ids.cacheKey, dq.ids.subnet, dq.ids.dnssecOK, forwardedOverUDP, allowExpired, false, true, dq.ids.protocol != dnsdist::Protocol::DoH || forwardedOverUDP)) {
- dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [flags=dq.ids.origFlags](dnsheader& header) {
+ dnsdist::PacketMangling::editDNSHeaderFromPacket(dq.getMutableData(), [flags = dq.ids.origFlags](dnsheader& header) {
restoreFlags(&header, flags);
return true;
});
selectedBackend->incQueriesCount();
return ProcessQueryResult::PassToBackend;
}
- catch (const std::exception& e){
+ catch (const std::exception& e) {
vinfolog("Got an error while parsing a %s query (after applying rules) from %s, id %d: %s", (dq.overTCP() ? "TCP" : "UDP"), dq.ids.origRemote.toStringWithPort(), queryId, e.what());
}
return ProcessQueryResult::Drop;
class UDPCrossProtocolQuery : public CrossProtocolQuery
{
public:
- UDPCrossProtocolQuery(PacketBuffer&& buffer_, InternalQueryState&& ids_, std::shared_ptr<DownstreamState> ds): CrossProtocolQuery(InternalQuery(std::move(buffer_), std::move(ids_)), ds)
+ UDPCrossProtocolQuery(PacketBuffer&& buffer_, InternalQueryState&& ids_, std::shared_ptr<DownstreamState> ds) :
+ CrossProtocolQuery(InternalQuery(std::move(buffer_), std::move(ids_)), ds)
{
auto& ids = query.d_idstate;
const auto& buffer = query.d_buffer;
{
return s_sender;
}
+
private:
static std::shared_ptr<UDPTCPCrossQuerySender> s_sender;
};
return processQueryAfterRules(dq, holders, selectedBackend);
}
- catch (const std::exception& e){
+ catch (const std::exception& e) {
vinfolog("Got an error while parsing a %s query from %s, id %d: %s", (dq.overTCP() ? "TCP" : "UDP"), dq.ids.origRemote.toStringWithPort(), queryId, e.what());
}
return ProcessQueryResult::Drop;
assignOutgoingUDPQueryToBackend(ss, dh->id, dq, query);
}
- catch(const std::exception& e){
+ catch (const std::exception& e) {
vinfolog("Got an error in UDP question thread while parsing a query from %s, id %d: %s", ids.origRemote.toStringWithPort(), queryId, e.what());
}
}
}
/* go now */
- for(;;) {
+ for (;;) {
/* reset the IO vector, since it's also used to send the vector of responses
to avoid having to copy the data around */
vinfolog("Error sending responses with sendmmsg() (%d on %u): %s", sent, msgsToSend, stringerror());
}
}
-
}
}
#endif /* defined(HAVE_RECVMMSG) && defined(HAVE_SENDMMSG) && defined(MSG_WAITFORONE) */
}
}
}
- catch (const std::exception &e) {
+ catch (const std::exception& e) {
errlog("UDP client thread died because of exception: %s", e.what());
}
- catch (const PDNSException &e) {
+ catch (const PDNSException& e) {
errlog("UDP client thread died because of PowerDNS exception: %s", e.reason);
}
catch (...) {
{
auto lua = g_lua.lock();
try {
- auto maintenanceCallback = lua->readVariable<boost::optional<std::function<void()> > >("maintenance");
+ auto maintenanceCallback = lua->readVariable<boost::optional<std::function<void()>>>("maintenance");
if (maintenanceCallback) {
(*maintenanceCallback)();
}
dnsdist::lua::hooks::runMaintenanceHooks(*lua);
secondsToWaitLog = 0;
}
- catch (const std::exception &e) {
+ catch (const std::exception& e) {
if (secondsToWaitLog <= 0) {
warnlog("Error during execution of maintenance function(s): %s", e.what());
secondsToWaitLog = 61;
continue;
}
const auto& packetCache = pair.first;
- size_t upTo = (packetCache->getMaxEntries()* (100 - g_cacheCleaningPercentage)) / 100;
+ size_t upTo = (packetCache->getMaxEntries() * (100 - g_cacheCleaningPercentage)) / 100;
packetCache->purgeExpired(upTo, now);
}
counter = 0;
try {
doSecPoll(g_secPollSuffix);
}
- catch(...) {
+ catch (...) {
}
// coverity[store_truncates_time_t]
sleep(g_secPollInterval);
setThreadName("dnsdist/healthC");
constexpr int intervalUsec = 1000 * 1000;
- struct timeval lastRound{
+ struct timeval lastRound
+ {
.tv_sec = 0,
.tv_usec = 0
};
static void setupLocalSocket(ClientState& clientState, const ComboAddress& addr, int& socket, bool tcp, bool warn)
{
- (void) warn;
+ (void)warn;
socket = SSocket(addr.sin4.sin_family, !tcp ? SOCK_DGRAM : SOCK_STREAM, 0);
if (tcp) {
if (!tcp && IsAnyAddress(addr)) {
int one = 1;
- (void) setsockopt(socket, IPPROTO_IP, GEN_IP_PKTINFO, &one, sizeof(one)); // linux supports this, so why not - might fail on other systems
+ (void)setsockopt(socket, IPPROTO_IP, GEN_IP_PKTINFO, &one, sizeof(one)); // linux supports this, so why not - might fail on other systems
#ifdef IPV6_RECVPKTINFO
- if (addr.isIPv6() && setsockopt(socket, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)) < 0 &&
- !g_warned_ipv6_recvpktinfo) {
+ if (addr.isIPv6() && setsockopt(socket, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)) < 0 && !g_warned_ipv6_recvpktinfo) {
warnlog("Warning: IPV6_RECVPKTINFO setsockopt failed: %s", stringerror());
g_warned_ipv6_recvpktinfo = true;
}
catch (const std::exception& e) {
warnlog(e.what());
}
- } else {
+ }
+ else {
try {
auto result = raiseSocketSendBufferToMax(socket);
if (result > 0) {
infolog("Raised send buffer to %u for local address '%s'", result, addr.toStringWithPort());
}
- } catch (const std::exception& e) {
+ }
+ catch (const std::exception& e) {
warnlog(e.what());
}
}
catch (const std::exception& e) {
warnlog(e.what());
}
- } else {
+ }
+ else {
try {
auto result = raiseSocketReceiveBufferToMax(socket);
if (result > 0) {
infolog("Raised receive buffer to %u for local address '%s'", result, addr.toStringWithPort());
}
- } catch (const std::exception& e) {
+ }
+ catch (const std::exception& e) {
warnlog(e.what());
}
}
else {
infolog("Listening on %s", addr.toStringWithPort());
}
- } else {
+ }
+ else {
if (clientState.doqFrontend != nullptr) {
infolog("Listening on %s for DoQ", addr.toStringWithPort());
- } else if (clientState.doh3Frontend != nullptr) {
+ }
+ else if (clientState.doh3Frontend != nullptr) {
infolog("Listening on %s for DoH3", addr.toStringWithPort());
}
#ifdef HAVE_XSK
/* skip some warnings if there is an identical UDP context */
bool warn = !cstate->tcp || cstate->tlsFrontend != nullptr || cstate->dohFrontend != nullptr;
int& descriptor = !cstate->tcp ? cstate->udpFD : cstate->tcpFD;
- (void) warn;
+ (void)warn;
setupLocalSocket(*cstate, cstate->local, descriptor, cstate->tcp, warn);
static void usage()
{
- cout<<endl;
- cout<<"Syntax: dnsdist [-C,--config file] [-c,--client [IP[:PORT]]]\n";
- cout<<"[-e,--execute cmd] [-h,--help] [-l,--local addr]\n";
- cout<<"[-v,--verbose] [--check-config] [--version]\n";
- cout<<"\n";
- cout<<"-a,--acl netmask Add this netmask to the ACL\n";
- cout<<"-C,--config file Load configuration from 'file'\n";
- cout<<"-c,--client Operate as a client, connect to dnsdist. This reads\n";
- cout<<" controlSocket from your configuration file, but also\n";
- cout<<" accepts an IP:PORT argument\n";
+ cout << endl;
+ cout << "Syntax: dnsdist [-C,--config file] [-c,--client [IP[:PORT]]]\n";
+ cout << "[-e,--execute cmd] [-h,--help] [-l,--local addr]\n";
+ cout << "[-v,--verbose] [--check-config] [--version]\n";
+ cout << "\n";
+ cout << "-a,--acl netmask Add this netmask to the ACL\n";
+ cout << "-C,--config file Load configuration from 'file'\n";
+ cout << "-c,--client Operate as a client, connect to dnsdist. This reads\n";
+ cout << " controlSocket from your configuration file, but also\n";
+ cout << " accepts an IP:PORT argument\n";
#if defined(HAVE_LIBSODIUM) || defined(HAVE_LIBCRYPTO)
- cout<<"-k,--setkey KEY Use KEY for encrypted communication to dnsdist. This\n";
- cout<<" is similar to setting setKey in the configuration file.\n";
- cout<<" NOTE: this will leak this key in your shell's history\n";
- cout<<" and in the systems running process list.\n";
+ cout << "-k,--setkey KEY Use KEY for encrypted communication to dnsdist. This\n";
+ cout << " is similar to setting setKey in the configuration file.\n";
+ cout << " NOTE: this will leak this key in your shell's history\n";
+ cout << " and in the systems running process list.\n";
#endif
- cout<<"--check-config Validate the configuration file and exit. The exit-code\n";
- cout<<" reflects the validation, 0 is OK, 1 means an error.\n";
- cout<<" Any errors are printed as well.\n";
- cout<<"-e,--execute cmd Connect to dnsdist and execute 'cmd'\n";
- cout<<"-g,--gid gid Change the process group ID after binding sockets\n";
- cout<<"-h,--help Display this helpful message\n";
- cout<<"-l,--local address Listen on this local address\n";
- cout<<"--supervised Don't open a console, I'm supervised\n";
- cout<<" (use with e.g. systemd and daemontools)\n";
- cout<<"--disable-syslog Don't log to syslog, only to stdout\n";
- cout<<" (use with e.g. systemd)\n";
- cout<<"--log-timestamps Prepend timestamps to messages logged to stdout.\n";
- cout<<"-u,--uid uid Change the process user ID after binding sockets\n";
- cout<<"-v,--verbose Enable verbose mode\n";
- cout<<"-V,--version Show dnsdist version information and exit\n";
+ cout << "--check-config Validate the configuration file and exit. The exit-code\n";
+ cout << " reflects the validation, 0 is OK, 1 means an error.\n";
+ cout << " Any errors are printed as well.\n";
+ cout << "-e,--execute cmd Connect to dnsdist and execute 'cmd'\n";
+ cout << "-g,--gid gid Change the process group ID after binding sockets\n";
+ cout << "-h,--help Display this helpful message\n";
+ cout << "-l,--local address Listen on this local address\n";
+ cout << "--supervised Don't open a console, I'm supervised\n";
+ cout << " (use with e.g. systemd and daemontools)\n";
+ cout << "--disable-syslog Don't log to syslog, only to stdout\n";
+ cout << " (use with e.g. systemd)\n";
+ cout << "--log-timestamps Prepend timestamps to messages logged to stdout.\n";
+ cout << "-u,--uid uid Change the process user ID after binding sockets\n";
+ cout << "-v,--verbose Enable verbose mode\n";
+ cout << "-V,--version Show dnsdist version information and exit\n";
}
#ifdef COVERAGE
if (dnsdist::logging::LoggingConfiguration::getSyslog()) {
syslog(LOG_INFO, "Exiting on user request");
}
- std::cout<<"Exiting on user request"<<std::endl;
+ std::cout << "Exiting on user request" << std::endl;
#endif /* __SANITIZE_THREAD__ */
_exit(EXIT_SUCCESS);
static void reportFeatures()
{
#ifdef LUAJIT_VERSION
- cout<<"dnsdist "<<VERSION<<" ("<<LUA_RELEASE<<" ["<<LUAJIT_VERSION<<"])"<<endl;
+ cout << "dnsdist " << VERSION << " (" << LUA_RELEASE << " [" << LUAJIT_VERSION << "])" << endl;
#else
- cout<<"dnsdist "<<VERSION<<" ("<<LUA_RELEASE<<")"<<endl;
+ cout << "dnsdist " << VERSION << " (" << LUA_RELEASE << ")" << endl;
#endif
- cout<<"Enabled features: ";
+ cout << "Enabled features: ";
#ifdef HAVE_XSK
- cout<<"AF_XDP ";
+ cout << "AF_XDP ";
#endif
#ifdef HAVE_CDB
- cout<<"cdb ";
+ cout << "cdb ";
#endif
#ifdef HAVE_DNS_OVER_QUIC
- cout<<"dns-over-quic ";
+ cout << "dns-over-quic ";
#endif
#ifdef HAVE_DNS_OVER_HTTP3
- cout<<"dns-over-http3 ";
+ cout << "dns-over-http3 ";
#endif
#ifdef HAVE_DNS_OVER_TLS
- cout<<"dns-over-tls(";
+ cout << "dns-over-tls(";
#ifdef HAVE_GNUTLS
- cout<<"gnutls";
+ cout << "gnutls";
#ifdef HAVE_LIBSSL
- cout<<" ";
+ cout << " ";
#endif
#endif /* HAVE_GNUTLS */
#ifdef HAVE_LIBSSL
- cout<<"openssl";
+ cout << "openssl";
#endif
- cout<<") ";
+ cout << ") ";
#endif /* HAVE_DNS_OVER_TLS */
#ifdef HAVE_DNS_OVER_HTTPS
- cout<<"dns-over-https(";
+ cout << "dns-over-https(";
#ifdef HAVE_LIBH2OEVLOOP
- cout<<"h2o";
+ cout << "h2o";
#endif /* HAVE_LIBH2OEVLOOP */
#if defined(HAVE_LIBH2OEVLOOP) && defined(HAVE_NGHTTP2)
- cout<<" ";
+ cout << " ";
#endif /* defined(HAVE_LIBH2OEVLOOP) && defined(HAVE_NGHTTP2) */
#ifdef HAVE_NGHTTP2
- cout<<"nghttp2";
+ cout << "nghttp2";
#endif /* HAVE_NGHTTP2 */
- cout<<") ";
+ cout << ") ";
#endif /* HAVE_DNS_OVER_HTTPS */
#ifdef HAVE_DNSCRYPT
- cout<<"dnscrypt ";
+ cout << "dnscrypt ";
#endif
#ifdef HAVE_EBPF
- cout<<"ebpf ";
+ cout << "ebpf ";
#endif
#ifdef HAVE_FSTRM
- cout<<"fstrm ";
+ cout << "fstrm ";
#endif
#ifdef HAVE_IPCIPHER
- cout<<"ipcipher ";
+ cout << "ipcipher ";
#endif
#ifdef HAVE_LIBEDIT
- cout<<"libedit ";
+ cout << "libedit ";
#endif
#ifdef HAVE_LIBSODIUM
- cout<<"libsodium ";
+ cout << "libsodium ";
#endif
#ifdef HAVE_LMDB
- cout<<"lmdb ";
+ cout << "lmdb ";
#endif
#ifndef DISABLE_PROTOBUF
- cout<<"protobuf ";
+ cout << "protobuf ";
#endif
#ifdef HAVE_RE2
- cout<<"re2 ";
+ cout << "re2 ";
#endif
#ifndef DISABLE_RECVMMSG
#if defined(HAVE_RECVMMSG) && defined(HAVE_SENDMMSG) && defined(MSG_WAITFORONE)
- cout<<"recvmmsg/sendmmsg ";
+ cout << "recvmmsg/sendmmsg ";
#endif
#endif /* DISABLE_RECVMMSG */
#ifdef HAVE_NET_SNMP
- cout<<"snmp ";
+ cout << "snmp ";
#endif
#ifdef HAVE_SYSTEMD
- cout<<"systemd";
+ cout << "systemd";
#endif
- cout<<endl;
+ cout << endl;
}
static void parseParameters(int argc, char** argv, ComboAddress& clientAddress)
{
- const std::array<struct option,16> longopts{{
- {"acl", required_argument, nullptr, 'a'},
- {"check-config", no_argument, nullptr, 1},
- {"client", no_argument, nullptr, 'c'},
- {"config", required_argument, nullptr, 'C'},
- {"disable-syslog", no_argument, nullptr, 2},
- {"execute", required_argument, nullptr, 'e'},
- {"gid", required_argument, nullptr, 'g'},
- {"help", no_argument, nullptr, 'h'},
- {"local", required_argument, nullptr, 'l'},
- {"log-timestamps", no_argument, nullptr, 4},
- {"setkey", required_argument, nullptr, 'k'},
- {"supervised", no_argument, nullptr, 3},
- {"uid", required_argument, nullptr, 'u'},
- {"verbose", no_argument, nullptr, 'v'},
- {"version", no_argument, nullptr, 'V'},
- {nullptr, 0, nullptr, 0}
- }};
+ const std::array<struct option, 16> longopts{{{"acl", required_argument, nullptr, 'a'},
+ {"check-config", no_argument, nullptr, 1},
+ {"client", no_argument, nullptr, 'c'},
+ {"config", required_argument, nullptr, 'C'},
+ {"disable-syslog", no_argument, nullptr, 2},
+ {"execute", required_argument, nullptr, 'e'},
+ {"gid", required_argument, nullptr, 'g'},
+ {"help", no_argument, nullptr, 'h'},
+ {"local", required_argument, nullptr, 'l'},
+ {"log-timestamps", no_argument, nullptr, 4},
+ {"setkey", required_argument, nullptr, 'k'},
+ {"supervised", no_argument, nullptr, 3},
+ {"uid", required_argument, nullptr, 'u'},
+ {"verbose", no_argument, nullptr, 'v'},
+ {"version", no_argument, nullptr, 'V'},
+ {nullptr, 0, nullptr, 0}}};
int longindex = 0;
string optstring;
while (true) {
g_cmdLine.gid = optarg;
break;
case 'h':
- cout<<"dnsdist "<<VERSION<<endl;
+ cout << "dnsdist " << VERSION << endl;
usage();
- cout<<"\n";
+ cout << "\n";
// NOLINTNEXTLINE(concurrency-mt-unsafe): only one thread at this point
exit(EXIT_SUCCESS);
break;
case 'k':
#if defined HAVE_LIBSODIUM || defined(HAVE_LIBCRYPTO)
if (B64Decode(string(optarg), g_consoleKey) < 0) {
- cerr<<"Unable to decode key '"<<optarg<<"'."<<endl;
+ cerr << "Unable to decode key '" << optarg << "'." << endl;
// NOLINTNEXTLINE(concurrency-mt-unsafe): only one thread at this point
exit(EXIT_FAILURE);
}
#else
- cerr<<"dnsdist has been built without libsodium or libcrypto, -k/--setkey is unsupported."<<endl;
+ cerr << "dnsdist has been built without libsodium or libcrypto, -k/--setkey is unsupported." << endl;
// NOLINTNEXTLINE(concurrency-mt-unsafe): only one thread at this point
exit(EXIT_FAILURE);
#endif
exit(EXIT_SUCCESS);
break;
case '?':
- //getopt_long printed an error message.
+ // getopt_long printed an error message.
usage();
// NOLINTNEXTLINE(concurrency-mt-unsafe): only one thread at this point
exit(EXIT_FAILURE);
for (const auto* ptr = argv; *ptr != nullptr; ++ptr) {
if (g_cmdLine.beClient) {
clientAddress = ComboAddress(*ptr, 5199);
- } else {
+ }
+ else {
g_cmdLine.remotes.emplace_back(*ptr);
}
}
bool precompute = false;
if (g_policy.getLocal()->getName() == "chashed") {
precompute = true;
- } else {
- for (const auto& entry: pools) {
+ }
+ else {
+ for (const auto& entry : pools) {
if (entry.second->policy != nullptr && entry.second->policy->getName() == "chashed") {
precompute = true;
- break ;
+ break;
}
}
}
vinfolog("Pre-computing hashes for consistent hash load-balancing policy");
// pre compute hashes
auto backends = g_dstates.getLocal();
- for (const auto& backend: *backends) {
+ for (const auto& backend : *backends) {
if (backend->d_config.d_weight < 100) {
vinfolog("Warning, the backend '%s' has a very low weight (%d), which will not yield a good distribution of queries with the 'chashed' policy. Please consider raising it to at least '100'.", backend->getName(), backend->d_config.d_weight);
}
}
bool retainedCapabilities = true;
- if (!g_capabilitiesToRetain.empty() &&
- (getegid() != newgid || geteuid() != newuid)) {
+ if (!g_capabilitiesToRetain.empty() && (getegid() != newgid || geteuid() != newuid)) {
retainedCapabilities = keepCapabilitiesAfterSwitchingIDs();
}
static void initFrontends()
{
if (!g_cmdLine.locals.empty()) {
- for (auto it = g_frontends.begin(); it != g_frontends.end(); ) {
+ for (auto it = g_frontends.begin(); it != g_frontends.end();) {
/* DoH, DoT and DNSCrypt frontends are separate */
if ((*it)->dohFrontend == nullptr && (*it)->tlsFrontend == nullptr && (*it)->dnscryptCtx == nullptr && (*it)->doqFrontend == nullptr && (*it)->doh3Frontend == nullptr) {
it = g_frontends.erase(it);
if (g_frontends.empty()) {
/* UDP */
- g_frontends.emplace_back(std::make_unique<ClientState>(ComboAddress("127.0.0.1", 53), false, false, 0, "", std::set<int>{}, true));
+ g_frontends.emplace_back(std::make_unique<ClientState>(ComboAddress("127.0.0.1", 53), false, false, 0, "", std::set<int>{}, true));
/* TCP */
- g_frontends.emplace_back(std::make_unique<ClientState>(ComboAddress("127.0.0.1", 53), true, false, 0, "", std::set<int>{}, true));
+ g_frontends.emplace_back(std::make_unique<ClientState>(ComboAddress("127.0.0.1", 53), true, false, 0, "", std::set<int>{}, true));
}
}
dotThreadHandle.detach();
#endif /* HAVE_LIBH2OEVLOOP */
#endif /* HAVE_DNS_OVER_HTTPS */
- continue;
- }
- if (clientState->doqFrontend != nullptr) {
+ continue;
+ }
+ if (clientState->doqFrontend != nullptr) {
#ifdef HAVE_DNS_OVER_QUIC
- std::thread doqThreadHandle(doqThread, clientState.get());
- if (!clientState->cpus.empty()) {
- mapThreadToCPUList(doqThreadHandle.native_handle(), clientState->cpus);
- }
- doqThreadHandle.detach();
-#endif /* HAVE_DNS_OVER_QUIC */
- continue;
+ std::thread doqThreadHandle(doqThread, clientState.get());
+ if (!clientState->cpus.empty()) {
+ mapThreadToCPUList(doqThreadHandle.native_handle(), clientState->cpus);
}
- if (clientState->doh3Frontend != nullptr) {
+ doqThreadHandle.detach();
+#endif /* HAVE_DNS_OVER_QUIC */
+ continue;
+ }
+ if (clientState->doh3Frontend != nullptr) {
#ifdef HAVE_DNS_OVER_HTTP3
- std::thread doh3ThreadHandle(doh3Thread, clientState.get());
- if (!clientState->cpus.empty()) {
- mapThreadToCPUList(doh3ThreadHandle.native_handle(), clientState->cpus);
- }
- doh3ThreadHandle.detach();
-#endif /* HAVE_DNS_OVER_HTTP3 */
- continue;
+ std::thread doh3ThreadHandle(doh3Thread, clientState.get());
+ if (!clientState->cpus.empty()) {
+ mapThreadToCPUList(doh3ThreadHandle.native_handle(), clientState->cpus);
}
- if (clientState->udpFD >= 0) {
+ doh3ThreadHandle.detach();
+#endif /* HAVE_DNS_OVER_HTTP3 */
+ continue;
+ }
+ if (clientState->udpFD >= 0) {
#ifdef USE_SINGLE_ACCEPTOR_THREAD
- udpStates.push_back(clientState.get());
+ udpStates.push_back(clientState.get());
#else /* USE_SINGLE_ACCEPTOR_THREAD */
- std::thread udpClientThreadHandle(udpClientThread, std::vector<ClientState*>{ clientState.get() });
- if (!clientState->cpus.empty()) {
- mapThreadToCPUList(udpClientThreadHandle.native_handle(), clientState->cpus);
- }
- udpClientThreadHandle.detach();
-#endif /* USE_SINGLE_ACCEPTOR_THREAD */
+ std::thread udpClientThreadHandle(udpClientThread, std::vector<ClientState*>{clientState.get()});
+ if (!clientState->cpus.empty()) {
+ mapThreadToCPUList(udpClientThreadHandle.native_handle(), clientState->cpus);
}
- else if (clientState->tcpFD >= 0) {
+ udpClientThreadHandle.detach();
+#endif /* USE_SINGLE_ACCEPTOR_THREAD */
+ }
+ else if (clientState->tcpFD >= 0) {
#ifdef USE_SINGLE_ACCEPTOR_THREAD
- tcpStates.push_back(clientState.get());
+ tcpStates.push_back(clientState.get());
#else /* USE_SINGLE_ACCEPTOR_THREAD */
- std::thread tcpAcceptorThreadHandle(tcpAcceptorThread, std::vector<ClientState*>{clientState.get() });
- if (!clientState->cpus.empty()) {
- mapThreadToCPUList(tcpAcceptorThreadHandle.native_handle(), clientState->cpus);
- }
- tcpAcceptorThreadHandle.detach();
-#endif /* USE_SINGLE_ACCEPTOR_THREAD */
+ std::thread tcpAcceptorThreadHandle(tcpAcceptorThread, std::vector<ClientState*>{clientState.get()});
+ if (!clientState->cpus.empty()) {
+ mapThreadToCPUList(tcpAcceptorThreadHandle.native_handle(), clientState->cpus);
}
+ tcpAcceptorThreadHandle.detach();
+#endif /* USE_SINGLE_ACCEPTOR_THREAD */
}
+ }
#ifdef USE_SINGLE_ACCEPTOR_THREAD
- if (!udpStates.empty()) {
- std::thread udpThreadHandle(udpClientThread, udpStates);
- udpThreadHandle.detach();
- }
- if (!tcpStates.empty()) {
- g_tcpclientthreads = std::make_unique<TCPClientCollection>(1, tcpStates);
- }
+ if (!udpStates.empty()) {
+ std::thread udpThreadHandle(udpClientThread, udpStates);
+ udpThreadHandle.detach();
+ }
+ if (!tcpStates.empty()) {
+ g_tcpclientthreads = std::make_unique<TCPClientCollection>(1, tcpStates);
+ }
#endif /* USE_SINGLE_ACCEPTOR_THREAD */
}
}
signal(SIGCHLD, SIG_IGN);
signal(SIGTERM, sigTermHandler);
- openlog("dnsdist", LOG_PID|LOG_NDELAY, LOG_DAEMON);
+ openlog("dnsdist", LOG_PID | LOG_NDELAY, LOG_DAEMON);
#ifdef HAVE_LIBSODIUM
if (sodium_init() == -1) {
- cerr<<"Unable to initialize crypto library"<<endl;
+ cerr << "Unable to initialize crypto library" << endl;
// NOLINTNEXTLINE(concurrency-mt-unsafe): only on thread at this point
exit(EXIT_FAILURE);
}
#endif /* HAVE_XSK */
ComboAddress clientAddress = ComboAddress();
- g_cmdLine.config=SYSCONFDIR "/dnsdist.conf";
+ g_cmdLine.config = SYSCONFDIR "/dnsdist.conf";
parseParameters(argc, argv, clientAddress);
}
auto consoleACL = g_consoleACL.getCopy();
- for (const auto& mask : { "127.0.0.1/8", "::1/128" }) {
+ for (const auto& mask : {"127.0.0.1/8", "::1/128"}) {
consoleACL.addMask(mask);
}
g_consoleACL.setState(consoleACL);
}
#endif /* DISABLE_SECPOLL */
- if(g_cmdLine.beSupervised) {
+ if (g_cmdLine.beSupervised) {
#ifdef HAVE_SYSTEMD
sd_notify(0, "READY=1");
#endif
try {
errlog("Fatal Lua error: %s", e.what());
std::rethrow_if_nested(e);
- } catch(const std::exception& ne) {
+ }
+ catch (const std::exception& ne) {
errlog("Details: %s", ne.what());
}
- catch (const PDNSException &ae)
- {
+ catch (const PDNSException& ae) {
errlog("Fatal pdns error: %s", ae.reason);
}
#ifdef COVERAGE
_exit(EXIT_FAILURE);
#endif
}
- catch (const std::exception &e)
- {
+ catch (const std::exception& e) {
errlog("Fatal error: %s", e.what());
#ifdef COVERAGE
cleanupLuaObjects();
_exit(EXIT_FAILURE);
#endif
}
- catch (const PDNSException &ae)
- {
+ catch (const PDNSException& ae) {
errlog("Fatal pdns error: %s", ae.reason);
#ifdef COVERAGE
cleanupLuaObjects();
struct DNSQuestion
{
- DNSQuestion(InternalQueryState& ids_, PacketBuffer& data_):
- data(data_), ids(ids_), ecsPrefixLength(ids.origRemote.sin4.sin_family == AF_INET ? g_ECSSourcePrefixV4 : g_ECSSourcePrefixV6), ecsOverride(g_ECSOverride) {
+ DNSQuestion(InternalQueryState& ids_, PacketBuffer& data_) :
+ data(data_), ids(ids_), ecsPrefixLength(ids.origRemote.sin4.sin_family == AF_INET ? g_ECSSourcePrefixV4 : g_ECSSourcePrefixV6), ecsOverride(g_ECSOverride)
+ {
}
DNSQuestion(const DNSQuestion&) = delete;
DNSQuestion& operator=(const DNSQuestion&) = delete;
return !(ids.protocol == dnsdist::Protocol::DoUDP || ids.protocol == dnsdist::Protocol::DNSCryptUDP);
}
- void setTag(std::string&& key, std::string&& value) {
+ void setTag(std::string&& key, std::string&& value)
+ {
if (!ids.qTag) {
ids.qTag = std::make_unique<QTag>();
}
ids.qTag->insert_or_assign(std::move(key), std::move(value));
}
- void setTag(const std::string& key, const std::string& value) {
+ void setTag(const std::string& key, const std::string& value)
+ {
if (!ids.qTag) {
ids.qTag = std::make_unique<QTag>();
}
ids.qTag->insert_or_assign(key, value);
}
- void setTag(const std::string& key, std::string&& value) {
+ void setTag(const std::string& key, std::string&& value)
+ {
if (!ids.qTag) {
ids.qTag = std::make_unique<QTag>();
}
struct DNSResponse : DNSQuestion
{
- DNSResponse(InternalQueryState& ids_, PacketBuffer& data_, const std::shared_ptr<DownstreamState>& downstream):
- DNSQuestion(ids_, data_), d_downstream(downstream) { }
+ DNSResponse(InternalQueryState& ids_, PacketBuffer& data_, const std::shared_ptr<DownstreamState>& downstream) :
+ DNSQuestion(ids_, data_), d_downstream(downstream) {}
DNSResponse(const DNSResponse&) = delete;
DNSResponse& operator=(const DNSResponse&) = delete;
DNSResponse(DNSResponse&&) = default;
class DNSAction
{
public:
- enum class Action : uint8_t { Drop, Nxdomain, Refused, Spoof, Allow, HeaderModify, Pool, Delay, Truncate, ServFail, None, NoOp, NoRecurse, SpoofRaw, SpoofPacket };
+ enum class Action : uint8_t
+ {
+ Drop,
+ Nxdomain,
+ Refused,
+ Spoof,
+ Allow,
+ HeaderModify,
+ Pool,
+ Delay,
+ Truncate,
+ ServFail,
+ None,
+ NoOp,
+ NoRecurse,
+ SpoofRaw,
+ SpoofPacket
+ };
static std::string typeToString(const Action& action)
{
- switch(action) {
+ switch (action) {
case Action::Drop:
return "Drop";
case Action::Nxdomain:
return "Unknown";
}
- virtual Action operator()(DNSQuestion*, string* ruleresult) const =0;
+ virtual Action operator()(DNSQuestion*, string* ruleresult) const = 0;
virtual ~DNSAction()
{
}
class DNSResponseAction
{
public:
- enum class Action : uint8_t { Allow, Delay, Drop, HeaderModify, ServFail, Truncate, None };
- virtual Action operator()(DNSResponse*, string* ruleresult) const =0;
+ enum class Action : uint8_t
+ {
+ Allow,
+ Delay,
+ Drop,
+ HeaderModify,
+ ServFail,
+ Truncate,
+ None
+ };
+ virtual Action operator()(DNSResponse*, string* ruleresult) const = 0;
virtual ~DNSResponseAction()
{
}
struct DynBlock
{
- DynBlock(): action(DNSAction::Action::None), warning(false)
+ DynBlock() :
+ action(DNSAction::Action::None), warning(false)
{
until.tv_sec = 0;
until.tv_nsec = 0;
}
- DynBlock(const std::string& reason_, const struct timespec& until_, const DNSName& domain_, DNSAction::Action action_): reason(reason_), domain(domain_), until(until_), action(action_), warning(false)
+ DynBlock(const std::string& reason_, const struct timespec& until_, const DNSName& domain_, DNSAction::Action action_) :
+ reason(reason_), domain(domain_), until(until_), action(action_), warning(false)
{
}
- DynBlock(const DynBlock& rhs): reason(rhs.reason), domain(rhs.domain), until(rhs.until), action(rhs.action), warning(rhs.warning), bpf(rhs.bpf)
+ DynBlock(const DynBlock& rhs) :
+ reason(rhs.reason), domain(rhs.domain), until(rhs.until), action(rhs.action), warning(rhs.warning), bpf(rhs.bpf)
{
blocks.store(rhs.blocks);
}
- DynBlock(DynBlock&& rhs): reason(std::move(rhs.reason)), domain(std::move(rhs.domain)), until(rhs.until), action(rhs.action), warning(rhs.warning), bpf(rhs.bpf)
+ DynBlock(DynBlock&& rhs) :
+ reason(std::move(rhs.reason)), domain(std::move(rhs.domain)), until(rhs.until), action(rhs.action), warning(rhs.warning), bpf(rhs.bpf)
{
blocks.store(rhs.blocks);
}
extern GlobalStateHolder<NetmaskTree<DynBlock, AddressAndPortRange>> g_dynblockNMG;
-extern vector<pair<struct timeval, std::string> > g_confDelta;
+extern vector<pair<struct timeval, std::string>> g_confDelta;
using pdns::stat_t;
{
}
- BasicQPSLimiter(unsigned int burst): d_tokens(burst)
+ BasicQPSLimiter(unsigned int burst) :
+ d_tokens(burst)
{
d_prev.start();
}
auto delta = d_prev.udiffAndSet();
if (delta > 0.0) { // time, frequently, does go backwards..
- d_tokens += 1.0 * rate * (delta/1000000.0);
+ d_tokens += 1.0 * rate * (delta / 1000000.0);
}
if (d_tokens > burst) {
class QPSLimiter : public BasicQPSLimiter
{
public:
- QPSLimiter(): BasicQPSLimiter()
+ QPSLimiter() :
+ BasicQPSLimiter()
{
}
- QPSLimiter(unsigned int rate, unsigned int burst): BasicQPSLimiter(burst), d_rate(rate), d_burst(burst), d_passthrough(false)
+ QPSLimiter(unsigned int rate, unsigned int burst) :
+ BasicQPSLimiter(burst), d_rate(rate), d_burst(burst), d_passthrough(false)
{
d_prev.start();
}
typedef std::unordered_map<string, unsigned int> QueryCountRecords;
typedef std::function<std::tuple<bool, string>(const DNSQuestion* dq)> QueryCountFilter;
-struct QueryCount {
+struct QueryCount
+{
QueryCount()
{
}
struct ClientState
{
- ClientState(const ComboAddress& local_, bool isTCP_, bool doReusePort, int fastOpenQueue, const std::string& itfName, const std::set<int>& cpus_, bool enableProxyProtocol): cpus(cpus_), interface(itfName), local(local_), fastOpenQueueSize(fastOpenQueue), tcp(isTCP_), reuseport(doReusePort), d_enableProxyProtocol(enableProxyProtocol)
+ ClientState(const ComboAddress& local_, bool isTCP_, bool doReusePort, int fastOpenQueue, const std::string& itfName, const std::set<int>& cpus_, bool enableProxyProtocol) :
+ cpus(cpus_), interface(itfName), local(local_), fastOpenQueueSize(fastOpenQueue), tcp(isTCP_), reuseport(doReusePort), d_enableProxyProtocol(enableProxyProtocol)
{
}
stat_t tlsResumptions{0}; // A TLS session has been resumed, either via session id or via a TLS ticket
stat_t tlsUnknownTicketKey{0}; // A TLS ticket has been presented but we don't have the associated key (might have expired)
stat_t tlsInactiveTicketKey{0}; // A TLS ticket has been successfully resumed but the key is no longer active, we should issue a new one
- stat_t tls10queries{0}; // valid DNS queries received via TLSv1.0
- stat_t tls11queries{0}; // valid DNS queries received via TLSv1.1
- stat_t tls12queries{0}; // valid DNS queries received via TLSv1.2
- stat_t tls13queries{0}; // valid DNS queries received via TLSv1.3
- stat_t tlsUnknownqueries{0}; // valid DNS queries received via unknown TLS version
+ stat_t tls10queries{0}; // valid DNS queries received via TLSv1.0
+ stat_t tls11queries{0}; // valid DNS queries received via TLSv1.1
+ stat_t tls12queries{0}; // valid DNS queries received via TLSv1.2
+ stat_t tls13queries{0}; // valid DNS queries received via TLSv1.3
+ stat_t tlsUnknownqueries{0}; // valid DNS queries received via unknown TLS version
pdns::stat_t_trait<double> tcpAvgQueriesPerConnection{0.0};
/* in ms */
pdns::stat_t_trait<double> tcpAvgConnectionDuration{0.0};
if (d_filter) {
detachFilter(getSocket());
for (const auto& [addr, socket] : d_additionalAddresses) {
- (void) addr;
+ (void)addr;
if (socket != -1) {
detachFilter(socket);
}
bpf->addSocket(getSocket());
for (const auto& [addr, socket] : d_additionalAddresses) {
- (void) addr;
+ (void)addr;
if (socket != -1) {
bpf->addSocket(socket);
}
struct CrossProtocolQuery;
-struct DownstreamState: public std::enable_shared_from_this<DownstreamState>
+struct DownstreamState : public std::enable_shared_from_this<DownstreamState>
{
DownstreamState(const DownstreamState&) = delete;
DownstreamState(DownstreamState&&) = delete;
DownstreamState& operator=(DownstreamState&&) = delete;
typedef std::function<std::tuple<DNSName, uint16_t, uint16_t>(const DNSName&, uint16_t, uint16_t, dnsheader*)> checkfunc_t;
- enum class Availability : uint8_t { Up, Down, Auto, Lazy };
- enum class LazyHealthCheckMode : uint8_t { TimeoutOnly, TimeoutOrServFail };
+ enum class Availability : uint8_t
+ {
+ Up,
+ Down,
+ Auto,
+ Lazy
+ };
+ enum class LazyHealthCheckMode : uint8_t
+ {
+ TimeoutOnly,
+ TimeoutOrServFail
+ };
struct Config
{
Config()
{
}
- Config(const ComboAddress& remote_): remote(remote_)
+ Config(const ComboAddress& remote_) :
+ remote(remote_)
{
}
};
DownstreamState(DownstreamState::Config&& config, std::shared_ptr<TLSCtx> tlsCtx, bool connect);
- DownstreamState(const ComboAddress& remote): DownstreamState(DownstreamState::Config(remote), nullptr, false)
+ DownstreamState(const ComboAddress& remote) :
+ DownstreamState(DownstreamState::Config(remote), nullptr, false)
{
}
stat_t queries{0};
stat_t responses{0};
stat_t nonCompliantResponses{0};
- struct {
+ struct
+ {
stat_t sendErrors{0};
stat_t reuseds{0};
stat_t queries{0};
SharedLockGuarded<std::vector<unsigned int>> hashes;
LockGuarded<std::unique_ptr<FDMultiplexer>> mplexer{nullptr};
+
private:
LockGuarded<std::map<uint16_t, IDState>> d_idStatesMap;
vector<IDState> idStates;
{
boost::circular_buffer<bool> d_lastResults;
time_t d_nextCheck{0};
- enum class LazyStatus: uint8_t { Healthy = 0, PotentialFailure, Failed };
+ enum class LazyStatus : uint8_t
+ {
+ Healthy = 0,
+ PotentialFailure,
+ Failed
+ };
LazyStatus d_status{LazyStatus::Healthy};
};
LockGuarded<LazyHealthCheckStats> d_lazyHealthCheckStats;
std::atomic_flag threadStarted;
uint8_t consecutiveSuccessfulChecks{0};
bool d_stopped{false};
+
public:
void updateStatisticsInfo()
{
return upStatus;
}
- void setUp() {
+ void setUp()
+ {
d_config.availability = Availability::Up;
}
latencyUsec = 0.0;
latencyUsecTCP = 0.0;
}
- void setAuto() {
+ void setAuto()
+ {
d_config.availability = Availability::Auto;
}
- void setLazyAuto() {
+ void setLazyAuto()
+ {
d_config.availability = Availability::Lazy;
d_lazyHealthCheckStats.lock()->d_lastResults.set_capacity(d_config.d_lazyHealthCheckSampleSize);
}
bool healthCheckRequired(std::optional<time_t> currentTime = std::nullopt);
- const string& getName() const {
+ const string& getName() const
+ {
return d_config.name;
}
- const string& getNameWithAddr() const {
+ const string& getNameWithAddr() const
+ {
return d_config.nameWithAddr;
}
void setName(const std::string& newName)
{
d_config.name = newName;
- d_config.nameWithAddr = newName.empty() ? d_config.remote.toStringWithPort() : (d_config.name + " (" + d_config.remote.toStringWithPort()+ ")");
+ d_config.nameWithAddr = newName.empty() ? d_config.remote.toStringWithPort() : (d_config.name + " (" + d_config.remote.toStringWithPort() + ")");
}
string getStatus() const
class DNSRule
{
public:
- virtual ~DNSRule ()
+ virtual ~DNSRule()
{
}
virtual bool matches(const DNSQuestion* dq) const = 0;
struct ServerPool
{
- ServerPool(): d_servers(std::make_shared<const ServerPolicy::NumberedServerVector>())
+ ServerPool() :
+ d_servers(std::make_shared<const ServerPolicy::NumberedServerVector>())
{
}
bool d_useECS{false};
};
-enum ednsHeaderFlags {
+enum ednsHeaderFlags
+{
EDNS_HEADER_FLAG_NONE = 0,
EDNS_HEADER_FLAG_DO = 32768
};
extern GlobalStateHolder<ServerPolicy> g_policy;
extern GlobalStateHolder<servers_t> g_dstates;
extern GlobalStateHolder<pools_t> g_pools;
-extern GlobalStateHolder<vector<DNSDistRuleAction> > g_ruleactions;
-extern GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_respruleactions;
-extern GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_cachehitrespruleactions;
-extern GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_selfansweredrespruleactions;
-extern GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_cacheInsertedRespRuleActions;
+extern GlobalStateHolder<vector<DNSDistRuleAction>> g_ruleactions;
+extern GlobalStateHolder<vector<DNSDistResponseRuleAction>> g_respruleactions;
+extern GlobalStateHolder<vector<DNSDistResponseRuleAction>> g_cachehitrespruleactions;
+extern GlobalStateHolder<vector<DNSDistResponseRuleAction>> g_selfansweredrespruleactions;
+extern GlobalStateHolder<vector<DNSDistResponseRuleAction>> g_cacheInsertedRespRuleActions;
extern GlobalStateHolder<NetmaskGroup> g_ACL;
extern ComboAddress g_serverControl; // not changed during runtime
extern uint32_t g_socketUDPRecvBuffer;
extern shared_ptr<BPFFilter> g_defaultBPFFilter;
-extern std::vector<std::shared_ptr<DynBPFFilter> > g_dynBPFFilters;
+extern std::vector<std::shared_ptr<DynBPFFilter>> g_dynBPFFilters;
struct LocalHolders
{
- LocalHolders(): acl(g_ACL.getLocal()), policy(g_policy.getLocal()), ruleactions(g_ruleactions.getLocal()), cacheHitRespRuleactions(g_cachehitrespruleactions.getLocal()), cacheInsertedRespRuleActions(g_cacheInsertedRespRuleActions.getLocal()), selfAnsweredRespRuleactions(g_selfansweredrespruleactions.getLocal()), servers(g_dstates.getLocal()), dynNMGBlock(g_dynblockNMG.getLocal()), dynSMTBlock(g_dynblockSMT.getLocal()), pools(g_pools.getLocal())
+ LocalHolders() :
+ acl(g_ACL.getLocal()), policy(g_policy.getLocal()), ruleactions(g_ruleactions.getLocal()), cacheHitRespRuleactions(g_cachehitrespruleactions.getLocal()), cacheInsertedRespRuleActions(g_cacheInsertedRespRuleActions.getLocal()), selfAnsweredRespRuleactions(g_selfansweredrespruleactions.getLocal()), servers(g_dstates.getLocal()), dynNMGBlock(g_dynblockNMG.getLocal()), dynSMTBlock(g_dynblockSMT.getLocal()), pools(g_pools.getLocal())
{
}
LocalStateHolder<NetmaskGroup> acl;
LocalStateHolder<ServerPolicy> policy;
- LocalStateHolder<vector<DNSDistRuleAction> > ruleactions;
- LocalStateHolder<vector<DNSDistResponseRuleAction> > cacheHitRespRuleactions;
- LocalStateHolder<vector<DNSDistResponseRuleAction> > cacheInsertedRespRuleActions;
- LocalStateHolder<vector<DNSDistResponseRuleAction> > selfAnsweredRespRuleactions;
+ LocalStateHolder<vector<DNSDistRuleAction>> ruleactions;
+ LocalStateHolder<vector<DNSDistResponseRuleAction>> cacheHitRespRuleactions;
+ LocalStateHolder<vector<DNSDistResponseRuleAction>> cacheInsertedRespRuleActions;
+ LocalStateHolder<vector<DNSDistResponseRuleAction>> selfAnsweredRespRuleactions;
LocalStateHolder<servers_t> servers;
- LocalStateHolder<NetmaskTree<DynBlock, AddressAndPortRange> > dynNMGBlock;
- LocalStateHolder<SuffixMatchTree<DynBlock> > dynSMTBlock;
+ LocalStateHolder<NetmaskTree<DynBlock, AddressAndPortRange>> dynNMGBlock;
+ LocalStateHolder<SuffixMatchTree<DynBlock>> dynSMTBlock;
LocalStateHolder<pools_t> pools;
};
void tcpAcceptorThread(const std::vector<ClientState*>& states);
void setLuaNoSideEffect(); // if nothing has been declared, set that there are no side effects
-void setLuaSideEffect(); // set to report a side effect, cancelling all _no_ side effect calls
+void setLuaSideEffect(); // set to report a side effect, cancelling all _no_ side effect calls
bool getLuaNoSideEffect(); // set if there were only explicit declarations of _no_ side effect
void resetLuaSideEffect(); // reset to indeterminate state
extern std::set<std::string> g_capabilitiesToRetain;
static const uint16_t s_udpIncomingBufferSize{1500}; // don't accept UDP queries larger than this value
-enum class ProcessQueryResult : uint8_t { Drop, SendAnswer, PassToBackend, Asynchronous };
+enum class ProcessQueryResult : uint8_t
+{
+ Drop,
+ SendAnswer,
+ PassToBackend,
+ Asynchronous
+};
ProcessQueryResult processQuery(DNSQuestion& dq, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend);
ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend);
bool processResponse(PacketBuffer& response, const std::vector<DNSDistResponseRuleAction>& respRuleActions, const std::vector<DNSDistResponseRuleAction>& insertedRespRuleActions, DNSResponse& dr, bool muted);
return true;
}
-namespace dnsdist {
+namespace dnsdist
+{
std::unique_ptr<CrossProtocolQuery> getInternalQueryFromDQ(DNSQuestion& dq, bool isResponse)
{
return nullptr;
static const uint16_t ECSSourcePrefixV4 = 24;
static const uint16_t ECSSourcePrefixV6 = 56;
-static void validateQuery(const PacketBuffer& packet, bool hasEdns=true, bool hasXPF=false, uint16_t additionals=0, uint16_t answers=0, uint16_t authorities=0)
+static void validateQuery(const PacketBuffer& packet, bool hasEdns = true, bool hasXPF = false, uint16_t additionals = 0, uint16_t answers = 0, uint16_t authorities = 0)
{
MOADNSParser mdp(true, reinterpret_cast<const char*>(packet.data()), packet.size());
BOOST_CHECK_EQUAL(expectedOption.substr(EDNS_OPTION_CODE_SIZE + EDNS_OPTION_LENGTH_SIZE), std::string(ecsOption->second.values.at(0).content, ecsOption->second.values.at(0).size));
}
-static void validateResponse(const PacketBuffer& packet, bool hasEdns, uint8_t additionalCount=0)
+static void validateResponse(const PacketBuffer& packet, bool hasEdns, uint8_t additionalCount = 0)
{
MOADNSParser mdp(false, reinterpret_cast<const char*>(packet.data()), packet.size());
auto packet = query;
- ids.qname = DNSName(reinterpret_cast<const char *>(packet.data()), packet.size(), sizeof(dnsheader), false, &ids.qtype, &ids.qclass);
+ ids.qname = DNSName(reinterpret_cast<const char*>(packet.data()), packet.size(), sizeof(dnsheader), false, &ids.qtype, &ids.qclass);
BOOST_CHECK_EQUAL(ids.qname, name);
BOOST_CHECK(ids.qtype == QType::A);
BOOST_CHECK(ids.qclass == QClass::IN);
validateECS(packet, ids.origRemote);
}
-BOOST_AUTO_TEST_CASE(addECSWithEDNSNoECS) {
+BOOST_AUTO_TEST_CASE(addECSWithEDNSNoECS)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote;
validateQuery(packet);
}
-BOOST_AUTO_TEST_CASE(addECSWithEDNSNoECSAlreadyParsed) {
+BOOST_AUTO_TEST_CASE(addECSWithEDNSNoECSAlreadyParsed)
+{
InternalQueryState ids;
ids.origRemote = ComboAddress("2001:DB8::1");
ids.protocol = dnsdist::Protocol::DoUDP;
validateECS(packet, ids.origRemote);
}
-BOOST_AUTO_TEST_CASE(replaceECSWithSameSize) {
+BOOST_AUTO_TEST_CASE(replaceECSWithSameSize)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote("192.168.1.25");
validateECS(packet, remote);
}
-BOOST_AUTO_TEST_CASE(replaceECSWithSameSizeAlreadyParsed) {
+BOOST_AUTO_TEST_CASE(replaceECSWithSameSizeAlreadyParsed)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote("192.168.1.25");
validateECS(packet, remote);
}
-BOOST_AUTO_TEST_CASE(replaceECSWithSmaller) {
+BOOST_AUTO_TEST_CASE(replaceECSWithSmaller)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote("192.168.1.25");
validateECS(packet, remote);
}
-BOOST_AUTO_TEST_CASE(replaceECSWithLarger) {
+BOOST_AUTO_TEST_CASE(replaceECSWithLarger)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote("192.168.1.25");
validateQuery(packet);
}
-BOOST_AUTO_TEST_CASE(replaceECSFollowedByTSIG) {
+BOOST_AUTO_TEST_CASE(replaceECSFollowedByTSIG)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote("192.168.1.25");
validateQuery(packet, true, false, 1);
}
-BOOST_AUTO_TEST_CASE(replaceECSAfterAN) {
+BOOST_AUTO_TEST_CASE(replaceECSAfterAN)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote("192.168.1.25");
validateQuery(packet, true, false, 0, 1, 0);
}
-BOOST_AUTO_TEST_CASE(replaceECSAfterAuth) {
+BOOST_AUTO_TEST_CASE(replaceECSAfterAuth)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote("192.168.1.25");
validateQuery(packet, true, false, 0, 0, 1);
}
-BOOST_AUTO_TEST_CASE(replaceECSBetweenTwoRecords) {
+BOOST_AUTO_TEST_CASE(replaceECSBetweenTwoRecords)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote("192.168.1.25");
validateQuery(packet, true, false, 2);
}
-BOOST_AUTO_TEST_CASE(insertECSInEDNSBetweenTwoRecords) {
+BOOST_AUTO_TEST_CASE(insertECSInEDNSBetweenTwoRecords)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote("192.168.1.25");
validateQuery(packet, true, false, 2);
}
-BOOST_AUTO_TEST_CASE(insertECSAfterTSIG) {
+BOOST_AUTO_TEST_CASE(insertECSAfterTSIG)
+{
bool ednsAdded = false;
bool ecsAdded = false;
ComboAddress remote("192.168.1.25");
validateQuery(packet, true, false);
}
-
-BOOST_AUTO_TEST_CASE(removeEDNSWhenFirst) {
+BOOST_AUTO_TEST_CASE(removeEDNSWhenFirst)
+{
DNSName name("www.powerdns.com.");
PacketBuffer response;
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
size_t const ednsOptRRSize = sizeof(struct dnsrecordheader) + 1 /* root in OPT RR */;
validateResponse(newResponse, false, 1);
}
-BOOST_AUTO_TEST_CASE(removeEDNSWhenIntermediary) {
+BOOST_AUTO_TEST_CASE(removeEDNSWhenIntermediary)
+{
DNSName name("www.powerdns.com.");
PacketBuffer response;
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
size_t const ednsOptRRSize = sizeof(struct dnsrecordheader) + 1 /* root in OPT RR */;
validateResponse(newResponse, false, 2);
}
-BOOST_AUTO_TEST_CASE(removeEDNSWhenLast) {
+BOOST_AUTO_TEST_CASE(removeEDNSWhenLast)
+{
DNSName name("www.powerdns.com.");
PacketBuffer response;
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
size_t const ednsOptRRSize = sizeof(struct dnsrecordheader) + 1 /* root in OPT RR */;
validateResponse(newResponse, false, 1);
}
-BOOST_AUTO_TEST_CASE(removeECSWhenOnlyOption) {
+BOOST_AUTO_TEST_CASE(removeECSWhenOnlyOption)
+{
DNSName name("www.powerdns.com.");
ComboAddress origRemote("127.0.0.1");
size_t responseLen = response.size();
size_t existingOptLen = optLen;
BOOST_CHECK(existingOptLen < responseLen);
- res = removeEDNSOptionFromOPT(reinterpret_cast<char *>(response.data()) + optStart, &optLen, EDNSOptionCode::ECS);
+ res = removeEDNSOptionFromOPT(reinterpret_cast<char*>(response.data()) + optStart, &optLen, EDNSOptionCode::ECS);
BOOST_CHECK_EQUAL(res, 0);
BOOST_CHECK_EQUAL(optLen, existingOptLen - (origECSOptionStr.size() + 4));
responseLen -= (existingOptLen - optLen);
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) response.data(), responseLen, sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)response.data(), responseLen, sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
validateResponse(response, true, 1);
}
-BOOST_AUTO_TEST_CASE(removeECSWhenFirstOption) {
+BOOST_AUTO_TEST_CASE(removeECSWhenFirstOption)
+{
DNSName name("www.powerdns.com.");
ComboAddress origRemote("127.0.0.1");
size_t responseLen = response.size();
size_t existingOptLen = optLen;
BOOST_CHECK(existingOptLen < responseLen);
- res = removeEDNSOptionFromOPT(reinterpret_cast<char *>(response.data()) + optStart, &optLen, EDNSOptionCode::ECS);
+ res = removeEDNSOptionFromOPT(reinterpret_cast<char*>(response.data()) + optStart, &optLen, EDNSOptionCode::ECS);
BOOST_CHECK_EQUAL(res, 0);
BOOST_CHECK_EQUAL(optLen, existingOptLen - (origECSOptionStr.size() + 4));
responseLen -= (existingOptLen - optLen);
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) response.data(), responseLen, sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)response.data(), responseLen, sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
validateResponse(response, true, 1);
}
-BOOST_AUTO_TEST_CASE(removeECSWhenIntermediaryOption) {
+BOOST_AUTO_TEST_CASE(removeECSWhenIntermediaryOption)
+{
DNSName name("www.powerdns.com.");
ComboAddress origRemote("127.0.0.1");
size_t responseLen = response.size();
size_t existingOptLen = optLen;
BOOST_CHECK(existingOptLen < responseLen);
- res = removeEDNSOptionFromOPT(reinterpret_cast<char *>(response.data()) + optStart, &optLen, EDNSOptionCode::ECS);
+ res = removeEDNSOptionFromOPT(reinterpret_cast<char*>(response.data()) + optStart, &optLen, EDNSOptionCode::ECS);
BOOST_CHECK_EQUAL(res, 0);
BOOST_CHECK_EQUAL(optLen, existingOptLen - (origECSOptionStr.size() + 4));
responseLen -= (existingOptLen - optLen);
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) response.data(), responseLen, sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)response.data(), responseLen, sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
validateResponse(response, true, 1);
}
-BOOST_AUTO_TEST_CASE(removeECSWhenLastOption) {
+BOOST_AUTO_TEST_CASE(removeECSWhenLastOption)
+{
DNSName name("www.powerdns.com.");
ComboAddress origRemote("127.0.0.1");
size_t responseLen = response.size();
size_t existingOptLen = optLen;
BOOST_CHECK(existingOptLen < responseLen);
- res = removeEDNSOptionFromOPT(reinterpret_cast<char *>(response.data()) + optStart, &optLen, EDNSOptionCode::ECS);
+ res = removeEDNSOptionFromOPT(reinterpret_cast<char*>(response.data()) + optStart, &optLen, EDNSOptionCode::ECS);
BOOST_CHECK_EQUAL(res, 0);
BOOST_CHECK_EQUAL(optLen, existingOptLen - (origECSOptionStr.size() + 4));
responseLen -= (existingOptLen - optLen);
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) response.data(), responseLen, sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)response.data(), responseLen, sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
validateResponse(response, true, 1);
}
-BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenOnlyOption) {
+BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenOnlyOption)
+{
DNSName name("www.powerdns.com.");
ComboAddress origRemote("127.0.0.1");
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
validateResponse(newResponse, true, 1);
}
-BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenFirstOption) {
+BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenFirstOption)
+{
DNSName name("www.powerdns.com.");
ComboAddress origRemote("127.0.0.1");
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
validateResponse(newResponse, true, 1);
}
-BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenIntermediaryOption) {
+BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenIntermediaryOption)
+{
DNSName name("www.powerdns.com.");
ComboAddress origRemote("127.0.0.1");
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
validateResponse(newResponse, true, 1);
}
-BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenLastOption) {
+BOOST_AUTO_TEST_CASE(rewritingWithoutECSWhenLastOption)
+{
DNSName name("www.powerdns.com.");
ComboAddress origRemote("127.0.0.1");
unsigned int consumed = 0;
uint16_t qtype;
- DNSName qname((const char*) newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
+ DNSName qname((const char*)newResponse.data(), newResponse.size(), sizeof(dnsheader), false, &qtype, nullptr, &consumed);
BOOST_CHECK_EQUAL(qname, name);
BOOST_CHECK(qtype == QType::A);
validateResponse(newResponse, true, 1);
}
-static DNSQuestion turnIntoResponse(InternalQueryState& ids, PacketBuffer& query, bool resizeBuffer=true)
+static DNSQuestion turnIntoResponse(InternalQueryState& ids, PacketBuffer& query, bool resizeBuffer = true)
{
if (resizeBuffer) {
query.resize(4096);
return getEDNSZ(dq);
}
-BOOST_AUTO_TEST_CASE(test_getEDNSZ) {
+BOOST_AUTO_TEST_CASE(test_getEDNSZ)
+{
uint16_t z;
uint16_t udpPayloadSize;
BOOST_CHECK_EQUAL(udpPayloadSize, 512);
}
- {
+ {
/* valid EDNS, options, DO not set */
PacketBuffer query;
GenericDNSPacketWriter<PacketBuffer> pw(query, qname, qtype, qclass, 0);
BOOST_CHECK_EQUAL(z, EDNS_HEADER_FLAG_DO);
BOOST_CHECK_EQUAL(udpPayloadSize, 512);
}
-
}
-BOOST_AUTO_TEST_CASE(test_addEDNSToQueryTurnedResponse) {
+BOOST_AUTO_TEST_CASE(test_addEDNSToQueryTurnedResponse)
+{
InternalQueryState ids;
ids.qname = DNSName("www.powerdns.com.");
ids.qtype = QType::A;
}
}
-BOOST_AUTO_TEST_CASE(test_getEDNSOptionsStart) {
+BOOST_AUTO_TEST_CASE(test_getEDNSOptionsStart)
+{
const DNSName qname("www.powerdns.com.");
const uint16_t qtype = QType::A;
const uint16_t qclass = QClass::IN;
BOOST_CHECK_EQUAL(optRDPosition, optRDExpectedOffset);
BOOST_CHECK_EQUAL(remaining, query.size() - optRDExpectedOffset);
}
-
}
-BOOST_AUTO_TEST_CASE(test_isEDNSOptionInOpt) {
+BOOST_AUTO_TEST_CASE(test_isEDNSOptionInOpt)
+{
auto locateEDNSOption = [](const PacketBuffer& query, uint16_t code, size_t* optContentStart, uint16_t* optContentLen) {
uint16_t optStart;
}
}
-BOOST_AUTO_TEST_CASE(test_setNegativeAndAdditionalSOA) {
+BOOST_AUTO_TEST_CASE(test_setNegativeAndAdditionalSOA)
+{
InternalQueryState ids;
ids.origRemote = ComboAddress("192.0.2.1");
ids.protocol = dnsdist::Protocol::DoUDP;
ids.qname = DNSName(reinterpret_cast<const char*>(packet.data()), packet.size(), sizeof(dnsheader), false, &ids.qtype, nullptr);
DNSQuestion dq(ids, packet);
- BOOST_CHECK(setNegativeAndAdditionalSOA(dq, true, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4 , 5, false));
+ BOOST_CHECK(setNegativeAndAdditionalSOA(dq, true, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4, 5, false));
BOOST_CHECK(packet.size() > query.size());
MOADNSParser mdp(true, reinterpret_cast<const char*>(packet.data()), packet.size());
ids.qname = DNSName(reinterpret_cast<const char*>(packet.data()), packet.size(), sizeof(dnsheader), false, &ids.qtype, nullptr);
DNSQuestion dq(ids, packet);
- BOOST_CHECK(setNegativeAndAdditionalSOA(dq, true, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4 , 5, false));
+ BOOST_CHECK(setNegativeAndAdditionalSOA(dq, true, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4, 5, false));
BOOST_CHECK(packet.size() > queryWithEDNS.size());
MOADNSParser mdp(true, reinterpret_cast<const char*>(packet.data()), packet.size());
ids.qname = DNSName(reinterpret_cast<const char*>(packet.data()), packet.size(), sizeof(dnsheader), false, &ids.qtype, nullptr);
DNSQuestion dq(ids, packet);
- BOOST_CHECK(setNegativeAndAdditionalSOA(dq, false, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4 , 5, false));
+ BOOST_CHECK(setNegativeAndAdditionalSOA(dq, false, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4, 5, false));
BOOST_CHECK(packet.size() > query.size());
MOADNSParser mdp(true, reinterpret_cast<const char*>(packet.data()), packet.size());
ids.qname = DNSName(reinterpret_cast<const char*>(packet.data()), packet.size(), sizeof(dnsheader), false, &ids.qtype, nullptr);
DNSQuestion dq(ids, packet);
- BOOST_CHECK(setNegativeAndAdditionalSOA(dq, false, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4 , 5, false));
+ BOOST_CHECK(setNegativeAndAdditionalSOA(dq, false, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4, 5, false));
BOOST_CHECK(packet.size() > queryWithEDNS.size());
MOADNSParser mdp(true, reinterpret_cast<const char*>(packet.data()), packet.size());
ids.qname = DNSName(reinterpret_cast<const char*>(packet.data()), packet.size(), sizeof(dnsheader), false, &ids.qtype, nullptr);
DNSQuestion dq(ids, packet);
- BOOST_CHECK(setNegativeAndAdditionalSOA(dq, true, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4 ,
- 5, true));
+ BOOST_CHECK(setNegativeAndAdditionalSOA(dq, true, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4,
+ 5, true));
BOOST_CHECK(packet.size() > query.size());
MOADNSParser mdp(true, reinterpret_cast<const char*>(packet.data()), packet.size());
ids.qname = DNSName(reinterpret_cast<const char*>(packet.data()), packet.size(), sizeof(dnsheader), false, &ids.qtype, nullptr);
DNSQuestion dq(ids, packet);
- BOOST_CHECK(setNegativeAndAdditionalSOA(dq, true, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4 , 5, true));
+ BOOST_CHECK(setNegativeAndAdditionalSOA(dq, true, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4, 5, true));
BOOST_CHECK(packet.size() > queryWithEDNS.size());
MOADNSParser mdp(true, reinterpret_cast<const char*>(packet.data()), packet.size());
ids.qname = DNSName(reinterpret_cast<const char*>(packet.data()), packet.size(), sizeof(dnsheader), false, &ids.qtype, nullptr);
DNSQuestion dq(ids, packet);
- BOOST_CHECK(setNegativeAndAdditionalSOA(dq, false, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4 , 5, true));
+ BOOST_CHECK(setNegativeAndAdditionalSOA(dq, false, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4, 5, true));
BOOST_CHECK(packet.size() > query.size());
MOADNSParser mdp(true, reinterpret_cast<const char*>(packet.data()), packet.size());
ids.qname = DNSName(reinterpret_cast<const char*>(packet.data()), packet.size(), sizeof(dnsheader), false, &ids.qtype, nullptr);
DNSQuestion dq(ids, packet);
- BOOST_CHECK(setNegativeAndAdditionalSOA(dq, false, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4 , 5, true));
+ BOOST_CHECK(setNegativeAndAdditionalSOA(dq, false, DNSName("zone."), 42, DNSName("mname."), DNSName("rname."), 1, 2, 3, 4, 5, true));
BOOST_CHECK(packet.size() > queryWithEDNS.size());
MOADNSParser mdp(true, reinterpret_cast<const char*>(packet.data()), packet.size());
}
}
-BOOST_AUTO_TEST_CASE(getEDNSOptionsWithoutEDNS) {
+BOOST_AUTO_TEST_CASE(getEDNSOptionsWithoutEDNS)
+{
InternalQueryState ids;
ids.origRemote = ComboAddress("192.168.1.25");
ids.protocol = dnsdist::Protocol::DoUDP;
static ssize_t send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data)
{
auto* conn = static_cast<DOHConnection*>(user_data);
- //NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API
conn->d_clientOutBuffer.insert(conn->d_clientOutBuffer.end(), data, data + length);
return static_cast<ssize_t>(length);
}
{
auto* conn = static_cast<DOHConnection*>(user_data);
auto& response = conn->d_responses[stream_id];
- //NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API
response.insert(response.end(), data, data + len);
return 0;
}
try {
uint16_t responseCode{0};
auto expected = s_connectionContexts.at(conn->d_connectionID).d_responseCodes.at((frame->hd.stream_id - 1) / 2);
- //NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): nghttp2 API
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): nghttp2 API
pdns::checked_stoi_into(responseCode, std::string(reinterpret_cast<const char*>(value), valuelen));
conn->d_responseCodes[frame->hd.stream_id] = responseCode;
if (responseCode != expected) {
BOOST_REQUIRE_GE(buffer.size(), toRead);
- //NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
+ // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
std::copy(externalBuffer.begin(), externalBuffer.begin() + toRead, buffer.begin() + pos);
pos += toRead;
- //NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
+ // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
externalBuffer.erase(externalBuffer.begin(), externalBuffer.begin() + toRead);
return step.nextState;
static bool receivedOverUDP = true;
-BOOST_AUTO_TEST_CASE(test_PacketCacheSimple) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheSimple)
+{
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, 86400, 1);
BOOST_CHECK_EQUAL(PC.getSize(), 0U);
try {
for (counter = 0; counter < 100000; ++counter) {
- auto a = DNSName(std::to_string(counter))+DNSName(" hello");
+ auto a = DNSName(std::to_string(counter)) + DNSName(" hello");
ids.qname = a;
PacketBuffer query;
BOOST_CHECK_EQUAL(skipped, PC.getInsertCollisions());
BOOST_CHECK_EQUAL(PC.getSize(), counter - skipped);
- size_t deleted=0;
- size_t delcounter=0;
- for (delcounter=0; delcounter < counter/1000; ++delcounter) {
- ids.qname = DNSName(std::to_string(delcounter))+DNSName(" hello");
+ size_t deleted = 0;
+ size_t delcounter = 0;
+ for (delcounter = 0; delcounter < counter / 1000; ++delcounter) {
+ ids.qname = DNSName(std::to_string(delcounter)) + DNSName(" hello");
PacketBuffer query;
GenericDNSPacketWriter<PacketBuffer> pwQ(query, ids.qname, QType::A, QClass::IN, 0);
pwQ.getHeader()->rd = 1;
}
BOOST_CHECK_EQUAL(PC.getSize(), counter - skipped - deleted);
- size_t matches=0;
- size_t expected=counter-skipped-deleted;
+ size_t matches = 0;
+ size_t expected = counter - skipped - deleted;
for (; delcounter < counter; ++delcounter) {
- ids.qname = DNSName(std::to_string(delcounter))+DNSName(" hello");
+ ids.qname = DNSName(std::to_string(delcounter)) + DNSName(" hello");
PacketBuffer query;
GenericDNSPacketWriter<PacketBuffer> pwQ(query, ids.qname, QType::A, QClass::IN, 0);
pwQ.getHeader()->rd = 1;
BOOST_CHECK_EQUAL(PC.purgeExpired(0, now), 0U);
}
catch (const PDNSException& e) {
- cerr<<"Had error: "<<e.reason<<endl;
+ cerr << "Had error: " << e.reason << endl;
throw;
}
}
-BOOST_AUTO_TEST_CASE(test_PacketCacheSharded) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheSharded)
+{
const size_t maxEntries = 150000;
const size_t numberOfShards = 10;
DNSDistPacketCache PC(maxEntries, 86400, 1, 60, 3600, 60, false, numberOfShards);
BOOST_CHECK_EQUAL(PC.purgeExpired(0, now), 0U);
}
catch (const PDNSException& e) {
- cerr<<"Had error: "<<e.reason<<endl;
+ cerr << "Had error: " << e.reason << endl;
throw;
}
}
-BOOST_AUTO_TEST_CASE(test_PacketCacheTCP) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheTCP)
+{
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, 86400, 1);
InternalQueryState ids;
BOOST_CHECK(!subnet);
}
}
- catch(PDNSException& e) {
- cerr<<"Had error: "<<e.reason<<endl;
+ catch (PDNSException& e) {
+ cerr << "Had error: " << e.reason << endl;
throw;
}
}
-BOOST_AUTO_TEST_CASE(test_PacketCacheServFailTTL) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheServFailTTL)
+{
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, 86400, 1);
InternalQueryState ids;
BOOST_CHECK_EQUAL(found, true);
BOOST_CHECK(!subnet);
}
- catch(PDNSException& e) {
- cerr<<"Had error: "<<e.reason<<endl;
+ catch (PDNSException& e) {
+ cerr << "Had error: " << e.reason << endl;
throw;
}
}
-BOOST_AUTO_TEST_CASE(test_PacketCacheNoDataTTL) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheNoDataTTL)
+{
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, /* maxTTL */ 86400, /* minTTL */ 1, /* tempFailureTTL */ 60, /* maxNegativeTTL */ 1);
BOOST_CHECK_EQUAL(found, false);
BOOST_CHECK(!subnet);
}
- catch(const PDNSException& e) {
- cerr<<"Had error: "<<e.reason<<endl;
+ catch (const PDNSException& e) {
+ cerr << "Had error: " << e.reason << endl;
throw;
}
}
-BOOST_AUTO_TEST_CASE(test_PacketCacheNXDomainTTL) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheNXDomainTTL)
+{
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, /* maxTTL */ 86400, /* minTTL */ 1, /* tempFailureTTL */ 60, /* maxNegativeTTL */ 1);
BOOST_CHECK_EQUAL(found, false);
BOOST_CHECK(!subnet);
}
- catch(const PDNSException& e) {
- cerr<<"Had error: "<<e.reason<<endl;
+ catch (const PDNSException& e) {
+ cerr << "Had error: " << e.reason << endl;
throw;
}
}
-BOOST_AUTO_TEST_CASE(test_PacketCacheTruncated) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheTruncated)
+{
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, /* maxTTL */ 86400, /* minTTL */ 1, /* tempFailureTTL */ 60, /* maxNegativeTTL */ 1);
ids.qtype = QType::A;
ids.qclass = QClass::IN;
ids.protocol = dnsdist::Protocol::DoUDP;
- ids.queryRealTime.start(); // does not have to be accurate ("realTime") in tests
+ ids.queryRealTime.start(); // does not have to be accurate ("realTime") in tests
bool dnssecOK = false;
try {
allowTruncated = false;
found = PC.get(dnsQuestion, pwR.getHeader()->id, &key, subnet, dnssecOK, receivedOverUDP, 0, true, allowTruncated);
BOOST_CHECK_EQUAL(found, false);
-}
- catch(const PDNSException& e) {
- cerr<<"Had error: "<<e.reason<<endl;
+ }
+ catch (const PDNSException& e) {
+ cerr << "Had error: " << e.reason << endl;
throw;
}
}
-BOOST_AUTO_TEST_CASE(test_PacketCacheMaximumSize) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheMaximumSize)
+{
const size_t maxEntries = 150000;
DNSDistPacketCache packetCache(maxEntries, 86400, 1);
InternalQueryState ids;
try {
ComboAddress remote;
bool dnssecOK = false;
- for(unsigned int counter=0; counter < 100000; ++counter) {
- ids.qname = DNSName("hello ")+DNSName(std::to_string(counter+offset));
+ for (unsigned int counter = 0; counter < 100000; ++counter) {
+ ids.qname = DNSName("hello ") + DNSName(std::to_string(counter + offset));
PacketBuffer query;
GenericDNSPacketWriter<PacketBuffer> pwQ(query, ids.qname, QType::A, QClass::IN, 0);
pwQ.getHeader()->rd = 1;
g_PC.insert(key, subnet, *(getFlagsFromDNSHeader(dnsQuestion.getHeader().get())), dnssecOK, ids.qname, QType::A, QClass::IN, response, receivedOverUDP, 0, boost::none);
}
}
- catch(PDNSException& e) {
- cerr<<"Had error: "<<e.reason<<endl;
+ catch (PDNSException& e) {
+ cerr << "Had error: " << e.reason << endl;
throw;
}
}
ids.qname = DNSName("www.powerdns.com.");
ids.protocol = dnsdist::Protocol::DoUDP;
bool dnssecOK = false;
- try
- {
+ try {
ComboAddress remote;
- for(unsigned int counter=0; counter < 100000; ++counter) {
- ids.qname = DNSName("hello ")+DNSName(std::to_string(counter+offset));
+ for (unsigned int counter = 0; counter < 100000; ++counter) {
+ ids.qname = DNSName("hello ") + DNSName(std::to_string(counter + offset));
PacketBuffer query;
GenericDNSPacketWriter<PacketBuffer> pwQ(query, ids.qname, QType::A, QClass::IN, 0);
pwQ.getHeader()->rd = 1;
DNSQuestion dnsQuestion(ids, query);
bool found = g_PC.get(dnsQuestion, 0, &key, subnet, dnssecOK, receivedOverUDP);
if (!found) {
- g_missing++;
+ g_missing++;
}
}
}
- catch(PDNSException& e) {
- cerr<<"Had error in threadReader: "<<e.reason<<endl;
+ catch (PDNSException& e) {
+ cerr << "Had error in threadReader: " << e.reason << endl;
throw;
}
}
-BOOST_AUTO_TEST_CASE(test_PacketCacheThreaded) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheThreaded)
+{
try {
std::vector<std::thread> threads;
for (int i = 0; i < 4; ++i) {
- threads.push_back(std::thread(threadMangler, i*1000000UL));
+ threads.push_back(std::thread(threadMangler, i * 1000000UL));
}
for (auto& t : threads) {
threads.clear();
BOOST_CHECK_EQUAL(g_PC.getSize() + g_PC.getDeferredInserts() + g_PC.getInsertCollisions(), 400000U);
- BOOST_CHECK_SMALL(1.0*g_PC.getInsertCollisions(), 10000.0);
+ BOOST_CHECK_SMALL(1.0 * g_PC.getInsertCollisions(), 10000.0);
for (int i = 0; i < 4; ++i) {
- threads.push_back(std::thread(threadReader, i*1000000UL));
+ threads.push_back(std::thread(threadReader, i * 1000000UL));
}
for (auto& t : threads) {
BOOST_CHECK((g_PC.getDeferredInserts() + g_PC.getDeferredLookups() + g_PC.getInsertCollisions()) >= g_missing);
}
- catch(PDNSException& e) {
- cerr<<"Had error: "<<e.reason<<endl;
+ catch (PDNSException& e) {
+ cerr << "Had error: " << e.reason << endl;
throw;
}
-
}
-BOOST_AUTO_TEST_CASE(test_PCCollision) {
+BOOST_AUTO_TEST_CASE(test_PCCollision)
+{
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, 86400, 1, 60, 3600, 60, false, 1, true, true);
BOOST_CHECK_EQUAL(PC.getSize(), 0U);
#endif
}
-BOOST_AUTO_TEST_CASE(test_PCDNSSECCollision) {
+BOOST_AUTO_TEST_CASE(test_PCDNSSECCollision)
+{
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, 86400, 1, 60, 3600, 60, false, 1, true, true);
BOOST_CHECK_EQUAL(PC.getSize(), 0U);
found = PC.get(dnsQuestion, 0, &key, subnetOut, true, receivedOverUDP);
BOOST_CHECK_EQUAL(found, true);
}
-
}
-BOOST_AUTO_TEST_CASE(test_PacketCacheInspection) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheInspection)
+{
const size_t maxEntries = 100;
DNSDistPacketCache PC(maxEntries, 86400, 1);
BOOST_CHECK_EQUAL(PC.getSize(), 0U);
}
}
-BOOST_AUTO_TEST_CASE(test_PacketCacheXFR) {
+BOOST_AUTO_TEST_CASE(test_PacketCacheXFR)
+{
const size_t maxEntries = 150000;
DNSDistPacketCache PC(maxEntries, 86400, 1);
BOOST_CHECK_EQUAL(PC.getSize(), 0U);
- const std::set<QType> xfrTypes = { QType::AXFR, QType::IXFR };
+ const std::set<QType> xfrTypes = {QType::AXFR, QType::IXFR};
for (const auto& type : xfrTypes) {
bool dnssecOK = false;
InternalQueryState ids;