### `function gettag(remote, ednssubnet, local, qname, qtype)`
The `gettag` function is invoked when the Recursor attempts to discover in which
packetcache an answer is available.
+
This function must return an integer, which is the tag number of the packetcache.
In addition to this integer, this function can return a table of policy tags.
-
The resulting tag number can be accessed via `dq.tag` in the `preresolve` hook,
and the policy tags via `dq:getPolicyTags()` in every hook.
+Starting with 4.1.0, it can also return a table whose keys and values are strings
+to fill the upcoming `DNSQuestion`'s `data` table.
The tagged packetcache can e.g. be used to answer queries from cache that have
e.g. been filtered for certain IPs (this logic should be implemented in the
return false;
}
-int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector<std::string>* policyTags)
+int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector<std::string>* policyTags, std::unordered_map<string,string>& data)
{
return 0;
}
return false; // don't block
}
-int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector<std::string>* policyTags)
+int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector<std::string>* policyTags, std::unordered_map<string,string>& data)
{
if(d_gettag) {
auto ret = d_gettag(remote, ednssubnet, local, qname, qtype);
}
}
}
+ const auto& dataret = std::get<2>(ret);
+ if (dataret) {
+ data = *dataret;
+ }
return std::get<0>(ret);
}
return 0;
#endif
};
- int gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector<std::string>* policyTags);
+ int gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector<std::string>* policyTags, std::unordered_map<string,string>& data);
bool prerpz(DNSQuestion& dq, int& ret);
bool preresolve(DNSQuestion& dq, int& ret);
d_postresolve);
}
- typedef std::function<std::tuple<int,boost::optional<std::unordered_map<int,string> > >(ComboAddress, Netmask, ComboAddress, DNSName, uint16_t)> gettag_t;
+ typedef std::function<std::tuple<int,boost::optional<std::unordered_map<int,string> >,boost::optional<std::unordered_map<string,string> > >(ComboAddress, Netmask, ComboAddress, DNSName, uint16_t)> gettag_t;
gettag_t d_gettag; // public so you can query if we have this hooked
private:
shared_ptr<TCPConnection> d_tcpConnection;
vector<pair<uint16_t, string> > d_ednsOpts;
std::vector<std::string> d_policyTags;
+ std::unordered_map<string,string> d_data;
};
dq.appliedPolicy = &appliedPolicy;
dq.currentRecords = &ret;
dq.dh = &dc->d_mdp.d_header;
+ dq.data = dc->d_data;
if(dc->d_mdp.d_qtype==QType::ANY && !dc->d_tcp && g_anyToTcp) {
pw.getHeader()->tc = 1;
if(t_pdl->get() && (*t_pdl)->d_gettag) {
try {
- dc->d_tag = (*t_pdl)->gettag(conn->d_remote, ednssubnet, dest, qname, qtype, &dc->d_policyTags);
+ dc->d_tag = (*t_pdl)->gettag(conn->d_remote, ednssubnet, dest, qname, qtype, &dc->d_policyTags, dc->d_data);
}
catch(std::exception& e) {
if(g_logCommonErrors)
unsigned int ctag=0;
bool needECS = false;
std::vector<std::string> policyTags;
+ std::unordered_map<string,string> data;
#ifdef HAVE_PROTOBUF
boost::uuids::uuid uniqueId;
auto luaconfsLocal = g_luaconfs.getLocal();
if(t_pdl->get() && (*t_pdl)->d_gettag) {
try {
- ctag=(*t_pdl)->gettag(fromaddr, ednssubnet, destaddr, qname, qtype, &policyTags);
+ ctag=(*t_pdl)->gettag(fromaddr, ednssubnet, destaddr, qname, qtype, &policyTags, data);
}
catch(std::exception& e) {
if(g_logCommonErrors)
dc->setLocal(destaddr);
dc->d_tcp=false;
dc->d_policyTags = policyTags;
+ dc->d_data = data;
#ifdef HAVE_PROTOBUF
if (luaconfsLocal->protobufServer || luaconfsLocal->outgoingProtobufServer) {
dc->d_uuid = uniqueId;