{ "getTLSFrontend", true, "n", "returns the TLS frontend with index n" },
{ "getTLSFrontendCount", true, "", "returns the number of DoT listeners" },
{ "getVerbose", true, "", "get whether log messages at the verbose level will be logged" },
- { "grepq", true, "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] [,options]", "shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms" },
{ "hashPassword", true, "password [, workFactor]", "Returns a hashed and salted version of the supplied password, usable with 'setWebserverConfig()'"},
{ "HTTPHeaderRule", true, "name, regex", "matches DoH queries with a HTTP header 'name' whose content matches the regular expression 'regex'"},
{ "HTTPPathRegexRule", true, "regex", "matches DoH queries whose HTTP path matches 'regex'"},
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include <fcntl.h>
+
#include "dnsdist.hh"
#include "dnsdist-lua.hh"
#include "dnsdist-dynblocks.hh"
}
});
- luaCtx.writeFunction("grepq", [](LuaTypeOrArrayOf<std::string> inp, boost::optional<unsigned int> limit) {
+ luaCtx.writeFunction("grepq", [](LuaTypeOrArrayOf<std::string> inp, boost::optional<unsigned int> limit, boost::optional<LuaAssociativeTable<std::string>> options) {
setLuaNoSideEffect();
boost::optional<Netmask> nm;
boost::optional<DNSName> dn;
int msec=-1;
+ std::unique_ptr<FILE, decltype(&fclose)> outputFile{nullptr, fclose};
+
+ if (options) {
+ if (options->count("outputFile")) {
+ const std::string& outputFileName = options->at("outputFile");
+ int fd = open(outputFileName.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0600);
+ if (fd < 0) {
+ g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n";
+ return;
+ }
+ outputFile = std::unique_ptr<FILE, decltype(&fclose)>(fdopen(fd, "w"), fclose);
+ if (outputFile == nullptr) {
+ g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n";
+ return;
+ }
+ }
+ }
vector<string> vec;
auto str=boost::get<string>(&inp);
std::multimap<struct timespec, string> out;
- boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n");
- g_outputBuffer+= (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str();
+ boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n");
+ if (!outputFile) {
+ g_outputBuffer += (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str();
+ }
+ else {
+ fprintf(outputFile.get(), "%s", (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str().c_str());
+ }
if(msec==-1) {
for(const auto& c : qr) {
}
}
- for(const auto& p : out) {
- g_outputBuffer+=p.second;
+ for (const auto& p : out) {
+ if (!outputFile) {
+ g_outputBuffer += p.second;
+ }
+ else {
+ fprintf(outputFile.get(), "%s", p.second.c_str());
+ }
}
});
:param int top: How many rules to return. Default is 10.
-.. function:: grepq(selector[, num])
- grepq(selectors[, num])
+.. function:: grepq(selector[, num [, options]])
+ grepq(selectors[, num [, options]])
+
+ .. versionchanged:: 1.9.0
+ ``options`` optional parameter table added.
Prints the last ``num`` queries and responses matching ``selector`` or ``selectors``.
Queries and responses are accounted in separate ring buffers, and answers from the packet cache are not stored in the response ring buffer.
:param str selector: Select queries based on this property.
:param {str} selectors: A lua table of selectors. Only queries matching all selectors are shown
:param int num: Show a maximum of ``num`` recent queries+responses, default is 10.
+ :param table options: A table with key: value pairs with options described below.
+
+ Options:
+
+ * ``outputFile=path``: string - Write the output of the command to the supplied file, instead of the standard output.
.. function:: setVerbose(verbose)