"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "pdns/dnsdist-console.cc" between
pdns-auth-4.1.13.tar.gz and pdns-auth-4.2.0.tar.gz

About: PowerDNS Authoritative Nameserver is a versatile nameserver which supports a large number of backends (that can either be plain zone files or be more dynamic in nature).

dnsdist-console.cc  (pdns-auth-4.1.13):dnsdist-console.cc  (pdns-auth-4.2.0)
skipping to change at line 22 skipping to change at line 22
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "dnsdist.hh"
#include "sodcrypto.hh"
#include "pwd.h"
#if defined (__OpenBSD__) #include <fstream>
#include <pwd.h>
#include <thread>
#if defined (__OpenBSD__) || defined(__NetBSD__)
#include <readline/readline.h> #include <readline/readline.h>
#include <readline/history.h> #include <readline/history.h>
#else #else
#include <editline/readline.h> #include <editline/readline.h>
#endif #endif
#include <fstream>
#include "dolog.hh"
#include "ext/json11/json11.hpp" #include "ext/json11/json11.hpp"
#include "dolog.hh"
#include "dnsdist.hh"
#include "dnsdist-console.hh"
#include "sodcrypto.hh"
#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_logConsoleConnections{true};
bool g_consoleEnabled{false};
uint32_t g_consoleOutputMsgMaxSize{10000000};
// MUST BE CALLED UNDER A LOCK - right now the LuaLock // MUST BE CALLED UNDER A LOCK - right now the LuaLock
void feedConfigDelta(const std::string& line) static void feedConfigDelta(const std::string& line)
{ {
if(line.empty()) if(line.empty())
return; return;
struct timeval now; struct timeval now;
gettimeofday(&now, 0); gettimeofday(&now, 0);
g_confDelta.push_back({now,line}); g_confDelta.push_back({now,line});
} }
string historyFile(const bool &ignoreHOME = false) static string historyFile(const bool &ignoreHOME = false)
{ {
string ret; string ret;
struct passwd pwd; struct passwd pwd;
struct passwd *result; struct passwd *result;
char buf[16384]; char buf[16384];
getpwuid_r(geteuid(), &pwd, buf, sizeof(buf), &result); getpwuid_r(geteuid(), &pwd, buf, sizeof(buf), &result);
const char *homedir = getenv("HOME"); const char *homedir = getenv("HOME");
if (result) if (result)
ret = string(pwd.pw_dir); ret = string(pwd.pw_dir);
if (homedir && !ignoreHOME) // $HOME overrides what the OS tells us if (homedir && !ignoreHOME) // $HOME overrides what the OS tells us
ret = string(homedir); ret = string(homedir);
if (ret.empty()) if (ret.empty())
ret = "."; // CWD if nothing works.. ret = "."; // CWD if nothing works..
ret.append("/.dnsdist_history"); ret.append("/.dnsdist_history");
return ret; return ret;
} }
static bool getMsgLen32(int fd, uint32_t* len)
try
{
uint32_t raw;
size_t ret = readn2(fd, &raw, sizeof raw);
if(ret != sizeof raw)
return false;
*len = ntohl(raw);
if(*len > g_consoleOutputMsgMaxSize)
return false;
return true;
}
catch(...) {
return false;
}
static bool putMsgLen32(int fd, uint32_t len)
try
{
uint32_t raw = htonl(len);
size_t ret = writen2(fd, &raw, sizeof raw);
return ret==sizeof raw;
}
catch(...) {
return false;
}
static bool sendMessageToServer(int fd, const std::string& line, SodiumNonce& re
adingNonce, SodiumNonce& writingNonce, const bool outputEmptyLine)
{
string msg = sodEncryptSym(line, g_consoleKey, writingNonce);
const auto msgLen = msg.length();
if (msgLen > std::numeric_limits<uint32_t>::max()) {
cout << "Encrypted message is too long to be sent to the server, "<< std::to
_string(msgLen) << " > " << std::numeric_limits<uint32_t>::max() << endl;
return true;
}
putMsgLen32(fd, static_cast<uint32_t>(msgLen));
if (!msg.empty()) {
writen2(fd, msg);
}
uint32_t len;
if(!getMsgLen32(fd, &len)) {
cout << "Connection closed by the server." << endl;
return false;
}
if (len == 0) {
if (outputEmptyLine) {
cout << endl;
}
return true;
}
boost::scoped_array<char> resp(new char[len]);
readn2(fd, resp.get(), len);
msg.assign(resp.get(), len);
msg = sodDecryptSym(msg, g_consoleKey, readingNonce);
cout << msg;
cout.flush();
return true;
}
void doClient(ComboAddress server, const std::string& command) void doClient(ComboAddress server, const std::string& command)
{ {
if(g_verbose) if (!sodIsValidKey(g_consoleKey)) {
cerr << "The currently configured console key is not valid, please configure
a valid key using the setKey() directive" << endl;
return;
}
if(g_verbose) {
cout<<"Connecting to "<<server.toStringWithPort()<<endl; cout<<"Connecting to "<<server.toStringWithPort()<<endl;
}
int fd=socket(server.sin4.sin_family, SOCK_STREAM, 0); int fd=socket(server.sin4.sin_family, SOCK_STREAM, 0);
if (fd < 0) { if (fd < 0) {
cerr<<"Unable to connect to "<<server.toStringWithPort()<<endl; cerr<<"Unable to connect to "<<server.toStringWithPort()<<endl;
return; return;
} }
SConnect(fd, server); SConnect(fd, server);
setTCPNoDelay(fd); setTCPNoDelay(fd);
SodiumNonce theirs, ours, readingNonce, writingNonce; SodiumNonce theirs, ours, readingNonce, writingNonce;
ours.init(); ours.init();
writen2(fd, (const char*)ours.value, sizeof(ours.value)); writen2(fd, (const char*)ours.value, sizeof(ours.value));
readn2(fd, (char*)theirs.value, sizeof(theirs.value)); readn2(fd, (char*)theirs.value, sizeof(theirs.value));
readingNonce.merge(ours, theirs); readingNonce.merge(ours, theirs);
writingNonce.merge(theirs, ours); writingNonce.merge(theirs, ours);
if(!command.empty()) { /* try sending an empty message, the server should send an empty
string msg=sodEncryptSym(command, g_key, writingNonce); one back. If it closes the connection instead, we are probably
putMsgLen32(fd, (uint32_t) msg.length()); having a key mismatch issue. */
if(!msg.empty()) if (!sendMessageToServer(fd, "", readingNonce, writingNonce, false)) {
writen2(fd, msg); cerr<<"The server closed the connection right away, likely indicating a key
uint32_t len; mismatch. Please check your setKey() directive."<<endl;
if(getMsgLen32(fd, &len)) { close(fd);
if (len > 0) { return;
boost::scoped_array<char> resp(new char[len]); }
readn2(fd, resp.get(), len);
msg.assign(resp.get(), len); if (!command.empty()) {
msg=sodDecryptSym(msg, g_key, readingNonce); sendMessageToServer(fd, command, readingNonce, writingNonce, false);
cout<<msg;
cout.flush();
}
}
else {
cout << "Connection closed by the server." << endl;
}
close(fd); close(fd);
return; return;
} }
string histfile = historyFile(); string histfile = historyFile();
set<string> dupper; set<string> dupper;
{ {
ifstream history(histfile); ifstream history(histfile);
string line; string line;
while(getline(history, line)) while(getline(history, line))
skipping to change at line 139 skipping to change at line 214
if(!line.empty() && line != lastline) { if(!line.empty() && line != lastline) {
add_history(sline); add_history(sline);
history << sline <<endl; history << sline <<endl;
history.flush(); history.flush();
} }
lastline=line; lastline=line;
free(sline); free(sline);
if(line=="quit") if(line=="quit")
break; break;
if(line=="help") if(line=="help" || line=="?")
line="help()"; line="help()";
/* no need to send an empty line to the server */ /* no need to send an empty line to the server */
if(line.empty()) if(line.empty())
continue; continue;
string msg=sodEncryptSym(line, g_key, writingNonce); if (!sendMessageToServer(fd, line, readingNonce, writingNonce, true)) {
putMsgLen32(fd, (uint32_t) msg.length());
writen2(fd, msg);
uint32_t len;
if(!getMsgLen32(fd, &len)) {
cout << "Connection closed by the server." << endl;
break; break;
} }
if (len > 0) {
boost::scoped_array<char> resp(new char[len]);
readn2(fd, resp.get(), len);
msg.assign(resp.get(), len);
msg=sodDecryptSym(msg, g_key, readingNonce);
cout<<msg;
cout.flush();
}
else {
cout<<endl;
}
} }
close(fd); close(fd);
} }
void doConsole() void doConsole()
{ {
string histfile = historyFile(true); string histfile = historyFile(true);
set<string> dupper; set<string> dupper;
{ {
ifstream history(histfile); ifstream history(histfile);
skipping to change at line 199 skipping to change at line 257
if(!line.empty() && line != lastline) { if(!line.empty() && line != lastline) {
add_history(sline); add_history(sline);
history << sline <<endl; history << sline <<endl;
history.flush(); history.flush();
} }
lastline=line; lastline=line;
free(sline); free(sline);
if(line=="quit") if(line=="quit")
break; break;
if(line=="help") if(line=="help" || line=="?")
line="help()"; line="help()";
string response; string response;
try { try {
bool withReturn=true; bool withReturn=true;
retry:; retry:;
try { try {
std::lock_guard<std::mutex> lock(g_luamutex); std::lock_guard<std::mutex> lock(g_luamutex);
g_outputBuffer.clear(); g_outputBuffer.clear();
resetLuaSideEffect(); resetLuaSideEffect();
skipping to change at line 287 skipping to change at line 345
} }
catch(const std::exception& e) { catch(const std::exception& e) {
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
} }
} }
} }
/**** CARGO CULT CODE AHEAD ****/ /**** CARGO CULT CODE AHEAD ****/
const std::vector<ConsoleKeyword> g_consoleKeywords{ const std::vector<ConsoleKeyword> g_consoleKeywords{
/* keyword, function, parameters, description */ /* keyword, function, parameters, description */
{ "addACL", true, "netmask", "add to the ACL set who can use this server" }, { "addACL", true, "netmask", "add to the ACL set who can use this server" },
{ "addAction", true, "DNS rule, DNS action", "add a rule" }, { "addAction", true, "DNS rule, DNS action [, {uuid=\"UUID\"}]", "add a rule"
{ "addAnyTCRule", true, "", "(deprecated) generate TC=1 answers to ANY queries },
received over UDP, moving them to TCP" }, { "addBPFFilterDynBlocks", true, "addresses, dynbpf[[, seconds=10], msg]", "Th
{ "addDelay", true, "domain, n", "(deprecated) delay answers within that domai is is the eBPF equivalent of addDynBlocks(), blocking a set of addresses for (op
n by n milliseconds" }, tionally) a number of seconds, using an eBPF dynamic filter" },
{ "addDisableValidationRule", true, "DNS rule", "(deprecated) set the CD flags { "addConsoleACL", true, "netmask", "add a netmask to the console ACL" },
to 1 for all queries matching the specified domain" }, { "addDNSCryptBind", true, "\"127.0.0.1:8443\", \"provider name\", \"/path/to/
{ "addDNSCryptBind", true, "\"127.0.0.1:8443\", \"provider name\", \"/path/to/ resolver.cert\", \"/path/to/resolver.key\", {reusePort=false, tcpFastOpenQueueSi
resolver.cert\", \"/path/to/resolver.key\", {reusePort=false, tcpFastOpenSize=0, ze=0, interface=\"\", cpus={}}", "listen to incoming DNSCrypt queries on 127.0.0
interface=\"\", cpus={}}", "listen to incoming DNSCrypt queries on 127.0.0.1 po .1 port 8443, with a provider name of `provider name`, using a resolver certific
rt 8443, with a provider name of `provider name`, using a resolver certificate a ate and associated key stored respectively in the `resolver.cert` and `resolver.
nd associated key stored respectively in the `resolver.cert` and `resolver.key` key` files. The fifth optional parameter is a table of parameters" },
files. The fifth optional parameter is a table of parameters" }, { "addDOHLocal", true, "addr, certFile, keyFile [, urls [, vars]]", "listen to
{ "addDomainBlock", true, "domain", "(deprecated) block queries within this do incoming DNS over HTTPS queries on the specified address using the specified ce
main" }, rtificate and key. The last two parameters are tables" },
{ "addDomainSpoof", true, "domain, ip[, ip6]", "(deprecated) generate answers
for A/AAAA/ANY queries using the ip parameters" },
{ "addDynBlocks", true, "addresses, message[, seconds[, action]]", "block the set of addresses with message `msg`, for `seconds` seconds (10 by default), appl ying `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), appl ying `action` (default to the one set with `setDynBlocksAction()`)" },
{ "addLocal", true, "addr [, {doTCP=true, reusePort=false, tcpFastOpenSize=0, { "addDynBlockSMT", true, "names, msessage[, seconds [, action]]", "block the
interface=\"\", cpus={}}]", "add `addr` to the list of addresses we listen on" } set of names with message `msg`, for `seconds` seconds (10 by default), applying
, `action` (default to the one set with `setDynBlocksAction()`)" },
{ "addLuaAction", true, "x, func", "where 'x' is all the combinations from `ad { "addLocal", true, "addr [, {doTCP=true, reusePort=false, tcpFastOpenQueueSiz
dAction`, and func is a function with the parameter `dq`, which returns an actio e=0, interface=\"\", cpus={}}]", "add `addr` to the list of addresses we listen
n to be taken on this packet. Good for rare packets but where you want to do a l on" },
ot of processing" }, { "addCacheHitResponseAction", true, "DNS rule, DNS response action [, {uuid=\
{ "addLuaResponseAction", true, "x, func", "where 'x' is all the combinations "UUID\"}]", "add a cache hit response rule" },
from `addAction`, and func is a function with the parameter `dr`, which returns { "addResponseAction", true, "DNS rule, DNS response action [, {uuid=\"UUID\"}
an action to be taken on this response packet. Good for rare packets but where y ]", "add a response rule" },
ou want to do a lot of processing" }, { "addSelfAnsweredResponseAction", true, "DNS rule, DNS response action [, {uu
{ "addNoRecurseRule", true, "domain", "(deprecated) clear the RD flag for all id=\"UUID\"}]", "add a self-answered response rule" },
queries matching the specified domain" }, { "addTLSLocal", true, "addr, certFile(s), keyFile(s) [,params]", "listen to i
{ "addPoolRule", true, "domain, pool", "(deprecated) send queries to this doma ncoming DNS over TLS queries on the specified address using the specified certif
in to that pool" }, icate (or list of) and key (or list of). The last parameter is a table" },
{ "addQPSLimit", true, "domain, n", "(deprecated) limit queries within that do
main to n per second" },
{ "addQPSPoolRule", true, "x, limit, pool", "(deprecated) like `addPoolRule`,
but only select at most 'limit' queries/s for this pool, letting the subsequent
rules apply otherwise" },
{ "addCacheHitResponseAction", true, "DNS rule, DNS response action", "add a c
ache hit response rule" },
{ "addResponseAction", true, "DNS rule, DNS response action", "add a response
rule" },
{ "AllowAction", true, "", "let these packets go through" }, { "AllowAction", true, "", "let these packets go through" },
{ "AllowResponseAction", true, "", "let these packets go through" }, { "AllowResponseAction", true, "", "let these packets go through" },
{ "AllRule", true, "", "matches all traffic" }, { "AllRule", true, "", "matches all traffic" },
{ "AndRule", true, "list of DNS rules", "matches if all sub-rules matches" }, { "AndRule", true, "list of DNS rules", "matches if all sub-rules matches" },
{ "benchRule", true, "DNS Rule [, iterations [, suffix]]", "bench the specifie d DNS rule" }, { "benchRule", true, "DNS Rule [, iterations [, suffix]]", "bench the specifie d DNS rule" },
{ "carbonServer", true, "serverIP, [ourname], [interval]", "report statistics to serverIP using our hostname, or 'ourname' if provided, every 'interval' secon ds" }, { "carbonServer", true, "serverIP, [ourname], [interval]", "report statistics to serverIP using our hostname, or 'ourname' if provided, every 'interval' secon ds" },
{ "controlSocket", true, "addr", "open a control socket on this address / conn ect to this address in client mode" }, { "controlSocket", true, "addr", "open a control socket on this address / conn ect to this address in client mode" },
{ "clearDynBlocks", true, "", "clear all dynamic blocks" }, { "clearDynBlocks", true, "", "clear all dynamic blocks" },
{ "clearQueryCounters", true, "", "clears the query counter buffer" }, { "clearQueryCounters", true, "", "clears the query counter buffer" },
{ "clearRules", true, "", "remove all current rules" }, { "clearRules", true, "", "remove all current rules" },
{ "DelayAction", true, "milliseconds", "delay the response by the specified am ount of milliseconds (UDP-only)" }, { "DelayAction", true, "milliseconds", "delay the response by the specified am ount of milliseconds (UDP-only)" },
{ "DelayResponseAction", true, "milliseconds", "delay the response by the spec ified amount of milliseconds (UDP-only)" }, { "DelayResponseAction", true, "milliseconds", "delay the response by the spec ified amount of milliseconds (UDP-only)" },
{ "delta", true, "", "shows all commands entered that changed the configuratio n" }, { "delta", true, "", "shows all commands entered that changed the configuratio n" },
{ "DisableECSAction", true, "", "Disable the sending of ECS to the backend. Su bsequent rules are processed after this action." },
{ "DisableValidationAction", true, "", "set the CD bit in the question, let it go through" }, { "DisableValidationAction", true, "", "set the CD bit in the question, let it go through" },
{ "DNSSECRule", true, "", "matches queries with the DO bit set" },
{ "DnstapLogAction", true, "identity, FrameStreamLogger [, alterFunction]", "s
end the contents of this query to a FrameStreamLogger or RemoteLogger as dnstap.
`alterFunction` is a callback, receiving a DNSQuestion and a DnstapMessage, tha
t can be used to modify the dnstap message" },
{ "DnstapLogResponseAction", true, "identity, FrameStreamLogger [, alterFuncti
on]", "send the contents of this response to a remote or FrameStreamLogger or Re
moteLogger 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" }, { "DropAction", true, "", "drop these packets" },
{ "DropResponseAction", 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" }, { "dumpStats", true, "", "print all statistics we gather" },
{ "dynBlockRulesGroup", true, "", "return a new DynBlockRulesGroup object" },
{ "ECSOverrideAction", true, "override", "Whether an existing EDNS Client Subn
et value should be overridden (true) or not (false). Subsequent rules are proces
sed after this action" },
{ "ECSPrefixLengthAction", true, "v4, v6", "Set the ECS prefix length. Subsequ
ent rules are processed after this action" },
{ "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" }, { "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" }, { "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 exc eed `rate` queries/s for queries of type `type` over `seconds` seconds" }, { "exceedQTypeRate", true, "type, rate, seconds", "get set of address that exc eed `rate` queries/s for queries of type `type` over `seconds` seconds" },
{ "exceedRespByterate", true, "rate, seconds", "get set of addresses that exce eded `rate` bytes/s answers over `seconds` seconds" }, { "exceedRespByterate", true, "rate, seconds", "get set of addresses that exce eded `rate` bytes/s answers over `seconds` seconds" },
{ "exceedServFails", true, "rate, seconds", "get set of addresses that exceed `rate` servfails/s 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" }, { "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 u seful when you have a downstream server that messes up the case of the question qname in the answer" }, { "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 u seful when you have a downstream server that messes up the case of the question qname in the answer" },
{ "generateDNSCryptCertificate", true, "\"/path/to/providerPrivate.key\", \"/p ath/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 priva te key" }, { "generateDNSCryptCertificate", true, "\"/path/to/providerPrivate.key\", \"/p ath/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 priva te key" },
{ "generateDNSCryptProviderKeys", true, "\"/path/to/providerPublic.key\", \"/p ath/to/providerPrivate.key\"", "generate a new provider keypair" }, { "generateDNSCryptProviderKeys", true, "\"/path/to/providerPublic.key\", \"/p ath/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" }, { "getBind", true, "n", "returns the listener at index n" },
{ "getDNSCryptBind", true, "n", "return the `DNSCryptContext` object correspon ding to the bind `n`" }, { "getDNSCryptBind", true, "n", "return the `DNSCryptContext` object correspon ding to the bind `n`" },
{ "getDOHFrontend", true, "n", "returns the DOH frontend with index n" },
{ "getPool", true, "name", "return the pool named `name`, or \"\" for the defa ult pool" }, { "getPool", true, "name", "return the pool named `name`, or \"\" for the defa ult pool" },
{ "getPoolServers", true, "pool", "return servers part of this pool" }, { "getPoolServers", true, "pool", "return servers part of this pool" },
{ "getQueryCounters", true, "[max=10]", "show current buffer of query counters , limited by 'max' if provided" }, { "getQueryCounters", true, "[max=10]", "show current buffer of query counters , limited by 'max' if provided" },
{ "getResponseRing", true, "", "return the current content of the response rin g" }, { "getResponseRing", true, "", "return the current content of the response rin g" },
{ "getRespRing", true, "", "return the qname/rcode content of the response rin g" },
{ "getServer", true, "n", "returns server with index n" }, { "getServer", true, "n", "returns server with index n" },
{ "getServers", true, "", "returns a table with all defined servers" }, { "getServers", true, "", "returns a table with all defined servers" },
{ "getStatisticsCounters", true, "", "returns a map of statistic counters" },
{ "getTLSContext", true, "n", "returns the TLS context with index n" },
{ "getTLSFrontend", true, "n", "returns the TLS frontend with index n" },
{ "HTTPHeaderRule", true, "name, regex", "matches DoH queries with a HTTP head
er 'name' whose content matches the regular expression 'regex'"},
{ "HTTPPathRule", true, "path", "matches DoH queries whose HTTP path is an exa
ct match to 'path'"},
{ "inClientStartup", true, "", "returns true during console client parsing of
configuration" },
{ "includeDirectory", true, "path", "nclude configuration files from `path`" }
,
{ "grepq", true, "Netmask|DNS Name|100ms|{\"::1\", \"powerdns.com\", \"100ms\" } [, n]", "shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms" }, { "grepq", true, "Netmask|DNS Name|100ms|{\"::1\", \"powerdns.com\", \"100ms\" } [, n]", "shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms" },
{ "leastOutstanding", false, "", "Send traffic to downstream server with least outstanding queries, with the lowest 'order', and within that the lowest recent latency"}, { "leastOutstanding", false, "", "Send traffic to downstream server with least outstanding queries, with the lowest 'order', and within that the lowest recent latency"},
{ "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 whe ther we log in binary form (default) or in textual form, the `append` optional p arameter 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." }, { "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 whe ther we log in binary form (default) or in textual form, the `append` optional p arameter 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 DNSQues
tion" },
{ "LuaResponseAction", true, "function", "Invoke a Lua function that accepts a
DNSResponse" },
{ "MacAddrAction", true, "option", "Add the source MAC address to the query as
EDNS0 option option. This action is currently only supported on Linux. Subseque
nt rules are processed after this action" },
{ "makeIPCipherKey", true, "password", "generates a 16-byte key that can be us
ed to pseudonymize IP addresses with IP cipher" },
{ "makeKey", true, "", "generate a new server access key, emit configuration l ine ready for pasting" }, { "makeKey", true, "", "generate a new server access key, emit configuration l ine ready for pasting" },
{ "MaxQPSIPRule", true, "qps, v4Mask=32, v6Mask=64, burst=qps", "matches traff { "makeRule", true, "rule", "Make a NetmaskGroupRule() or a SuffixMatchNodeRul
ic exceeding the qps limit per subnet" }, e(), depending on how it is called" } ,
{ "MaxQPSIPRule", true, "qps, [v4Mask=32 [, v6Mask=64 [, burst=qps [, expirati
on=300 [, cleanupDelay=60]]]]]", "matches traffic exceeding the qps limit per su
bnet" },
{ "MaxQPSRule", true, "qps", "matches traffic **not** exceeding this qps limit " }, { "MaxQPSRule", true, "qps", "matches traffic **not** exceeding this qps limit " },
{ "mvCacheHitResponseRule", true, "from, to", "move cache hit response rule 'f rom' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" }, { "mvCacheHitResponseRule", true, "from, to", "move cache hit response rule 'f rom' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" },
{ "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" }, { "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" },
{ "mvRule", true, "from, to", "move rule 'from' to a position where it is in f ront of 'to'. 'to' can be one larger than the largest rule, in which case the ru le will be moved to the last position" }, { "mvRule", true, "from, to", "move rule 'from' to a position where it is in f ront of 'to'. 'to' can be one larger than the largest rule, in which case the ru le will be moved to the last 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" },
{ "NetmaskGroupRule", true, "nmg[, src]", "Matches traffic from/to the network
range specified in nmg. Set the src parameter to false to match nmg against des
tination address instead of source address. This can be used to differentiate be
tween clients" },
{ "newBPFFilter", true, "maxV4, maxV6, maxQNames", "Return a new eBPF socket f
ilter with a maximum of maxV4 IPv4, maxV6 IPv6 and maxQNames qname entries in th
e block table" },
{ "newCA", true, "address", "Returns a ComboAddress based on `address`" },
{ "newDNSName", true, "name", "make a DNSName based on this .-terminated name" }, { "newDNSName", true, "name", "make a DNSName based on this .-terminated name" },
{ "newPacketCache", true, "maxEntries[, maxTTL=86400, minTTL=0, temporaryFailu { "newDNSNameSet", true, "", "returns a new DNSNameSet" },
reTTL=60, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=tru { "newDynBPFFilter", true, "bpf", "Return a new dynamic eBPF filter associated
e]", "return a new Packet Cache" }, to a given BPF Filter" },
{ "newFrameStreamTcpLogger", true, "addr", "create a FrameStream logger object
writing to a TCP address (addr should be ip:port), to use with `DnstapLogAction
()` and `DnstapLogResponseAction()`" },
{ "newFrameStreamUnixLogger", true, "socket", "create a FrameStream logger obj
ect writing to a local unix socket, to use with `DnstapLogAction()` and `DnstapL
ogResponseAction()`" },
{ "newNMG", true, "", "Returns a NetmaskGroup" },
{ "newPacketCache", true, "maxEntries[, maxTTL=86400, minTTL=0, temporaryFailu
reTTL=60, staleTTL=60, dontAge=false, numberOfShards=1, deferrableInsertLock=tru
e, options={}]", "return a new Packet Cache" },
{ "newQPSLimiter", true, "rate, burst", "configure a QPS limiter with that rat e and that burst capacity" }, { "newQPSLimiter", true, "rate, burst", "configure a QPS limiter with that rat e and that burst capacity" },
{ "newRemoteLogger", true, "address:port [, timeout=2, maxQueuedEntries=100, r econnectWaitTime=1]", "create a Remote Logger object, to use with `RemoteLogActi on()` and `RemoteLogResponseAction()`" }, { "newRemoteLogger", true, "address:port [, timeout=2, maxQueuedEntries=100, r econnectWaitTime=1]", "create a Remote Logger object, to use with `RemoteLogActi on()` and `RemoteLogResponseAction()`" },
{ "newRuleAction", true, "DNS rule, DNS action", "return a pair of DNS Rule an { "newRuleAction", true, "DNS rule, DNS action [, {uuid=\"UUID\"}]", "return a
d DNS Action, to be used with `setRules()`" }, pair of DNS Rule and DNS Action, to be used with `setRules()`" },
{ "newServer", true, "{address=\"ip:port\", qps=1000, order=1, weight=10, pool { "newServer", true, "{address=\"ip:port\", qps=1000, order=1, weight=10, pool
=\"abuse\", retries=5, tcpConnectTimeout=5, tcpSendTimeout=30, tcpRecvTimeout=30 =\"abuse\", retries=5, tcpConnectTimeout=5, tcpSendTimeout=30, tcpRecvTimeout=30
, checkName=\"a.root-servers.net.\", checkType=\"A\", maxCheckFailures=1, mustRe , checkName=\"a.root-servers.net.\", checkType=\"A\", maxCheckFailures=1, mustRe
solve=false, useClientSubnet=true, source=\"address|interface name|address@inter solve=false, useClientSubnet=true, source=\"address|interface name|address@inter
face\"}", "instantiate a server" }, face\", sockets=1}", "instantiate a server" },
{ "newServerPolicy", true, "name, function", "create a policy object from a Lu a function" }, { "newServerPolicy", true, "name, function", "create a policy object from a Lu a function" },
{ "newSuffixMatchNode", true, "", "returns a new SuffixMatchNode" }, { "newSuffixMatchNode", true, "", "returns a new SuffixMatchNode" },
{ "NoneAction", true, "", "Does nothing. Subsequent rules are processed after this action" },
{ "NoRecurseAction", true, "", "strip RD bit from the question, let it go thro ugh" }, { "NoRecurseAction", true, "", "strip RD bit from the question, let it go thro ugh" },
{ "NotRule", true, "selector", "Matches the traffic if the selector rule does
not match" },
{ "OpcodeRule", true, "code", "Matches queries with opcode code. code can be d
irectly 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", "set the packet into the specified pool" }, { "PoolAction", true, "poolname", "set the packet into the specified pool" },
{ "PoolAvailableRule", true, "poolname", "Check whether a pool has any servers available to handle queries" },
{ "printDNSCryptProviderFingerprint", true, "\"/path/to/providerPublic.key\"", "display the fingerprint of the provided resolver public key" }, { "printDNSCryptProviderFingerprint", true, "\"/path/to/providerPublic.key\"", "display the fingerprint of the provided resolver public key" },
{ "RegexRule", true, "regex", "matches the query name against the supplied reg { "ProbaRule", true, "probability", "Matches queries with a given probability.
ex" }, 1.0 means always" },
{ "registerDynBPFFilter", true, "DynBPFFilter", "register this dynamic BPF fil { "QClassRule", true, "qclass", "Matches queries with the specified qclass. cl
ter into the web interface so that its counters are displayed" }, ass can be specified as an integer or as one of the built-in DNSClass" },
{ "RemoteLogAction", true, "RemoteLogger [, alterFunction]", "send the content
of this query to a remote logger via Protocol Buffer. `alterFunction` is a call
back, receiving a DNSQuestion and a DNSDistProtoBufMessage, that can be used to
modify the Protocol Buffer content, for example for anonymization purposes" },
{ "RemoteLogResponseAction", true, "RemoteLogger [,alterFunction [,includeCNAM
E]]", "send the content of this response to a remote logger via Protocol Buffer.
`alterFunction` is the same callback than the one in `RemoteLogAction` and `inc
ludeCNAME` indicates whether CNAME records inside the response should be parsed
and exported. The default is to only exports A and AAAA records" },
{ "rmCacheHitResponseRule", true, "n", "remove cache hit response rule n" },
{ "rmResponseRule", true, "n", "remove response rule n" },
{ "rmRule", true, "n", "remove rule n" },
{ "rmServer", true, "n", "remove server with index n" },
{ "roundrobin", false, "", "Simple round robin over available servers" },
{ "QNameLabelsCountRule", true, "min, max", "matches if the qname has less tha n `min` or more than `max` labels" }, { "QNameLabelsCountRule", true, "min, max", "matches if the qname has less tha n `min` or more than `max` labels" },
{ "QNameRule", true, "qname", "matches queries with the specified qname" }, { "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 t he wire is less than `min` or more than `max` bytes" }, { "QNameWireLengthRule", true, "min, max", "matches if the qname's length on t he wire is less than `min` or more than `max` bytes" },
{ "QPSAction", true, "maxqps", "Drop a packet if it does exceed the maxqps que
ries per second limits. Letting the subsequent rules apply otherwise" },
{ "QPSPoolAction", true, "maxqps, poolname", "Send the packet into the specifi
ed 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" }, { "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" }, { "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 i
s 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 reg
ex" },
{ "registerDynBPFFilter", true, "DynBPFFilter", "register this dynamic BPF fil
ter 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]]", "sen
d the content of this query to a remote logger via Protocol Buffer. `alterFuncti
on` is a callback, receiving a DNSQuestion and a DNSDistProtoBufMessage, that ca
n be used to modify the Protocol Buffer content, for example for anonymization p
urposes. `serverID` is the server identifier." },
{ "RemoteLogResponseAction", true, "RemoteLogger [,alterFunction [,includeCNAM
E [, serverID]]]", "send the content of this response to a remote logger via Pro
tocol Buffer. `alterFunction` is the same callback than the one in `RemoteLogAct
ion` and `includeCNAME` indicates whether CNAME records inside the response shou
ld be parsed and exported. The default is to only exports A and AAAA records. `s
erverID` is the server identifier." },
{ "rmCacheHitResponseRule", true, "id", "remove cache hit response rule in pos
ition 'id', or whose uuid matches if 'id' is an UUID string" },
{ "rmResponseRule", true, "id", "remove response rule in position 'id', or who
se uuid matches if 'id' is an UUID string" },
{ "rmRule", true, "id", "remove rule in position 'id', or whose uuid matches i
f 'id' is an UUID string" },
{ "rmSelfAnsweredResponseRule", true, "id", "remove self-answered response rul
e in position 'id', or whose uuid matches if 'id' is an UUID string" },
{ "rmServer", true, "n", "remove server with index n" },
{ "roundrobin", false, "", "Simple round robin over available servers" },
{ "sendCustomTrap", true, "str", "send a custom `SNMP` trap from Lua, containi ng the `str` string"}, { "sendCustomTrap", true, "str", "send a custom `SNMP` trap from Lua, containi ng the `str` string"},
{ "setACL", true, "{netmask, netmask}", "replace the ACL set with these netmas ks. Use `setACL({})` to reset the list, meaning no one can use us" }, { "setACL", true, "{netmask, netmask}", "replace the ACL set with these netmas ks. Use `setACL({})` to reset the list, meaning no one can use us" },
{ "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) fro
m backends" },
{ "setAPIWritable", true, "bool, dir", "allow modifications via the API. if `d ir` is set, it must be a valid directory where the configuration files will be w ritten by the API" }, { "setAPIWritable", true, "bool, dir", "allow modifications via the API. if `d ir` is set, it must be a valid directory where the configuration files will be w ritten by the API" },
{ "setCacheCleaningDelay", true, "num", "Set the interval in seconds between t
wo 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" },
{ "setConsoleACL", true, "{netmask, netmask}", "replace the console ACL set wi
th these netmasks" },
{ "setConsoleConnectionsLogging", true, "enabled", "whether to log the opening and closing of console connections" }, { "setConsoleConnectionsLogging", true, "enabled", "whether to log the opening and closing of console connections" },
{ "setDNSSECPool", true, "pool name", "move queries requesting DNSSEC processi { "setConsoleOutputMaxMsgSize", true, "messageSize", "set console message maxi
ng to this pool" }, mum size in bytes, default is 10 MB" },
{ "setDefaultBPFFilter", true, "filter", "When used at configuration time, the
corresponding BPFFilter will be attached to every bind" },
{ "setDynBlocksAction", true, "action", "set which action is performed when a query is blocked. Only DNSAction.Drop (the default) and DNSAction.Refused are su pported" }, { "setDynBlocksAction", true, "action", "set which action is performed when a query is blocked. Only DNSAction.Drop (the default) and DNSAction.Refused are su pported" },
{ "SetECSAction", true, "v4[, v6]", "Set the ECS prefix and prefix length sent to backends to an arbitrary value" },
{ "setECSOverride", true, "bool", "whether to override an existing EDNS Client Subnet value in the query" }, { "setECSOverride", true, "bool", "whether to override an existing EDNS Client Subnet value in the query" },
{ "setECSSourcePrefixV4", true, "prefix-length", "the EDNS Client Subnet prefi x-length used for IPv4 queries" }, { "setECSSourcePrefixV4", true, "prefix-length", "the EDNS Client Subnet prefi x-length used for IPv4 queries" },
{ "setECSSourcePrefixV6", true, "prefix-length", "the EDNS Client Subnet prefi x-length used for IPv6 queries" }, { "setECSSourcePrefixV6", true, "prefix-length", "the EDNS Client Subnet prefi x-length used for IPv6 queries" },
{ "setKey", true, "key", "set access key to that key" }, { "setKey", true, "key", "set access key to that key" },
{ "setLocal", true, "addr [, {doTCP=true, reusePort=false, tcpFastOpenSize=0, interface=\"\", cpus={}}]", "reset the list of addresses we listen on to this ad dress" }, { "setLocal", true, "addr [, {doTCP=true, reusePort=false, tcpFastOpenQueueSiz e=0, interface=\"\", cpus={}}]", "reset the list of addresses we listen on to th is address" },
{ "setMaxTCPClientThreads", true, "n", "set the maximum of TCP client threads, handling TCP connections" }, { "setMaxTCPClientThreads", true, "n", "set the maximum of TCP client threads, handling TCP connections" },
{ "setMaxTCPConnectionDuration", true, "n", "set the maximum duration of an in coming TCP connection, in seconds. 0 means unlimited" }, { "setMaxTCPConnectionDuration", true, "n", "set the maximum duration of an in coming TCP connection, in seconds. 0 means unlimited" },
{ "setMaxTCPConnectionsPerClient", true, "n", "set the maximum number of TCP c onnections per client. 0 means unlimited" }, { "setMaxTCPConnectionsPerClient", true, "n", "set the maximum number of TCP c onnections per client. 0 means unlimited" },
{ "setMaxTCPQueriesPerConnection", true, "n", "set the maximum number of queri es in an incoming TCP connection. 0 means unlimited" }, { "setMaxTCPQueriesPerConnection", true, "n", "set the maximum number of queri es in an incoming TCP connection. 0 means unlimited" },
{ "setMaxTCPQueuedConnections", true, "n", "set the maximum number of TCP conn ections queued (waiting to be picked up by a client thread)" }, { "setMaxTCPQueuedConnections", true, "n", "set the maximum number of TCP conn ections queued (waiting to be picked up by a client thread)" },
{ "setMaxUDPOutstanding", true, "n", "set the maximum number of outstanding UD P queries to a given backend server. This can only be set at configuration time and defaults to 10240" }, { "setMaxUDPOutstanding", true, "n", "set the maximum number of outstanding UD P queries to a given backend server. This can only be set at configuration time and defaults to 10240" },
{ "setPayloadSizeOnSelfGeneratedAnswers", true, "payloadSize", "set the UDP pa yload size advertised via EDNS on self-generated responses" },
{ "setPoolServerPolicy", true, "policy, pool", "set the server selection polic y for this pool to that policy" }, { "setPoolServerPolicy", true, "policy, pool", "set the server selection polic y for this pool to that policy" },
{ "setPoolServerPolicy", true, "name, func, pool", "set the server selection p { "setPoolServerPolicyLua", true, "name, func, pool", "set the server selectio
olicy for this pool to one named 'name' and provided by 'function'" }, n policy for this pool to one named 'name' and provided by 'function'" },
{ "setPreserveTrailingData", true, "bool", "set whether trailing data should b
e preserved while adding ECS or XPF records to incoming queries" },
{ "setQueryCount", true, "bool", "set whether queries should be counted" }, { "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 sho uld and how it 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 sho uld and how it should be counted" },
{ "setRingBuffersSize", true, "n", "set the capacity of the ringbuffers used f { "setRingBuffersLockRetries", true, "n", "set the number of attempts to get a
or live traffic inspection to `n`" }, non-blocking lock to a ringbuffer shard before blocking" },
{ "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 loa
d-balancing policy will still try to select a backend even if all backends are c
urrently 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 suppl ied list of pairs of DNS Rules and DNS Actions (see `newRuleAction()`)" }, { "setRules", true, "list of rules", "replace the current rules with the suppl ied 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 poli cy" }, { "setServerPolicy", true, "policy", "set server selection policy to that poli cy" },
{ "setServerPolicyLua", true, "name, function", "set server selection policy t o one named 'name' and provided by 'function'" }, { "setServerPolicyLua", true, "name, function", "set server selection policy t o one named 'name' and provided by 'function'" },
{ "setServFailWhenNoServer", true, "bool", "if set, return a ServFail when no servers are available, instead of the default behaviour of dropping the query" } , { "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 fo r at most n seconds when there is no backend available to answer for a query" }, { "setStaleCacheEntriesTTL", true, "n", "allows using cache entries expired fo r at most n seconds when there is no backend available to answer for a query" },
{ "setSyslogFacility", true, "facility", "set the syslog logging facility to ' facility'. Defaults to LOG_DAEMON" },
{ "setTCPDownstreamCleanupInterval", true, "interval", "minimum interval in se conds between two cleanups of the idle TCP downstream connections" }, { "setTCPDownstreamCleanupInterval", true, "interval", "minimum interval in se conds between two cleanups of the idle TCP downstream connections" },
{ "setTCPUseSinglePipe", true, "bool", "whether the incoming TCP connections s hould be put into a single queue instead of using per-thread queues. Defaults to false" }, { "setTCPUseSinglePipe", true, "bool", "whether the incoming TCP connections s hould be put into a single queue instead of using per-thread queues. Defaults to false" },
{ "setTCPRecvTimeout", true, "n", "set the read timeout on TCP connections fro m the client, in seconds" }, { "setTCPRecvTimeout", true, "n", "set the read timeout on TCP connections fro m the client, in seconds" },
{ "setTCPSendTimeout", true, "n", "set the write timeout on TCP connections fr om the client, in seconds" }, { "setTCPSendTimeout", true, "n", "set the write timeout on TCP connections fr om the client, in seconds" },
{ "setUDPMultipleMessagesVectorSize", true, "n", "set the size of the vector p assed to recvmmsg() to receive UDP messages. Default to 1 which means that the f eature is disabled and recvmsg() is used instead" }, { "setUDPMultipleMessagesVectorSize", true, "n", "set the size of the vector p assed to recvmmsg() to receive UDP messages. Default to 1 which means that the f eature is disabled and recvmsg() is used instead" },
{ "setUDPTimeout", true, "n", "set the maximum time dnsdist will wait for a re sponse from a backend over UDP, in seconds" }, { "setUDPTimeout", true, "n", "set the maximum time dnsdist will wait for a re sponse from a backend over UDP, in seconds" },
{ "setVerboseHealthChecks", true, "bool", "set whether health check errors wil l be logged" }, { "setVerboseHealthChecks", true, "bool", "set whether health check errors wil l be logged" },
{ "setWebserverConfig", true, "[{password=string, apiKey=string, customHeaders
}]", "Updates webserver configuration" },
{ "setWHashedPertubation", true, "value", "Set the hash perturbation value to
be used in the whashed policy instead of a random one, allowing to have consiste
nt whashed results on different instance" },
{ "show", true, "string", "outputs `string`" }, { "show", true, "string", "outputs `string`" },
{ "showACL", true, "", "show our ACL set" }, { "showACL", true, "", "show our ACL set" },
{ "showBinds", true, "", "show listening addresses (frontends)" }, { "showBinds", true, "", "show listening addresses (frontends)" },
{ "showCacheHitResponseRules", true, "", "show all defined cache hit response { "showCacheHitResponseRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}
rules" }, ]", "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 bi nds" }, { "showDNSCryptBinds", true, "", "display the currently configured DNSCrypt bi nds" },
{ "showDOHFrontends", true, "", "list all the available DOH frontends" },
{ "showDynBlocks", true, "", "show dynamic blocks in force" }, { "showDynBlocks", true, "", "show dynamic blocks in force" },
{ "showPools", true, "", "show the available pools" }, { "showPools", true, "", "show the available pools" },
{ "showPoolServerPolicy", true, "pool", "show server selection policy for this pool" }, { "showPoolServerPolicy", true, "pool", "show server selection policy for this pool" },
{ "showResponseLatency", true, "", "show a plot of the response time latency d istribution" }, { "showResponseLatency", true, "", "show a plot of the response time latency d istribution" },
{ "showResponseRules", true, "", "show all defined response rules" }, { "showResponseRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "sho
{ "showRules", true, "", "show all defined rules" }, w all defined response rules, optionally with their UUIDs and optionally truncat
ed to a given width" },
{ "showRules", true, "[{showUUIDs=false, truncateRuleWidth=-1}]", "show all de
fined rules, optionally with their UUIDs and optionally truncated to a given wid
th" },
{ "showSecurityStatus", true, "", "Show the security status"},
{ "showSelfAnsweredResponseRules", true, "[{showUUIDs=false, truncateRuleWidth
=-1}]", "show all defined self-answered response rules, optionally with their UU
IDs and optionally truncated to a given width" },
{ "showServerPolicy", true, "", "show name of currently operational server sel ection policy" }, { "showServerPolicy", true, "", "show name of currently operational server sel ection policy" },
{ "showServers", true, "", "output all servers" }, { "showServers", true, "[{showUUIDs=false}]", "output all servers, optionally with their UUIDs" },
{ "showTCPStats", true, "", "show some statistics regarding TCP" }, { "showTCPStats", true, "", "show some statistics regarding TCP" },
{ "showTLSContexts", true, "", "list all the available TLS contexts" },
{ "showVersion", true, "", "show the current version" }, { "showVersion", true, "", "show the current version" },
{ "shutdown", true, "", "shut down `dnsdist`" }, { "shutdown", true, "", "shut down `dnsdist`" },
{ "SkipCacheAction", true, "", "Don’t lookup the cache for this query, don’t s
tore the answer" },
{ "SNIRule", true, "name", "Create a rule which matches on the incoming TLS SN
I value, if any (DoT or DoH)" },
{ "snmpAgent", true, "enableTraps [, masterSocket]", "enable `SNMP` support. ` enableTraps` is a boolean indicating whether traps should be sent and `masterSoc ket` an optional string specifying how to connect to the master agent"}, { "snmpAgent", true, "enableTraps [, masterSocket]", "enable `SNMP` support. ` enableTraps` is a boolean indicating whether traps should be sent and `masterSoc ket` an optional string specifying how to connect to the master agent"},
{ "SNMPTrapAction", true, "[reason]", "send an SNMP trap, adding the optional `reason` string as the query description"}, { "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 o ptional `reason` string as the response description"}, { "SNMPTrapResponseAction", true, "[reason]", "send an SNMP trap, adding the o ptional `reason` string as the response description"},
{ "SpoofAction", true, "{ip, ...} ", "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" }, { "SpoofAction", true, "{ip, ...} ", "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", "Forge a response with the specified CNAM
E value" },
{ "SuffixMatchNodeRule", true, "smn[, quiet]", "Matches based on a group of do
main suffixes for rapid testing of membership. Pass true as second parameter to
prevent listing of all domains matched" },
{ "TagAction", true, "name, value", "set the tag named 'name' to the given val
ue" },
{ "TagResponseAction", true, "name, value", "set the tag named 'name' to the g
iven value" },
{ "TagRule", true, "name [, value]", "matches if the tag named 'name' is prese
nt, with the given 'value' matching if any" },
{ "TCAction", true, "", "create answer to query with TC and RD bits set, to mo ve to TCP" }, { "TCAction", true, "", "create answer to query with TC and RD bits set, to mo ve to TCP" },
{ "TCPRule", true, "[tcp]", "Matches question received over TCP if tcp is true
, over UDP otherwise" },
{ "TeeAction", true, "remote [, addECS]", "send copy of query to remote, optio
nally adding ECS info" },
{ "TempFailureCacheTTLAction", true, "ttl", "set packetcache TTL for temporary
failure replies" },
{ "testCrypto", true, "", "test of the crypto all works" }, { "testCrypto", true, "", "test of the crypto all works" },
{ "TimedIPSetRule", true, "", "Create a rule which matches a set of IP address es which expire"}, { "TimedIPSetRule", true, "", "Create a rule which matches a set of IP address es which expire"},
{ "topBandwidth", true, "top", "show top-`top` clients that consume the most b andwidth over length of ringbuffer" }, { "topBandwidth", true, "top", "show top-`top` clients that consume the most b andwidth over length of ringbuffer" },
{ "topCacheHitResponseRule", true, "", "move the last cache hit response rule to the first position" }, { "topCacheHitResponseRule", true, "", "move the last cache hit response rule to the first position" },
{ "topClients", true, "n", "show top-`n` clients sending the most queries over length of ringbuffer" }, { "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 op tionally cut down to 'labels' labels" }, { "topQueries", true, "n[, labels]", "show top 'n' queries, as grouped when op tionally cut down to 'labels' labels" },
{ "topResponses", true, "n, kind[, labels]", "show top 'n' responses with RCOD E=kind (0=NO Error, 2=ServFail, 3=ServFail), as grouped when optionally cut down to 'labels' labels" }, { "topResponses", true, "n, kind[, labels]", "show top 'n' responses with RCOD E=kind (0=NO Error, 2=ServFail, 3=ServFail), as grouped when optionally cut down to 'labels' labels" },
{ "topResponseRule", true, "", "move the last response rule to the first posit ion" }, { "topResponseRule", true, "", "move the last response rule to the first posit ion" },
{ "topRule", true, "", "move the last rule to the first position" }, { "topRule", true, "", "move the last rule to the first position" },
{ "topSelfAnsweredResponseRule", true, "", "move the last self-answered respon se rule to the first position" },
{ "topSlow", true, "[top][, limit][, labels]", "show `top` queries slower than `limit` milliseconds, grouped by last `labels` labels" }, { "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 PowerD NS Authoritative Server 2.9.22. Note: turning this on breaks compatibility with RFC 6891." }, { "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 PowerD NS Authoritative Server 2.9.22. Note: turning this on breaks compatibility with RFC 6891." },
{ "unregisterDynBPFFilter", true, "DynBPFFilter", "unregister this dynamic BPF filter" }, { "unregisterDynBPFFilter", true, "DynBPFFilter", "unregister this dynamic BPF filter" },
{ "webserver", true, "address:port, password [, apiKey [, customHeaders ]])", "launch a webserver with stats on that address with that password" }, { "webserver", true, "address:port, password [, apiKey [, customHeaders ]])", "launch a webserver with stats on that address with that password" },
{ "whashed", false, "", "Weighted hashed ('sticky') distribution over availabl e servers, based on the server 'weight' parameter" }, { "whashed", false, "", "Weighted hashed ('sticky') distribution over availabl e servers, based on the server 'weight' parameter" },
{ "chashed", false, "", "Consistent hashed ('sticky') distribution over availa ble servers, also based on the server 'weight' parameter" },
{ "wrandom", false, "", "Weighted random over available servers, based on the server 'weight' parameter" }, { "wrandom", false, "", "Weighted random over available servers, based on the server 'weight' parameter" },
}; };
extern "C" { extern "C" {
char* my_generator(const char* text, int state) char* my_generator(const char* text, int state)
{ {
string t(text); string t(text);
/* to keep it readable, we try to keep only 4 keywords per line /* to keep it readable, we try to keep only 4 keywords per line
and to start a new line when the first letter changes */ and to start a new line when the first letter changes */
static int s_counter=0; static int s_counter=0;
skipping to change at line 484 skipping to change at line 623
if (start == 0) if (start == 0)
matches = rl_completion_matches ((char*)text, &my_generator); matches = rl_completion_matches ((char*)text, &my_generator);
// skip default filename completion. // skip default filename completion.
rl_attempted_completion_over = 1; rl_attempted_completion_over = 1;
return matches; return matches;
} }
} }
void controlClientThread(int fd, ComboAddress client) static void controlClientThread(int fd, ComboAddress client)
try try
{ {
setThreadName("dnsdist/conscli");
setTCPNoDelay(fd); setTCPNoDelay(fd);
SodiumNonce theirs, ours, readingNonce, writingNonce; SodiumNonce theirs, ours, readingNonce, writingNonce;
ours.init(); ours.init();
readn2(fd, (char*)theirs.value, sizeof(theirs.value)); readn2(fd, (char*)theirs.value, sizeof(theirs.value));
writen2(fd, (char*)ours.value, sizeof(ours.value)); writen2(fd, (char*)ours.value, sizeof(ours.value));
readingNonce.merge(ours, theirs); readingNonce.merge(ours, theirs);
writingNonce.merge(theirs, ours); writingNonce.merge(theirs, ours);
for(;;) { for(;;) {
uint32_t len; uint32_t len;
skipping to change at line 511 skipping to change at line 651
/* just ACK an empty message /* just ACK an empty message
with an empty response */ with an empty response */
putMsgLen32(fd, 0); putMsgLen32(fd, 0);
continue; continue;
} }
boost::scoped_array<char> msg(new char[len]); boost::scoped_array<char> msg(new char[len]);
readn2(fd, msg.get(), len); readn2(fd, msg.get(), len);
string line(msg.get(), len); string line(msg.get(), len);
line = sodDecryptSym(line, g_key, readingNonce);
line = sodDecryptSym(line, g_consoleKey, readingNonce);
// cerr<<"Have decrypted line: "<<line<<endl; // cerr<<"Have decrypted line: "<<line<<endl;
string response; string response;
try { try {
bool withReturn=true; bool withReturn=true;
retry:; retry:;
try { try {
std::lock_guard<std::mutex> lock(g_luamutex); std::lock_guard<std::mutex> lock(g_luamutex);
g_outputBuffer.clear(); g_outputBuffer.clear();
resetLuaSideEffect(); resetLuaSideEffect();
skipping to change at line 596 skipping to change at line 737
response+= ": " + string(ne.what()); response+= ": " + string(ne.what());
} }
catch(const PDNSException& ne) { catch(const PDNSException& ne) {
// ne is the exception that was thrown from inside the lambda // ne is the exception that was thrown from inside the lambda
response += ": " + string(ne.reason); response += ": " + string(ne.reason);
} }
} }
catch(const LuaContext::SyntaxErrorException& e) { catch(const LuaContext::SyntaxErrorException& e) {
response = "Error: " + string(e.what()) + ": "; response = "Error: " + string(e.what()) + ": ";
} }
response = sodEncryptSym(response, g_key, writingNonce); response = sodEncryptSym(response, g_consoleKey, writingNonce);
putMsgLen32(fd, response.length()); putMsgLen32(fd, response.length());
writen2(fd, response.c_str(), response.length()); writen2(fd, response.c_str(), response.length());
} }
if (g_logConsoleConnections) { if (g_logConsoleConnections) {
infolog("Closed control connection from %s", client.toStringWithPort()); infolog("Closed control connection from %s", client.toStringWithPort());
} }
close(fd); close(fd);
fd=-1; fd=-1;
} }
catch(std::exception& e) catch(std::exception& e)
{ {
errlog("Got an exception in client connection from %s: %s", client.toStringWit hPort(), e.what()); errlog("Got an exception in client connection from %s: %s", client.toStringWit hPort(), e.what());
if(fd >= 0) if(fd >= 0)
close(fd); close(fd);
} }
void controlThread(int fd, ComboAddress local)
try
{
setThreadName("dnsdist/control");
ComboAddress client;
int sock;
auto localACL = g_consoleACL.getLocal();
infolog("Accepting control connections on %s", local.toStringWithPort());
while ((sock = SAccept(fd, client)) >= 0) {
if (!sodIsValidKey(g_consoleKey)) {
vinfolog("Control connection from %s dropped because we don't have a valid
key configured, please configure one using setKey()", client.toStringWithPort()
);
close(sock);
continue;
}
if (!localACL->match(client)) {
vinfolog("Control connection from %s dropped because of ACL", client.toStr
ingWithPort());
close(sock);
continue;
}
if (g_logConsoleConnections) {
warnlog("Got control connection from %s", client.toStringWithPort());
}
std::thread t(controlClientThread, sock, client);
t.detach();
}
}
catch(const std::exception& e)
{
close(fd);
errlog("Control connection died: %s", e.what());
}
 End of changes. 66 change blocks. 
134 lines changed or deleted 365 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)