* getFakeAAAARecords: Get a fake AAAA record, see [DNS64](#dns64)
* getFakePTRRecords: Get a fake PTR record, see [DNS64](#dns64)
* udpQueryResponse: Do a UDP query and call a handler, see [`udpQueryResponse`](#udpqueryresponse)
+* appliedPolicy - The decision that was made by the policy engine, see [Modifying policy decisions](#modifying-policy-decisions). It has the following fields:
+ * policyName: The name of the policy (used in e.g. protobuf logging)
+ * policyAction: The action taken by the engine
+ * policyCustom: The CNAME content for the `pdns.policyactions.Custom` response, a string
+ * policyTTL: The TTL in seconds for the `pdns.policyactions.Custom` response
It also supports the following methods:
return false
end
```
+
+## Modifying Policy Decisions
+The PowerDNS Recursor has a [policy engine based on Response Policy Zones (RPZ)](settings.md#response-policy-zone-rpz).
+Starting with version 4.0.1 of the recursor, it is possible to alter this decision inside the Lua hooks.
+If the decision is modified in a Lua hook, `false` should be returned, as the query is not actually handled by Lua so the decision is picked up by the Recursor.
+The result of the policy decision is checked after `preresolve` and `postresolve`.
+
+For example, if a decision is set to `pdns.policykinds.NODATA` by the policy engine and is unchanged in `preresolve`, the query is replied to with a NODATA response immediately after `preresolve`.
+
+### Example script
+```
+-- Dont ever block my own domain and IPs
+myDomain = newDN("example.com")
+
+myNetblock = newNMG()
+myNetblock:addMasks("192.0.2.0/24")
+
+function preresolve(dq)
+ if dq.qname:isPartOf(myDomain) and dq.appliedPolicy.policyKind != pdns.policykinds.NoAction then
+ pdnslog("Not blocking our own domain!")
+ dq.appliedPolicy.policyKind = pdns.policykinds.NoAction
+ end
+end
+
+function postresolve(dq)
+ if dq.appliedPolicy.policyKind != pdns.policykinds.NoAction then
+ local records = dq:getRecords()
+ for k,v in pairs(records) do
+ if v.type == pdns.A then
+ local blockedIP = newCA(v:getContent())
+ if myNetblock:match(blockedIP) then
+ pdnslog("Not blocking our IP space")
+ dq.appliedPolicy.policyKind = pdns.policykinds.NoAction
+ end
+ end
+ end
+ end
+end
+```
+
+The decision is contained in the `dq` object under `dq.appliedPolicy` and features 4 fields:
+
+### `dq.appliedPolicy.policyName`
+A string with the name of the policy (set by `polName=` in the `rpzFile` and `rpzMaster` configuration items).
+It is advised to overwrite this when modifying the `policyKind`
+
+### `dq.appliedPolicy.policyKind`
+The kind of policy response, there are several policy kinds:
+
+ * `pdns.policykinds.Custom` will return a NoError, CNAME answer with the value specified in `dq.appliedPolicy.policyCustom`
+ * `pdns.policykinds.Drop` will simply cause the query to be dropped
+ * `pdns.policykinds.NoAction` will continue normal processing of the query
+ * `pdns.policykinds.NODATA` will return a NoError response with no value in the answer section
+ * `pdns.policykinds.NXDOMAIN` will return a response with a NXDomain rcode
+ * `pdns.policykinds.Truncate` will return a NoError, no answer, truncated response over UDP. Normal processing will continue over TCP
+
+### `dq.appliedPolicy.policyCustom` and `dq.appliedPolicy.policyTTL`
+These fields are only used when `dq.appliedPolicy.policyKind` is set to `pdns.policykinds.Custom`.
+`dq.appliedPolicy.policyCustom` contains the name for the CNAME target as a string.
+And `dq.appliedPolicy.policyTTL` is the TTL field (in seconds) for the CNAME response.
#include "namespaces.hh"
#include "rec_channel.hh"
#include "ednssubnet.hh"
+#include "filterpo.hh"
#include <unordered_set>
#if !defined(HAVE_LUA)
return false;
}
-bool RecursorLua4::postresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& ret, std::string* appliedPolicy, std::vector<std::string>* policyTags, int& res, bool* variable)
+bool RecursorLua4::postresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& ret, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& res, bool* variable)
{
return false;
}
-bool RecursorLua4::preresolve(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& ret, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, std::string* appliedPolicy, std::vector<std::string>* policyTags, int& res, bool* variable)
+bool RecursorLua4::preresolve(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& ret, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& res, bool* variable)
{
return false;
}
d_lw->registerMember("udpQueryDest", &DNSQuestion::udpQueryDest);
d_lw->registerMember("udpCallback", &DNSQuestion::udpCallback);
d_lw->registerMember("appliedPolicy", &DNSQuestion::appliedPolicy);
+ d_lw->registerMember("policyName", &DNSFilterEngine::Policy::d_name);
+ d_lw->registerMember("policyKind", &DNSFilterEngine::Policy::d_kind);
+ d_lw->registerMember("policyTTL", &DNSFilterEngine::Policy::d_ttl);
+ d_lw->registerMember<DNSFilterEngine::Policy, string>("policyCustom",
+ [](const DNSFilterEngine::Policy& pol) -> string {
+ return pol.d_custom->getZoneRepresentation();
+ },
+ [](DNSFilterEngine::Policy& pol, string content) {
+ // Only CNAMES for now, when we ever add a d_custom_type, there will be pain
+ pol.d_custom = shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(QType::CNAME, 1, content));
+ }
+ );
d_lw->registerFunction("getEDNSOptions", &DNSQuestion::getEDNSOptions);
d_lw->registerFunction("getEDNSOption", &DNSQuestion::getEDNSOption);
d_lw->registerFunction("getEDNSSubnet", &DNSQuestion::getEDNSSubnet);
{"Error", LOG_ERR}
}});
+ pd.push_back({"policykinds", in_t {
+ {"NoAction", (int)DNSFilterEngine::PolicyKind::NoAction},
+ {"Drop", (int)DNSFilterEngine::PolicyKind::Drop },
+ {"NXDOMAIN", (int)DNSFilterEngine::PolicyKind::NXDOMAIN},
+ {"NODATA", (int)DNSFilterEngine::PolicyKind::NODATA },
+ {"Truncate", (int)DNSFilterEngine::PolicyKind::Truncate},
+ {"Custom", (int)DNSFilterEngine::PolicyKind::Custom }
+ }});
+
for(const auto& n : QType::names)
pd.push_back({n.first, n.second});
pd.push_back({"now", &g_now});
d_gettag = d_lw->readVariable<boost::optional<gettag_t>>("gettag").get_value_or(0);
}
-bool RecursorLua4::preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, std::string* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable)
+bool RecursorLua4::preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable)
{
return genhook(d_preresolve, remote, local, query, qtype, isTcp, res, ednsOpts, tag, appliedPolicy, policyTags, ret, variable);
}
return genhook(d_nodata, remote, local, query, qtype, isTcp, res, 0, 0, nullptr, nullptr, ret, variable);
}
-bool RecursorLua4::postresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, std::string* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable)
+bool RecursorLua4::postresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable)
{
return genhook(d_postresolve, remote, local, query, qtype, isTcp, res, 0, 0, appliedPolicy, policyTags, ret, variable);
}
return 0;
}
-bool RecursorLua4::genhook(luacall_t& func, const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, std::string* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable)
+bool RecursorLua4::genhook(luacall_t& func, const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable)
{
if(!func)
return false;
dq->isTcp = isTcp;
dq->rcode = ret;
dq->policyTags = policyTags;
+ dq->appliedPolicy = appliedPolicy;
bool handled=func(dq);
if(variable) *variable |= dq->variable; // could still be set to indicate this *name* is variable, even if not 'handled'
}
}
res=dq->records;
- if (appliedPolicy) {
- *appliedPolicy=dq->appliedPolicy;
- }
}
#include "dnsname.hh"
#include "namespaces.hh"
#include "dnsrecords.hh"
+#include "filterpo.hh"
#include <unordered_map>
#ifdef HAVE_CONFIG_H
#include "config.h"
public:
explicit RecursorLua4(const std::string& fname);
~RecursorLua4(); // this is so unique_ptr works with an incomplete type
- bool preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, std::string* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable);
+ bool preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable);
bool nxdomain(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret, bool* variable);
bool nodata(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret, bool* variable);
- bool postresolve(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, std::string* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable);
+ bool postresolve(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable);
bool preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret);
bool ipfilter(const ComboAddress& remote, const ComboAddress& local, const struct dnsheader&);
const std::vector<pair<uint16_t, string>>* ednsOptions;
DNSName followupName;
- string appliedPolicy;
+ DNSFilterEngine::Policy* appliedPolicy;
std::vector<std::string>* policyTags;
bool isTcp;
};
typedef std::function<bool(std::shared_ptr<DNSQuestion>)> luacall_t;
luacall_t d_preresolve, d_nxdomain, d_nodata, d_postresolve, d_preoutquery, d_postoutquery;
- bool genhook(luacall_t& func, const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, std::string* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable);
+ bool genhook(luacall_t& func, const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable);
typedef std::function<bool(ComboAddress,ComboAddress, struct dnsheader)> ipfilter_t;
ipfilter_t d_ipfilter;
};
}
#ifdef HAVE_PROTOBUF
-static void protobufLogQuery(const std::shared_ptr<RemoteLogger>& logger, uint8_t maskV4, uint8_t maskV6, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const Netmask& ednssubnet, bool tcp, uint16_t id, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::string appliedPolicy, const std::vector<std::string>& policyTags)
+static void protobufLogQuery(const std::shared_ptr<RemoteLogger>& logger, uint8_t maskV4, uint8_t maskV6, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const Netmask& ednssubnet, bool tcp, uint16_t id, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const DNSFilterEngine::Policy appliedPolicy, const std::vector<std::string>& policyTags)
{
Netmask requestorNM(remote, remote.sin4.sin_family == AF_INET ? maskV4 : maskV6);
const ComboAddress& requestor = requestorNM.getMaskedNetwork();
RecProtoBufMessage message(DNSProtoBufMessage::Query, uniqueId, &requestor, &local, qname, qtype, qclass, id, tcp, len);
message.setEDNSSubnet(ednssubnet, ednssubnet.isIpv4() ? maskV4 : maskV6);
- if (!appliedPolicy.empty()) {
- message.setAppliedPolicy(appliedPolicy);
+ if (!appliedPolicy.d_name.empty()) {
+ message.setAppliedPolicy(appliedPolicy.d_name);
}
if (!policyTags.empty()) {
message.setPolicyTags(policyTags);
vector<uint8_t> packet;
auto luaconfsLocal = g_luaconfs.getLocal();
- std::string appliedPolicy;
+ DNSFilterEngine::Policy appliedPolicy;
RecProtoBufMessage pbMessage(RecProtoBufMessage::Response);
#ifdef HAVE_PROTOBUF
if (luaconfsLocal->protobufServer) {
if(!dc->d_mdp.d_header.rd)
sr.setCacheOnly();
+ // Check if the query has a policy attached to it
dfepol = luaconfsLocal->dfe.getQueryPolicy(dc->d_mdp.d_qname, dc->d_remote);
-
- switch(dfepol.d_kind) {
- case DNSFilterEngine::PolicyKind::NoAction:
- break;
- case DNSFilterEngine::PolicyKind::Drop:
- g_stats.policyDrops++;
- delete dc;
- dc=0;
- return;
- case DNSFilterEngine::PolicyKind::NXDOMAIN:
- res=RCode::NXDomain;
- appliedPolicy=dfepol.d_name;
- goto haveAnswer;
-
- case DNSFilterEngine::PolicyKind::NODATA:
- res=RCode::NoError;
- appliedPolicy=dfepol.d_name;
- goto haveAnswer;
-
- case DNSFilterEngine::PolicyKind::Custom:
- res=RCode::NoError;
- spoofed.d_name=dc->d_mdp.d_qname;
- spoofed.d_type=dfepol.d_custom->getType();
- spoofed.d_ttl = dfepol.d_ttl;
- spoofed.d_class = 1;
- spoofed.d_content = dfepol.d_custom;
- spoofed.d_place = DNSResourceRecord::ANSWER;
- ret.push_back(spoofed);
- appliedPolicy=dfepol.d_name;
- goto haveAnswer;
-
-
- case DNSFilterEngine::PolicyKind::Truncate:
- if(!dc->d_tcp) {
- res=RCode::NoError;
- pw.getHeader()->tc=1;
- appliedPolicy=dfepol.d_name;
- goto haveAnswer;
- }
- break;
- }
+ appliedPolicy = dfepol;
// if there is a RecursorLua active, and it 'took' the query in preResolve, we don't launch beginResolve
if(!t_pdl->get() || !(*t_pdl)->preresolve(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, dc->d_ednsOpts.empty() ? 0 : &dc->d_ednsOpts, dc->d_tag, &appliedPolicy, &dc->d_policyTags, res, &variableAnswer)) {
+
+ switch(appliedPolicy.d_kind) {
+ case DNSFilterEngine::PolicyKind::NoAction:
+ break;
+ case DNSFilterEngine::PolicyKind::Drop:
+ g_stats.policyDrops++;
+ delete dc;
+ dc=0;
+ return;
+ case DNSFilterEngine::PolicyKind::NXDOMAIN:
+ res=RCode::NXDomain;
+ goto haveAnswer;
+ case DNSFilterEngine::PolicyKind::NODATA:
+ res=RCode::NoError;
+ goto haveAnswer;
+ case DNSFilterEngine::PolicyKind::Custom:
+ res=RCode::NoError;
+ spoofed.d_name=dc->d_mdp.d_qname;
+ spoofed.d_type=appliedPolicy.d_custom->getType();
+ spoofed.d_ttl = appliedPolicy.d_ttl;
+ spoofed.d_class = 1;
+ spoofed.d_content = appliedPolicy.d_custom;
+ spoofed.d_place = DNSResourceRecord::ANSWER;
+ ret.push_back(spoofed);
+ goto haveAnswer;
+ case DNSFilterEngine::PolicyKind::Truncate:
+ if(!dc->d_tcp) {
+ res=RCode::NoError;
+ pw.getHeader()->tc=1;
+ goto haveAnswer;
+ }
+ break;
+ }
+
+ // Query got not handled for Policy reasons, now actually go out to find an answer
try {
res = sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret);
shouldNotValidate = sr.wasOutOfBand();
res = RCode::ServFail;
}
- dfepol = luaconfsLocal->dfe.getPostPolicy(ret);
- switch(dfepol.d_kind) {
+ dfepol = luaconfsLocal->dfe.getPostPolicy(ret);
+ appliedPolicy = dfepol;
+
+ if(t_pdl->get()) {
+ if(res == RCode::NoError) {
+ auto i=ret.cbegin();
+ for(; i!= ret.cend(); ++i)
+ if(i->d_type == dc->d_mdp.d_qtype && i->d_place == DNSResourceRecord::ANSWER)
+ break;
+ if(i == ret.cend())
+ (*t_pdl)->nodata(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, res, &variableAnswer);
+ }
+ else if(res == RCode::NXDomain)
+ (*t_pdl)->nxdomain(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, res, &variableAnswer);
+
+
+ (*t_pdl)->postresolve(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, &appliedPolicy, &dc->d_policyTags, res, &variableAnswer);
+ }
+
+ switch(appliedPolicy.d_kind) {
case DNSFilterEngine::PolicyKind::NoAction:
break;
case DNSFilterEngine::PolicyKind::Drop:
case DNSFilterEngine::PolicyKind::NXDOMAIN:
ret.clear();
res=RCode::NXDomain;
- appliedPolicy=dfepol.d_name;
goto haveAnswer;
case DNSFilterEngine::PolicyKind::NODATA:
ret.clear();
res=RCode::NoError;
- appliedPolicy=dfepol.d_name;
goto haveAnswer;
case DNSFilterEngine::PolicyKind::Truncate:
ret.clear();
res=RCode::NoError;
pw.getHeader()->tc=1;
- appliedPolicy=dfepol.d_name;
goto haveAnswer;
}
break;
ret.clear();
res=RCode::NoError;
spoofed.d_name=dc->d_mdp.d_qname;
- spoofed.d_type=dfepol.d_custom->getType();
- spoofed.d_ttl = dfepol.d_ttl;
+ spoofed.d_type=appliedPolicy.d_custom->getType();
+ spoofed.d_ttl = appliedPolicy.d_ttl;
spoofed.d_class = 1;
- spoofed.d_content = dfepol.d_custom;
+ spoofed.d_content = appliedPolicy.d_custom;
spoofed.d_place = DNSResourceRecord::ANSWER;
ret.push_back(spoofed);
- appliedPolicy=dfepol.d_name;
goto haveAnswer;
}
-
- if(t_pdl->get()) {
- if(res == RCode::NoError) {
- auto i=ret.cbegin();
- for(; i!= ret.cend(); ++i)
- if(i->d_type == dc->d_mdp.d_qtype && i->d_place == DNSResourceRecord::ANSWER)
- break;
- if(i == ret.cend())
- (*t_pdl)->nodata(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, res, &variableAnswer);
- }
- else if(res == RCode::NXDomain)
- (*t_pdl)->nxdomain(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, res, &variableAnswer);
-
-
- (*t_pdl)->postresolve(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, &appliedPolicy, &dc->d_policyTags, res, &variableAnswer);
- }
}
haveAnswer:;
if(res == PolicyDecision::DROP) {
if (luaconfsLocal->protobufServer) {
pbMessage.setBytes(packet.size());
pbMessage.setResponseCode(pw.getHeader()->rcode);
- pbMessage.setAppliedPolicy(appliedPolicy);
+ pbMessage.setAppliedPolicy(appliedPolicy.d_name);
pbMessage.setPolicyTags(dc->d_policyTags);
pbMessage.setQueryTime(dc->d_now.tv_sec, dc->d_now.tv_usec);
protobufLogResponse(luaconfsLocal->protobufServer, pbMessage);
getQNameAndSubnet(std::string(conn->data, conn->qlen), &qname, &qtype, &qclass, &ednssubnet);
dc->d_ednssubnet = ednssubnet;
- protobufLogQuery(luaconfsLocal->protobufServer, luaconfsLocal->protobufMaskV4, luaconfsLocal->protobufMaskV6, dc->d_uuid, dest, conn->d_remote, ednssubnet, true, dh->id, conn->qlen, qname, qtype, qclass, std::string(), std::vector<std::string>());
+ protobufLogQuery(luaconfsLocal->protobufServer, luaconfsLocal->protobufMaskV4, luaconfsLocal->protobufMaskV6, dc->d_uuid, dest, conn->d_remote, ednssubnet, true, dh->id, conn->qlen, qname, qtype, qclass, DNSFilterEngine::Policy(), std::vector<std::string>());
}
catch(std::exception& e) {
if(g_logCommonErrors)
RecProtoBufMessage pbMessage(DNSProtoBufMessage::DNSProtoBufMessageType::Response);
#ifdef HAVE_PROTOBUF
if(luaconfsLocal->protobufServer) {
- protobufLogQuery(luaconfsLocal->protobufServer, luaconfsLocal->protobufMaskV4, luaconfsLocal->protobufMaskV6, uniqueId, fromaddr, destaddr, ednssubnet, false, dh->id, question.size(), qname, qtype, qclass, std::string(), policyTags);
+ protobufLogQuery(luaconfsLocal->protobufServer, luaconfsLocal->protobufMaskV4, luaconfsLocal->protobufMaskV6, uniqueId, fromaddr, destaddr, ednssubnet, false, dh->id, question.size(), qname, qtype, qclass, DNSFilterEngine::Policy(), policyTags);
}
#endif /* HAVE_PROTOBUF */