/src/pdns/pdns/dnsdistdist/dnsdist-console-completion.cc
Line | Count | Source |
1 | | /* |
2 | | * This file is part of PowerDNS or dnsdist. |
3 | | * Copyright -- PowerDNS.COM B.V. and its contributors |
4 | | * |
5 | | * This program is free software; you can redistribute it and/or modify |
6 | | * it under the terms of version 2 of the GNU General Public License as |
7 | | * published by the Free Software Foundation. |
8 | | * |
9 | | * In addition, for the avoidance of any doubt, permission is granted to |
10 | | * link this program with OpenSSL and to (re)distribute the binaries |
11 | | * produced as the result of such linking. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU General Public License |
19 | | * along with this program; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
21 | | */ |
22 | | #include <atomic> |
23 | | #include <boost/algorithm/string.hpp> |
24 | | |
25 | | #include "config.h" |
26 | | #include "dnsdist-console-completion.hh" |
27 | | #include "dnsdist-rule-chains.hh" |
28 | | |
29 | | #ifdef HAVE_LIBEDIT |
30 | | #if defined(__OpenBSD__) || defined(__NetBSD__) |
31 | | // If this is not undeffed, __attribute__ will be redefined by /usr/include/readline/rlstdc.h |
32 | | #undef __STRICT_ANSI__ |
33 | | #include <readline/readline.h> |
34 | | #include <readline/history.h> |
35 | | #else |
36 | | #include <editline/readline.h> |
37 | | #endif |
38 | | #endif /* HAVE_LIBEDIT */ |
39 | | |
40 | | namespace dnsdist::console::completion |
41 | | { |
42 | | #ifndef DISABLE_COMPLETION |
43 | | /**** CARGO CULT CODE AHEAD ****/ |
44 | | static std::vector<dnsdist::console::completion::ConsoleKeyword> s_consoleKeywords{ |
45 | | /* keyword, function, parameters, description */ |
46 | | {"addACL", true, "netmask", "add to the ACL set who can use this server"}, |
47 | | {"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"}, |
48 | | {"addCapabilitiesToRetain", true, "capability or list of capabilities", "Linux capabilities to retain after startup, like CAP_BPF"}, |
49 | | {"addConsoleACL", true, "netmask", "add a netmask to the console ACL"}, |
50 | | {"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"}, |
51 | | {"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"}, |
52 | | {"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"}, |
53 | | {"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"}, |
54 | | {"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()`)"}, |
55 | | {"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()`)"}, |
56 | | {"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()`)"}, |
57 | | {"addLocal", true, R"(addr [, {doTCP=true, reusePort=false, tcpFastOpenQueueSize=0, interface="", cpus={}}])", "add `addr` to the list of addresses we listen on"}, |
58 | | {"addMaintenanceCallback", true, "callback", "register a function to be called as part of the maintenance hook, every second"}, |
59 | | {"addExitCallback", true, "callback", "register a function to be called when DNSdist exits"}, |
60 | | {"addServerStateChangeCallback", true, "callback", "register a function to be called when state changed for a given server"}, |
61 | | {"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"}, |
62 | | {"AllowAction", true, "", "let these packets go through"}, |
63 | | {"AllowResponseAction", true, "", "let these packets go through"}, |
64 | | {"AllRule", true, "", "matches all traffic"}, |
65 | | {"AndRule", true, "list of DNS rules", "matches if all sub-rules matches"}, |
66 | | {"benchRule", true, "DNS Rule [, iterations [, suffix]]", "bench the specified DNS rule"}, |
67 | | {"carbonServer", true, "serverIP, [ourname], [interval]", "report statistics to serverIP using our hostname, or 'ourname' if provided, every 'interval' seconds"}, |
68 | | {"clearConsoleHistory", true, "", "clear the internal (in-memory) history of console commands"}, |
69 | | {"clearDynBlocks", true, "", "clear all dynamic blocks"}, |
70 | | {"clearQueryCounters", true, "", "clears the query counter buffer"}, |
71 | | {"controlSocket", true, "addr", "open a control socket on this address / connect to this address in client mode"}, |
72 | | {"ContinueAction", true, "action", "execute the specified action and continue the processing of the remaining rules, regardless of the return of the action"}, |
73 | | {"declareMetric", true, "name, type, description [, prometheusName]", "Declare a custom metric"}, |
74 | | {"decMetric", true, "name", "Decrement a custom metric"}, |
75 | | {"DelayAction", true, "milliseconds", "delay the response by the specified amount of milliseconds (UDP-only)"}, |
76 | | {"DelayResponseAction", true, "milliseconds", "delay the response by the specified amount of milliseconds (UDP-only)"}, |
77 | | {"delta", true, "", "shows all commands entered that changed the configuration"}, |
78 | | {"DNSSECRule", true, "", "matches queries with the DO bit set"}, |
79 | | {"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"}, |
80 | | {"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"}, |
81 | | {"DropAction", true, "", "drop these packets"}, |
82 | | {"DropResponseAction", true, "", "drop these packets"}, |
83 | | {"DSTPortRule", true, "port", "matches questions received to the destination port specified"}, |
84 | | {"dumpStats", true, "", "print all statistics we gather"}, |
85 | | {"dynBlockRulesGroup", true, "", "return a new DynBlockRulesGroup object"}, |
86 | | {"EDNSVersionRule", true, "version", "matches queries with the specified EDNS version"}, |
87 | | {"EDNSOptionRule", true, "optcode", "matches queries with the specified EDNS0 option present"}, |
88 | | {"enableLuaConfiguration", true, "", "Enable using Lua configuration directives along with a YAML configuration file. It is strongly advised not to use this directive unless absolutely necessary, and to prefer doing all the configuration in either Lua or YAML"}, |
89 | | {"ERCodeAction", true, "ercode", "Reply immediately by turning the query into a response with the specified EDNS extended rcode"}, |
90 | | {"ERCodeRule", true, "rcode", "matches responses with the specified extended rcode (EDNS0)"}, |
91 | | {"exceedNXDOMAINs", true, "rate, seconds", "get set of addresses that exceed `rate` NXDOMAIN/s over `seconds` seconds"}, |
92 | | {"exceedQRate", true, "rate, seconds", "get set of address that exceed `rate` queries/s over `seconds` seconds"}, |
93 | | {"exceedQTypeRate", true, "type, rate, seconds", "get set of address that exceed `rate` queries/s for queries of type `type` over `seconds` seconds"}, |
94 | | {"exceedRespByterate", true, "rate, seconds", "get set of addresses that exceeded `rate` bytes/s answers over `seconds` seconds"}, |
95 | | {"exceedServFails", true, "rate, seconds", "get set of addresses that exceed `rate` servfails/s over `seconds` seconds"}, |
96 | | {"firstAvailable", false, "", "picks the server with the lowest `order` that has not exceeded its QPS limit"}, |
97 | | {"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"}, |
98 | | {"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"}, |
99 | | {"generateDNSCryptProviderKeys", true, R"("/path/to/providerPublic.key", "/path/to/providerPrivate.key")", "generate a new provider keypair"}, |
100 | | {"getAction", true, "n", "Returns the Action associated with rule n"}, |
101 | | {"getBind", true, "n", "returns the listener at index n"}, |
102 | | {"getBindCount", true, "", "returns the number of listeners all kinds"}, |
103 | | {"getCurrentTime", true, "", "returns the current time"}, |
104 | | {"getDynamicBlocks", true, "", "returns a table of the current network-based dynamic blocks"}, |
105 | | {"getDynamicBlocksSMT", true, "", "returns a table of the current suffix-based dynamic blocks"}, |
106 | | {"getDNSCryptBind", true, "n", "return the `DNSCryptContext` object corresponding to the bind `n`"}, |
107 | | {"getDNSCryptBindCount", true, "", "returns the number of DNSCrypt listeners"}, |
108 | | {"getDOHFrontend", true, "n", "returns the DoH frontend with index n"}, |
109 | | {"getDOHFrontendCount", true, "", "returns the number of DoH listeners"}, |
110 | | {"getDOH3Frontend", true, "n", "returns the DoH3 frontend with index n"}, |
111 | | {"getDOH3FrontendCount", true, "", "returns the number of DoH3 listeners"}, |
112 | | {"getDOQFrontend", true, "n", "returns the DoQ frontend with index n"}, |
113 | | {"getDOQFrontendCount", true, "", "returns the number of DoQ listeners"}, |
114 | | {"getListOfAddressesOfNetworkInterface", true, "itf", "returns the list of addresses configured on a given network interface, as strings"}, |
115 | | {"getListOfNetworkInterfaces", true, "", "returns the list of network interfaces present on the system, as strings"}, |
116 | | {"getListOfRangesOfNetworkInterface", true, "itf", "returns the list of network ranges configured on a given network interface, as strings"}, |
117 | | {"getMACAddress", true, "IP addr", "return the link-level address (MAC) corresponding to the supplied neighbour IP address, if known by the kernel"}, |
118 | | {"getMetric", true, "name", "Get the value of a custom metric"}, |
119 | | {"getObjectFromYAMLConfiguration", true, "name", "Get an object created in YAML configuration"}, |
120 | | {"getOutgoingTLSSessionCacheSize", true, "", "returns the number of TLS sessions (for outgoing connections) currently cached"}, |
121 | | {"getPool", true, "name", "return the pool named `name`, or \"\" for the default pool"}, |
122 | | {"getPoolServers", true, "pool", "return servers part of this pool"}, |
123 | | {"getPoolNames", true, "", "returns a table with all the pool names"}, |
124 | | {"getQueryCounters", true, "[max=10]", "show current buffer of query counters, limited by 'max' if provided"}, |
125 | | {"getResponseRing", true, "", "return the current content of the response ring"}, |
126 | | {"getRespRing", true, "", "return the qname/rcode content of the response ring"}, |
127 | | {"getRingBuffersSamplingRate", true, "", "return current sampling rate of the in-memory ring buffers"}, |
128 | | {"getServer", true, "id", "returns server with index 'n' or whose uuid matches if 'id' is an UUID string"}, |
129 | | {"getServers", true, "", "returns a table with all defined servers"}, |
130 | | {"getStatisticsCounters", true, "", "returns a map of statistic counters"}, |
131 | | {"getTLSFrontend", true, "n", "returns the TLS frontend with index n"}, |
132 | | {"getTLSFrontendCount", true, "", "returns the number of DoT listeners"}, |
133 | | {"getVerbose", true, "", "get whether log messages at the verbose level will be logged"}, |
134 | | {"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"}, |
135 | | {"hashPassword", true, "password [, workFactor]", "Returns a hashed and salted version of the supplied password, usable with 'setWebserverConfig()'"}, |
136 | | {"HTTPHeaderRule", true, "name, regex", "matches DoH queries with a HTTP header 'name' whose content matches the regular expression 'regex'"}, |
137 | | {"HTTPPathRegexRule", true, "regex", "matches DoH queries whose HTTP path matches 'regex'"}, |
138 | | {"HTTPPathRule", true, "path", "matches DoH queries whose HTTP path is an exact match to 'path'"}, |
139 | | {"HTTPStatusAction", true, "status, reason, body", "return an HTTP response"}, |
140 | | {"inClientStartup", true, "", "returns true during console client parsing of configuration"}, |
141 | | {"includeDirectory", true, "path", "include configuration files from `path`"}, |
142 | | {"incMetric", true, "name", "Increment a custom metric"}, |
143 | | {"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"}, |
144 | | {"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."}, |
145 | | {"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"}, |
146 | | {"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"}, |
147 | | {"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'"}, |
148 | | {"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'"}, |
149 | | {"KeyValueStoreLookupRule", true, "kvs, lookupKey", "matches queries if the key is found in the specified Key Value store"}, |
150 | | {"KeyValueStoreRangeLookupRule", true, "kvs, lookupKey", "matches queries if the key is found in the specified Key Value store"}, |
151 | | {"leastOutstanding", false, "", "Send traffic to downstream server with least outstanding queries, with the lowest 'order', and within that the lowest recent latency"}, |
152 | | #if defined(HAVE_LIBSSL) && !defined(HAVE_TLS_PROVIDERS) |
153 | | {"loadTLSEngine", true, "engineName [, defaultString]", "Load the OpenSSL engine named 'engineName', setting the engine default string to 'defaultString' if supplied"}, |
154 | | #endif |
155 | | #if defined(HAVE_LIBSSL) && OPENSSL_VERSION_MAJOR >= 3 && defined(HAVE_TLS_PROVIDERS) |
156 | | {"loadTLSProvider", true, "providerName", "Load the OpenSSL provider named 'providerName'"}, |
157 | | #endif |
158 | | {"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."}, |
159 | | {"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."}, |
160 | | {"LuaAction", true, "function", "Invoke a Lua function that accepts a DNSQuestion"}, |
161 | | {"LuaFFIAction", true, "function", "Invoke a Lua FFI function that accepts a DNSQuestion"}, |
162 | | {"LuaFFIPerThreadAction", true, "function", "Invoke a Lua FFI function that accepts a DNSQuestion, with a per-thread Lua context"}, |
163 | | {"LuaFFIPerThreadResponseAction", true, "function", "Invoke a Lua FFI function that accepts a DNSResponse, with a per-thread Lua context"}, |
164 | | {"LuaFFIResponseAction", true, "function", "Invoke a Lua FFI function that accepts a DNSResponse"}, |
165 | | {"LuaFFIRule", true, "function", "Invoke a Lua FFI function that filters DNS questions"}, |
166 | | {"LuaResponseAction", true, "function", "Invoke a Lua function that accepts a DNSResponse"}, |
167 | | {"LuaRule", true, "function", "Invoke a Lua function that filters DNS questions"}, |
168 | | #ifdef HAVE_IPCIPHER |
169 | | {"makeIPCipherKey", true, "password", "generates a 16-byte key that can be used to pseudonymize IP addresses with IP cipher"}, |
170 | | #endif /* HAVE_IPCIPHER */ |
171 | | {"makeKey", true, "", "generate a new server access key, emit configuration line ready for pasting"}, |
172 | | {"makeRule", true, "rule", "Make a NetmaskGroupRule() or a SuffixMatchNodeRule(), depending on how it is called"}, |
173 | | {"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"}, |
174 | | {"MaxQPSRule", true, "qps", "matches traffic **not** exceeding this qps limit"}, |
175 | | {"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"}, |
176 | | {"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."}, |
177 | | {"newCA", true, "address", "Returns a ComboAddress based on `address`"}, |
178 | | #ifdef HAVE_CDB |
179 | | {"newCDBKVStore", true, "fname, refreshDelay", "Return a new KeyValueStore object associated to the corresponding CDB database"}, |
180 | | #endif |
181 | | {"newDNSName", true, "name", "make a DNSName based on this .-terminated name"}, |
182 | | {"newDNSNameSet", true, "", "returns a new DNSNameSet"}, |
183 | | {"newDynBPFFilter", true, "bpf", "Return a new dynamic eBPF filter associated to a given BPF Filter"}, |
184 | | {"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()`"}, |
185 | | {"newFrameStreamUnixLogger", true, "socket [, options]", "create a FrameStream logger object writing to a local unix socket, to use with `DnstapLogAction()` and `DnstapLogResponseAction()`"}, |
186 | | #ifdef HAVE_LMDB |
187 | | {"newLMDBKVStore", true, "fname, dbName [, noLock]", "Return a new KeyValueStore object associated to the corresponding LMDB database"}, |
188 | | #endif |
189 | | #ifdef HAVE_MMDB |
190 | | {"newMMDBKVStore", true, "mmdb, queryParams", "Return a new KeyValueStore object associated to the corresponding MMDB database"}, |
191 | | #endif |
192 | | {"newNMG", true, "", "Returns a NetmaskGroup"}, |
193 | | {"newPacketCache", true, "maxEntries[, maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=false, shuffle=false, numberOfShards=1, deferrableInsertLock=true, options={}]", "return a new Packet Cache"}, |
194 | | {"newQPSLimiter", true, "rate, burst", "configure a QPS limiter with that rate and that burst capacity"}, |
195 | | {"newRemoteLogger", true, "address:port [, timeout=2, maxQueuedEntries=100, reconnectWaitTime=1]", "create a Remote Logger object, to use with `RemoteLogAction()` and `RemoteLogResponseAction()`"}, |
196 | | {"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()`"}, |
197 | | {"newServer", true, R"({address="ip:port", qps=1000, order=1, weight=10, pool="abuse", retries=5, udpTimeout=0, 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"}, |
198 | | {"newServerPolicy", true, "name, function", "create a policy object from a Lua function"}, |
199 | | {"newSuffixMatchNode", true, "", "returns a new SuffixMatchNode"}, |
200 | | {"newSVCRecordParameters", true, "priority, target, mandatoryParams, alpns, noDefaultAlpn [, port [, ech [, ipv4hints [, ipv6hints [, additionalParameters ]]]]]", "return a new SVCRecordParameters object, to use with SpoofSVCAction"}, |
201 | | {"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"}, |
202 | | {"NoneAction", true, "", "Does nothing. Subsequent rules are processed after this action"}, |
203 | | {"NotRule", true, "selector", "Matches the traffic if the selector rule does not match"}, |
204 | | {"OpcodeRule", true, "code", "Matches queries with opcode code. code can be directly specified as an integer, or one of the built-in DNSOpcodes"}, |
205 | | #ifdef HAVE_MMDB |
206 | | {"openMMDB", true, "name, [, options]", "Open a MMDB database and return a reference to it"}, |
207 | | #endif |
208 | | {"OrRule", true, "selectors", "Matches the traffic if one or more of the selectors rules does match"}, |
209 | | {"PoolAction", true, "poolname [, stop]", "set the packet into the specified pool"}, |
210 | | {"PoolAvailableRule", true, "poolname", "Check whether a pool has any servers available to handle queries"}, |
211 | | {"PoolOutstandingRule", true, "poolname, limit", "Check whether a pool has outstanding queries above limit"}, |
212 | | {"printDNSCryptProviderFingerprint", true, R"("/path/to/providerPublic.key")", "display the fingerprint of the provided resolver public key"}, |
213 | | {"ProbaRule", true, "probability", "Matches queries with a given probability. 1.0 means always"}, |
214 | | {"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"}, |
215 | | {"QClassRule", true, "qclass", "Matches queries with the specified qclass. class can be specified as an integer or as one of the built-in DNSClass"}, |
216 | | {"QNameLabelsCountRule", true, "min, max", "matches if the qname has less than `min` or more than `max` labels"}, |
217 | | {"QNameRule", true, "qname", "matches queries with the specified qname"}, |
218 | | {"QNameSetRule", true, "set", "Matches if the set contains exact qname"}, |
219 | | {"QNameWireLengthRule", true, "min, max", "matches if the qname's length on the wire is less than `min` or more than `max` bytes"}, |
220 | | {"QPSAction", true, "maxqps", "Drop a packet if it does exceed the maxqps queries per second limits. Letting the subsequent rules apply otherwise"}, |
221 | | {"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"}, |
222 | | {"QTypeRule", true, "qtype", "matches queries with the specified qtype"}, |
223 | | {"RCodeAction", true, "rcode", "Reply immediately by turning the query into a response with the specified rcode"}, |
224 | | {"RCodeRule", true, "rcode", "matches responses with the specified rcode"}, |
225 | | {"RDRule", true, "", "Matches queries with the RD flag set"}, |
226 | | {"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"}, |
227 | | {"RecordsTypeCountRule", true, "section, qtype, minCount, maxCount", "Matches if there is at least minCount and at most maxCount records of type qtype in the section section"}, |
228 | | {"RegexRule", true, "regex", "matches the query name against the supplied regex"}, |
229 | | {"registerDynBPFFilter", true, "DynBPFFilter", "register this dynamic BPF filter into the web interface so that its counters are displayed"}, |
230 | | {"reloadAllCertificates", true, "", "reload all DNSCrypt and TLS certificates, along with their associated keys"}, |
231 | | {"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."}, |
232 | | {"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."}, |
233 | | {"requestTCPStatesDump", true, "", "Request a dump of the TCP states (incoming connections, outgoing connections) during the next scan. Useful for debugging purposes only"}, |
234 | | {"rmACL", true, "netmask", "remove netmask from ACL"}, |
235 | | {"rmServer", true, "id", "remove server with index 'id' or whose uuid matches if 'id' is an UUID string"}, |
236 | | {"roundrobin", false, "", "Simple round robin over available servers"}, |
237 | | {"sendCustomTrap", true, "str", "send a custom `SNMP` trap from Lua, containing the `str` string"}, |
238 | | {"setACL", true, "{netmask, netmask}", "replace the ACL set with these netmasks. Use `setACL({})` to reset the list, meaning no one can use us"}, |
239 | | {"setACLFromFile", true, "file", "replace the ACL set with netmasks in this file"}, |
240 | | {"setAddEDNSToSelfGeneratedResponses", true, "add", "set whether to add EDNS to self-generated responses, provided that the initial query had EDNS"}, |
241 | | {"setAllowEmptyResponse", true, "allow", "Set to true (defaults to false) to allow empty responses (qdcount=0) with a NoError or NXDomain rcode (default) from backends"}, |
242 | | {"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"}, |
243 | | {"setBanDurationForExceedingMaxReadIOsPerQuery", true, "n", "Set for how long, in seconds, a client (or range) will be prevented from opening a new TCP connection when it has exceeded the maximum number of read IOs per query over a TCP connection"}, |
244 | | {"setBanDurationForExceedingTCPTLSRate", true, "n", "Set for how long, in seconds, a client (or range) will be prevented from opening a new TCP connection when it has exceeded the TCP connection or TLS session rates"}, |
245 | | {"setCacheCleaningDelay", true, "num", "Set the interval in seconds between two runs of the cache cleaning algorithm, removing expired entries"}, |
246 | | {"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"}, |
247 | | {"setConsistentHashingBalancingFactor", true, "factor", "Set the balancing factor for bounded-load consistent hashing"}, |
248 | | {"setConsoleACL", true, "{netmask, netmask}", "replace the console ACL set with these netmasks"}, |
249 | | {"setConsoleBindFatal", true, "enable", "whether a failure to bind the console control socket is fatal"}, |
250 | | {"setConsoleConnectionsLogging", true, "enabled", "whether to log the opening and closing of console connections"}, |
251 | | {"setConsoleMaximumConcurrentConnections", true, "max", "Set the maximum number of concurrent console connections"}, |
252 | | {"setConsoleOutputMaxMsgSize", true, "messageSize", "set console message maximum size in bytes, default is 10 MB"}, |
253 | | {"setDefaultBPFFilter", true, "filter", "When used at configuration time, the corresponding BPFFilter will be attached to every bind"}, |
254 | | {"setDoHDownstreamCleanupInterval", true, "interval", "minimum interval in seconds between two cleanups of the idle DoH downstream connections"}, |
255 | | {"setDoHDownstreamMaxIdleTime", true, "time", "Maximum time in seconds that a downstream DoH connection to a backend might stay idle"}, |
256 | | {"setDynBlocksAction", true, "action", "set which action is performed when a query is blocked. Only DNSAction.Drop (the default) and DNSAction.Refused are supported"}, |
257 | | {"setDynBlocksPurgeInterval", true, "sec", "set how often the expired dynamic block entries should be removed"}, |
258 | | {"setDropEmptyQueries", true, "drop", "Whether to drop empty queries right away instead of sending a NOTIMP response"}, |
259 | | {"setECSOverride", true, "bool", "whether to override an existing EDNS Client Subnet value in the query"}, |
260 | | {"setECSSourcePrefixV4", true, "prefix-length", "the EDNS Client Subnet prefix-length used for IPv4 queries"}, |
261 | | {"setECSSourcePrefixV6", true, "prefix-length", "the EDNS Client Subnet prefix-length used for IPv6 queries"}, |
262 | | {"setKey", true, "key", "set access key to that key"}, |
263 | | {"setLocal", true, R"(addr [, {doTCP=true, reusePort=false, tcpFastOpenQueueSize=0, interface="", cpus={}}])", "reset the list of addresses we listen on to this address"}, |
264 | | {"setMaxCachedDoHConnectionsPerDownstream", true, "max", "Set the maximum number of inactive DoH connections to a backend cached by each worker DoH thread"}, |
265 | | {"setMaxCachedTCPConnectionsPerDownstream", true, "max", "Set the maximum number of inactive TCP connections to a backend cached by each worker TCP thread"}, |
266 | | {"setMaxTCPClientThreads", true, "n", "set the maximum of TCP client threads, handling TCP connections"}, |
267 | | {"setMaxTCPConnectionDuration", true, "n", "set the maximum duration of an incoming TCP connection, in seconds. 0 means unlimited"}, |
268 | | {"setMaxTCPConnectionRatePerClient", true, "n", "set the maximum number of new TCP connections that a given client can open per second"}, |
269 | | {"setMaxTCPConnectionsPerClient", true, "n", "set the maximum number of TCP connections per client. 0 means unlimited"}, |
270 | | {"setMaxTCPQueriesPerConnection", true, "n", "set the maximum number of queries in an incoming TCP connection. 0 means unlimited"}, |
271 | | {"setMaxTCPQueuedConnections", true, "n", "set the maximum number of TCP connections queued (waiting to be picked up by a client thread)"}, |
272 | | {"setMaxTCPReadIOsPerQuery", true, "n", "set the maximum number of read events needed to receive a new query on a TCP connection"}, |
273 | | {"setMaxTLSNewSessionRatePerClient", true, "n", "set the maximum number of new TLS sessions that a given client can open per second"}, |
274 | | {"setMaxTLSResumedSessionRatePerClient", true, "n", "set the maximum number of resumed TLS sessions that a given client can open per second"}, |
275 | | {"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"}, |
276 | | {"setMetric", true, "name, value", "Set the value of a custom metric to the supplied value"}, |
277 | | {"setPayloadSizeOnSelfGeneratedAnswers", true, "payloadSize", "set the UDP payload size advertised via EDNS on self-generated responses"}, |
278 | | {"setPoolServerPolicy", true, "policy, pool", "set the server selection policy for this pool to that policy"}, |
279 | | {"setPoolServerPolicyLua", true, "name, function, pool", "set the server selection policy for this pool to one named 'name' and provided by 'function'"}, |
280 | | {"setPoolServerPolicyLuaFFI", true, "name, function, pool", "set the server selection policy for this pool to one named 'name' and provided by 'function'"}, |
281 | | {"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'"}, |
282 | | {"setProxyProtocolACL", true, "{netmask, netmask}", "Set the netmasks who are allowed to send Proxy Protocol headers in front of queries/connections"}, |
283 | | {"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"}, |
284 | | {"setProxyProtocolMaximumPayloadSize", true, "max", "Set the maximum size of a Proxy Protocol payload, in bytes"}, |
285 | | {"setQueryCount", true, "bool", "set whether queries should be counted"}, |
286 | | {"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"}, |
287 | | {"SetReducedTTLResponseAction", true, "percentage", "Reduce the TTL of records in a response to a given percentage"}, |
288 | | {"setRingBuffersLockRetries", true, "n", "set the number of attempts to get a non-blocking lock to a ringbuffer shard before blocking"}, |
289 | | {"setRingBuffersOptions", true, "{ lockRetries=int, recordQueries=true, recordResponses=true }", "set ringbuffer options"}, |
290 | | {"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`"}, |
291 | | {"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"}, |
292 | | {"setSecurityPollInterval", true, "n", "set the security polling interval to `n` seconds"}, |
293 | | {"setSecurityPollSuffix", true, "suffix", "set the security polling suffix to the specified value"}, |
294 | | {"setServerPolicy", true, "policy", "set server selection policy to that policy"}, |
295 | | {"setServerPolicyLua", true, "name, function", "set server selection policy to one named 'name' and provided by 'function'"}, |
296 | | {"setServerPolicyLuaFFI", true, "name, function", "set server selection policy to one named 'name' and provided by the Lua FFI 'function'"}, |
297 | | {"setServerPolicyLuaFFIPerThread", true, "name, code", "set server selection policy to one named 'name' and returned by the Lua FFI code passed in 'code'"}, |
298 | | {"setServFailWhenNoServer", true, "bool", "if set, return a ServFail when no servers are available, instead of the default behaviour of dropping the query"}, |
299 | | {"setStaleCacheEntriesTTL", true, "n", "allows using cache entries expired for at most n seconds when there is no backend available to answer for a query"}, |
300 | | {"setStructuredLogging", true, "value [, options]", "set whether log messages should be in structured-logging-like format"}, |
301 | | {"setSyslogFacility", true, "facility", "set the syslog logging facility to 'facility'. Defaults to LOG_DAEMON"}, |
302 | | {"setTCPConnectionsMaskV4", true, "n", "Mask to apply to IPv4 addresses when enforcing the TLS connection or TLS sessions rates"}, |
303 | | {"setTCPConnectionsMaskV4Port", true, "n", "Mask to apply to the port when enforcing the TLS connection or TLS sessions rates for IPv4 addresses"}, |
304 | | {"setTCPConnectionsMaskV6", true, "n", "Mask to apply to IPv6 addresses when enforcing the TLS connection or TLS sessions rates"}, |
305 | | {"setTCPConnectionsOverloadThreshold", true, "n", "Set a threshold as a percentage to the maximum number of incoming TCP connections per frontend or per client. When this threshold is reached, new incoming TCP connections are restricted"}, |
306 | | {"setTCPConnectionRateInterval", true, "n", "Set the interval, in minutes, over which new TCP and TLS per client connection rates are computed"}, |
307 | | {"setTCPDownstreamCleanupInterval", true, "interval", "minimum interval in seconds between two cleanups of the idle TCP downstream connections"}, |
308 | | {"setTCPDownstreamMaxIdleTime", true, "time", "Maximum time in seconds that a downstream TCP connection to a backend might stay idle"}, |
309 | | {"setTCPConnectionsOverloadThreshold", true, "n", "Set a threshold as a percentage to the maximum number of incoming TCP connections per frontend or per client. When this threshold is reached, new incoming TCP connections are restricted: only query per connection is allowed (no out-of-order processing, no idle time allowed), the receive timeout is reduced to 500 milliseconds and the total duration of the TCP connection is limited to 5 seconds"}, |
310 | | {"setTCPFastOpenKey", true, "string", "TCP Fast Open Key"}, |
311 | | {"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"}, |
312 | | {"setTCPRecvTimeout", true, "n", "set the read timeout on TCP connections from the client, in seconds"}, |
313 | | {"setTCPSendTimeout", true, "n", "set the write timeout on TCP connections from the client, in seconds"}, |
314 | | {"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"}, |
315 | | {"setUDPSocketBufferSizes", true, "recv, send", "Set the size of the receive (SO_RCVBUF) and send (SO_SNDBUF) buffers for incoming UDP sockets"}, |
316 | | {"setUDPTimeout", true, "n", "set the maximum time dnsdist will wait for a response from a backend over UDP, in seconds"}, |
317 | | {"setVerbose", true, "bool", "set whether log messages at the verbose level will be logged"}, |
318 | | {"setVerboseHealthChecks", true, "bool", "set whether health check errors will be logged"}, |
319 | | {"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"}, |
320 | | {"setWebserverBindFatal", true, "enable", "whether a failure to bind a web server socket is fatal"}, |
321 | | {"setWebserverConfig", true, "[{password=string, apiKey=string, customHeaders, statsRequireAuthentication, prometheusAddInstanceLabel=bool}]", "Updates webserver configuration"}, |
322 | | {"setWeightedBalancingFactor", true, "factor", "Set the balancing factor for bounded-load weighted policies (whashed, wrandom)"}, |
323 | | {"setWHashedPerturbation", 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"}, |
324 | | {"show", true, "string", "outputs `string`"}, |
325 | | {"showACL", true, "", "show our ACL set"}, |
326 | | {"showBinds", true, "", "show listening addresses (frontends)"}, |
327 | | {"showConsoleACL", true, "", "show our current console ACL set"}, |
328 | | {"showDNSCryptBinds", true, "", "display the currently configured DNSCrypt binds"}, |
329 | | {"showDOHFrontends", true, "", "list all the available DOH frontends"}, |
330 | | {"showDOH3Frontends", true, "", "list all the available DOH3 frontends"}, |
331 | | {"showDOHResponseCodes", true, "", "show the HTTP response code statistics for the DoH frontends"}, |
332 | | {"showDOQFrontends", true, "", "list all the available DOQ frontends"}, |
333 | | {"showDynBlocks", true, "", "show dynamic blocks in force"}, |
334 | | {"showPools", true, "", "show the available pools"}, |
335 | | {"showPoolServerPolicy", true, "pool", "show server selection policy for this pool"}, |
336 | | {"showResponseLatency", true, "", "show a plot of the response time latency distribution"}, |
337 | | {"showSecurityStatus", true, "", "Show the security status"}, |
338 | | {"showServerPolicy", true, "", "show name of currently operational server selection policy"}, |
339 | | {"showServers", true, "[{showUUIDs=false}]", "output all servers, optionally with their UUIDs"}, |
340 | | {"showTCPStats", true, "", "show some statistics regarding TCP"}, |
341 | | {"showTLSErrorCounters", true, "", "show metrics about TLS handshake failures"}, |
342 | | {"showTLSFrontends", true, "", "list all the available TLS contexts"}, |
343 | | {"showVersion", true, "", "show the current version"}, |
344 | | {"showWebserverConfig", true, "", "Show the current webserver configuration"}, |
345 | | {"shutdown", true, "", "shut down `dnsdist`"}, |
346 | | {"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"}, |
347 | | {"SetAdditionalProxyProtocolValueAction", true, "type, value", "Add a Proxy Protocol TLV value of this type"}, |
348 | | {"SetDisableECSAction", true, "", "Disable the sending of ECS to the backend. Subsequent rules are processed after this action."}, |
349 | | {"SetDisableValidationAction", true, "", "set the CD bit in the question, let it go through"}, |
350 | | {"SetECSAction", true, "v4[, v6]", "Set the ECS prefix and prefix length sent to backends to an arbitrary value"}, |
351 | | {"SetECSOverrideAction", true, "override", "Whether an existing EDNS Client Subnet value should be overridden (true) or not (false). Subsequent rules are processed after this action"}, |
352 | | {"SetECSPrefixLengthAction", true, "v4, v6", "Set the ECS prefix length. Subsequent rules are processed after this action"}, |
353 | | {"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"}, |
354 | | {"SetEDNSOptionAction", true, "option, data", "Add arbitrary EDNS option and data to the query. Subsequent rules are processed after this action"}, |
355 | | {"SetEDNSOptionResponseAction", true, "option, data", "Add arbitrary EDNS option and data to the response. Subsequent rules are processed after this action"}, |
356 | | {"SetExtendedDNSErrorAction", true, "infoCode [, extraText [, clearExistingEntries]]", "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"}, |
357 | | {"SetExtendedDNSErrorResponseAction", true, "infoCode [, extraText [, clearExistingEntries]]", "Set an Extended DNS Error status that will be added to this response. Subsequent rules are processed after this action"}, |
358 | | {"SetNoRecurseAction", true, "", "strip RD bit from the question, let it go through"}, |
359 | | {"setOutgoingDoHWorkerThreads", true, "n", "Number of outgoing DoH worker threads"}, |
360 | | {"SetProxyProtocolValuesAction", true, "values", "Set the Proxy-Protocol values for this queries to 'values'"}, |
361 | | {"SetSkipCacheAction", true, "", "Don’t lookup the cache for this query, don’t store the answer"}, |
362 | | {"SetSkipCacheResponseAction", true, "", "Don’t store this response into the cache"}, |
363 | | {"SetTagAction", true, "name, value", "set the tag named 'name' to the given value"}, |
364 | | {"SetTagResponseAction", true, "name, value", "set the tag named 'name' to the given value"}, |
365 | | {"SetTempFailureCacheTTLAction", true, "ttl", "set packetcache TTL for temporary failure replies"}, |
366 | | {"SNIRule", true, "name", "Create a rule which matches on the incoming TLS SNI value, if any (DoT or DoH)"}, |
367 | | {"SNMPTrapAction", true, "[reason]", "send an SNMP trap, adding the optional `reason` string as the query description"}, |
368 | | {"SNMPTrapResponseAction", true, "[reason]", "send an SNMP trap, adding the optional `reason` string as the response description"}, |
369 | | {"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"}, |
370 | | {"SpoofCNAMEAction", true, "cname [, options]", "Forge a response with the specified CNAME value"}, |
371 | | {"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"}, |
372 | | {"SpoofSVCAction", true, "list of svcParams [, options]", "Forge a response with the specified SVC record data"}, |
373 | | {"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"}, |
374 | | {"TagRule", true, "name [, value]", "matches if the tag named 'name' is present, with the given 'value' matching if any"}, |
375 | | {"TCAction", true, "", "create answer to query with TC and RD bits set, to move to TCP"}, |
376 | | {"TCPRule", true, "[tcp]", "Matches question received over TCP if tcp is true, over UDP otherwise"}, |
377 | | {"TCResponseAction", true, "", "truncate a response"}, |
378 | | {"TeeAction", true, "remote [, addECS [, local]]", "send copy of query to remote, optionally adding ECS info, optionally set local address"}, |
379 | | {"testCrypto", true, "", "test of the crypto all works"}, |
380 | | {"TimedIPSetRule", true, "", "Create a rule which matches a set of IP addresses which expire"}, |
381 | | {"topBandwidth", true, "top", "show top-`top` clients that consume the most bandwidth over length of ringbuffer"}, |
382 | | {"topClients", true, "n", "show top-`n` clients sending the most queries over length of ringbuffer"}, |
383 | | {"topQueries", true, "n[, labels]", "show top 'n' queries, as grouped when optionally cut down to 'labels' labels"}, |
384 | | {"topSlow", true, "[top][, limit][, labels]", "show `top` queries slower than `limit` milliseconds (timeouts excepted), grouped by last `labels` labels"}, |
385 | | {"topTimeouts", true, "[top][, labels]", "show `top` queries that timed out, grouped by last `labels` labels"}, |
386 | | {"TrailingDataRule", true, "", "Matches if the query has trailing data"}, |
387 | | {"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."}, |
388 | | {"unregisterDynBPFFilter", true, "DynBPFFilter", "unregister this dynamic BPF filter"}, |
389 | | {"webserver", true, "address:port", "launch a webserver with stats on that address"}, |
390 | | {"whashed", false, "", "Weighted hashed ('sticky') distribution over available servers, based on the server 'weight' parameter"}, |
391 | | {"chashed", false, "", "Consistent hashed ('sticky') distribution over available servers, also based on the server 'weight' parameter"}, |
392 | | {"wrandom", false, "", "Weighted random over available servers, based on the server 'weight' parameter"}, |
393 | | {"setServerID", true, "name", "Set the internal Server ID to this value"}, |
394 | | {"getServerID", true, "", "Get the internal Server ID as a string"}, |
395 | | }; |
396 | | |
397 | | #if defined(HAVE_LIBEDIT) |
398 | | extern "C" |
399 | | { |
400 | | static char* dnsdist_completion_generator(const char* text, int state) |
401 | | { |
402 | | std::string textStr{text}; |
403 | | /* to keep it readable, we try to keep only 4 keywords per line |
404 | | and to start a new line when the first letter changes */ |
405 | | static int s_counter = 0; |
406 | | int counter = 0; |
407 | | if (state == 0) { |
408 | | s_counter = 0; |
409 | | } |
410 | | |
411 | | for (const auto& keyword : s_consoleKeywords) { |
412 | | if (boost::starts_with(keyword.name, textStr) && counter++ == s_counter) { |
413 | | std::string value(keyword.name); |
414 | | s_counter++; |
415 | | if (keyword.function) { |
416 | | value += "("; |
417 | | if (keyword.parameters.empty()) { |
418 | | value += ")"; |
419 | | } |
420 | | } |
421 | | return strdup(value.c_str()); |
422 | | } |
423 | | } |
424 | | return nullptr; |
425 | | } |
426 | | |
427 | | static char** dnsdist_completion_callback(const char* text, int start, int end) |
428 | | { |
429 | | (void)end; |
430 | | char** matches = nullptr; |
431 | | if (start == 0) { |
432 | | // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast): readline |
433 | | matches = rl_completion_matches(const_cast<char*>(text), &dnsdist_completion_generator); |
434 | | } |
435 | | |
436 | | // skip default filename completion. |
437 | | rl_attempted_completion_over = 1; |
438 | | |
439 | | return matches; |
440 | | } |
441 | | } |
442 | | #endif /* HAVE_LIBEDIT */ |
443 | | |
444 | | static void initializeConsoleKeywords() |
445 | 0 | { |
446 | 0 | static std::atomic<bool> s_initialized{false}; |
447 | 0 | if (s_initialized.exchange(true)) { |
448 | 0 | return; |
449 | 0 | } |
450 | | |
451 | 0 | for (const auto& chain : dnsdist::rules::getRuleChainDescriptions()) { |
452 | 0 | const std::string descriptionWithSpace = chain.description + (chain.description.empty() ? "" : " "); |
453 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"add" + chain.prefix + "Action", true, std::string(R"(DNS rule, DNS action [, {uuid="UUID", name="name"}])"), "add a " + descriptionWithSpace + "rule"}); |
454 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"show" + chain.prefix + "Rules", true, std::string("[{showUUIDs=false, truncateRuleWidth=-1}]"), "show all defined " + descriptionWithSpace + "rules, optionally with their UUIDs and optionally truncated to a given width"}); |
455 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"rm" + chain.prefix + "Rule", true, std::string("id"), "remove " + descriptionWithSpace + "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"}); |
456 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"mv" + chain.prefix + "Rule", true, std::string("from, to"), "move " + descriptionWithSpace + "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"}); |
457 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"mv" + chain.prefix + "RuleToTop", true, std::string(), "move the last " + descriptionWithSpace + "rule to the first position"}); |
458 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"get" + chain.prefix + "Rule", true, std::string("selector"), "Return the " + descriptionWithSpace + "rule corresponding to the selector, if any"}); |
459 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"getTop" + chain.prefix + "Rules", true, "[top]", "return the `top` " + descriptionWithSpace + "rules"}); |
460 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"top" + chain.prefix + "Rules", true, "[top][, vars]", "show `top` " + descriptionWithSpace + "rules"}); |
461 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"clear" + chain.prefix + "Rules", true, "", "remove all current " + descriptionWithSpace + "rules"}); |
462 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"set" + chain.prefix + "Rules", true, "list of " + descriptionWithSpace + "rules", "replace the current " + descriptionWithSpace + "rules with the supplied list of pairs of DNS Rules and DNS Actions (see `newRuleAction()`)"}); |
463 | 0 | } |
464 | |
|
465 | 0 | for (const auto& chain : dnsdist::rules::getResponseRuleChainDescriptions()) { |
466 | 0 | const std::string descriptionWithSpace = chain.description + (chain.description.empty() ? "" : " "); |
467 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"add" + chain.prefix + "ResponseAction", true, std::string(R"(DNS rule, DNS response action [, {uuid="UUID", name="name"}])"), "add a " + descriptionWithSpace + "response rule"}); |
468 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"show" + chain.prefix + "ResponseRules", true, std::string("[{showUUIDs=false, truncateRuleWidth=-1}]"), "show all defined " + descriptionWithSpace + "response rules, optionally with their UUIDs and optionally truncated to a given width"}); |
469 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"rm" + chain.prefix + "ResponseRule", true, std::string("id"), "remove " + descriptionWithSpace + "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"}); |
470 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"mv" + chain.prefix + "ResponseRule", true, std::string("from, to"), "move " + descriptionWithSpace + "response 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"}); |
471 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"mv" + chain.prefix + "ResponseRuleToTop", true, std::string(), "move the last " + descriptionWithSpace + "response rule to the first position"}); |
472 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"get" + chain.prefix + "ResponseRule", true, std::string("selector"), "Return the " + descriptionWithSpace + "response rule corresponding to the selector, if any"}); |
473 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"getTop" + chain.prefix + "ResponseRules", true, "[top]", "return the `top` " + descriptionWithSpace + "response rules"}); |
474 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"top" + chain.prefix + "ResponseRules", true, "[top][, vars]", "show `top` " + descriptionWithSpace + "response rules"}); |
475 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"clear" + chain.prefix + "ResponseRules", true, "", "remove all current " + descriptionWithSpace + "response rules"}); |
476 | 0 | s_consoleKeywords.push_back(ConsoleKeyword{"set" + chain.prefix + "ResponseRules", true, "list of " + descriptionWithSpace + "response rules", "replace the current " + descriptionWithSpace + "response rules with the supplied list of pairs of DNS Rules and DNS Actions (see `newRuleAction()`)"}); |
477 | 0 | } |
478 | 0 | } |
479 | | |
480 | | const std::vector<ConsoleKeyword>& getConsoleKeywords() |
481 | 0 | { |
482 | 0 | return s_consoleKeywords; |
483 | 0 | } |
484 | | |
485 | | std::string ConsoleKeyword::toString() const |
486 | 0 | { |
487 | 0 | std::string res(name); |
488 | 0 | if (function) { |
489 | 0 | res += "(" + parameters + ")"; |
490 | 0 | } |
491 | 0 | res += ": "; |
492 | 0 | res += description; |
493 | 0 | return res; |
494 | 0 | } |
495 | | #endif /* DISABLE_COMPLETION */ |
496 | | |
497 | | void setupCompletion() |
498 | 0 | { |
499 | 0 | #ifndef DISABLE_COMPLETION |
500 | 0 | initializeConsoleKeywords(); |
501 | | #ifdef HAVE_LIBEDIT |
502 | | rl_attempted_completion_function = dnsdist::console::completion::dnsdist_completion_callback; |
503 | | rl_completion_append_character = 0; |
504 | | #endif /* DISABLE_COMPLETION */ |
505 | 0 | #endif /* HAVE_LIBEDIT */ |
506 | 0 | } |
507 | | } |