addAction(&g_cachehitrespruleactions, var, boost::get<std::shared_ptr<DNSResponseAction> >(era), params);
});
+ luaCtx.writeFunction("addCacheInsertedResponseAction", [](luadnsrule_t var, boost::variant<std::shared_ptr<DNSAction>, std::shared_ptr<DNSResponseAction>> era, boost::optional<luaruleparams_t> params) {
+ if (era.type() != typeid(std::shared_ptr<DNSResponseAction>)) {
+ throw std::runtime_error("addCacheInsertedResponseAction() can only be called with response-related actions, not query-related ones. Are you looking for addAction()?");
+ }
+
+ addAction(&g_cacheInsertedRespRuleActions, var, boost::get<std::shared_ptr<DNSResponseAction> >(era), params);
+ });
+
luaCtx.writeFunction("addSelfAnsweredResponseAction", [](luadnsrule_t var, boost::variant<std::shared_ptr<DNSAction>, std::shared_ptr<DNSResponseAction>> era, boost::optional<luaruleparams_t> params) {
if (era.type() != typeid(std::shared_ptr<DNSResponseAction>)) {
throw std::runtime_error("addSelfAnsweredResponseAction() can only be called with response-related actions, not query-related ones. Are you looking for addAction()?");
mvRule(&g_cachehitrespruleactions, from, to);
});
+ luaCtx.writeFunction("showCacheInsertedResponseRules", [](boost::optional<ruleparams_t> vars) {
+ showRules(&g_cacheInsertedRespRuleActions, vars);
+ });
+
+ luaCtx.writeFunction("rmCacheInsertedResponseRule", [](boost::variant<unsigned int, std::string> id) {
+ rmRule(&g_cacheInsertedRespRuleActions, id);
+ });
+
+ luaCtx.writeFunction("mvCacheInsertedResponseRuleToTop", []() {
+ moveRuleToTop(&g_cacheInsertedRespRuleActions);
+ });
+
+ luaCtx.writeFunction("mvCacheInsertedResponseRule", [](unsigned int from, unsigned int to) {
+ mvRule(&g_cacheInsertedRespRuleActions, from, to);
+ });
+
luaCtx.writeFunction("showSelfAnsweredResponseRules", [](boost::optional<ruleparams_t> vars) {
showRules(&g_selfansweredrespruleactions, vars);
});
memcpy(&response.d_cleartextDH, dr.getHeader(), sizeof(response.d_cleartextDH));
- if (!processResponse(response.d_buffer, state->d_threadData.localRespRuleActions, dr, false, false)) {
+ if (!processResponse(response.d_buffer, *state->d_threadData.localRespRuleActions, *state->d_threadData.localCacheInsertedRespRuleActions, dr, false, false)) {
state->terminateClientConnection();
return;
}
addRulesToPrometheusOutput(output, g_ruleactions);
addRulesToPrometheusOutput(output, g_respruleactions);
addRulesToPrometheusOutput(output, g_cachehitrespruleactions);
+ addRulesToPrometheusOutput(output, g_cacheInsertedRespRuleActions);
addRulesToPrometheusOutput(output, g_selfansweredrespruleactions);
#ifndef DISABLE_DYNBLOCKS
}
auto responseRules = someResponseRulesToJson(&g_respruleactions);
auto cacheHitResponseRules = someResponseRulesToJson(&g_cachehitrespruleactions);
+ auto cacheInsertedResponseRules = someResponseRulesToJson(&g_cacheInsertedRespRuleActions);
auto selfAnsweredResponseRules = someResponseRulesToJson(&g_selfansweredrespruleactions);
string acl;
{ "rules", std::move(rules) },
{ "response-rules", std::move(responseRules) },
{ "cache-hit-response-rules", std::move(cacheHitResponseRules) },
+ { "cache-inserted-response-rules", std::move(cacheInsertedResponseRules) },
{ "self-answered-response-rules", std::move(selfAnsweredResponseRules) },
{ "acl", std::move(acl) },
{ "local", std::move(localaddressesStr) },
GlobalStateHolder<vector<DNSDistRuleAction> > g_ruleactions;
GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_respruleactions;
GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_cachehitrespruleactions;
+GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_cacheInsertedRespRuleActions;
GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_selfansweredrespruleactions;
Rings g_rings;
}
#endif /* HAVE_DNSCRYPT */
-static bool applyRulesToResponse(LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr)
+static bool applyRulesToResponse(const std::vector<DNSDistResponseRuleAction>& respRuleActions, DNSResponse& dr)
{
- DNSResponseAction::Action action=DNSResponseAction::Action::None;
+ DNSResponseAction::Action action = DNSResponseAction::Action::None;
std::string ruleresult;
- for(const auto& lr : *localRespRuleActions) {
- if(lr.d_rule->matches(&dr)) {
+ for (const auto& lr : respRuleActions) {
+ if (lr.d_rule->matches(&dr)) {
lr.d_rule->d_matches++;
- action=(*lr.d_action)(&dr, &ruleresult);
- switch(action) {
+ action = (*lr.d_action)(&dr, &ruleresult);
+ switch (action) {
case DNSResponseAction::Action::Allow:
return true;
break;
// whether the query was received over TCP or not (for rules, dnstap, protobuf, ...) will be taken from the DNSResponse, but receivedOverUDP is used to insert into the cache,
// so that answers received over UDP for DoH are still cached with UDP answers.
-bool processResponse(PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted, bool receivedOverUDP)
+bool processResponse(PacketBuffer& response, const vector<DNSDistResponseRuleAction>& respRuleActions, const vector<DNSDistResponseRuleAction>& insertedRespRuleActions, DNSResponse& dr, bool muted, bool receivedOverUDP)
{
- if (!applyRulesToResponse(localRespRuleActions, dr)) {
+ if (!applyRulesToResponse(respRuleActions, dr)) {
return false;
}
}
dr.packetCache->insert(cacheKey, zeroScope ? boost::none : dr.subnet, dr.cacheFlags, dr.dnssecOK, *dr.qname, dr.qtype, dr.qclass, response, receivedOverUDP, dr.getHeader()->rcode, dr.tempFailureTTL);
+
+ if (!applyRulesToResponse(insertedRespRuleActions, dr)) {
+ return false;
+ }
}
#ifdef HAVE_DNSCRYPT
try {
setThreadName("dnsdist/respond");
auto localRespRuleActions = g_respruleactions.getLocal();
+ auto localCacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal();
const size_t initialBufferSize = getInitialUDPPacketBufferSize();
PacketBuffer response(initialBufferSize);
}
memcpy(&cleartextDH, dr.getHeader(), sizeof(cleartextDH));
- if (!processResponse(response, localRespRuleActions, dr, ids->cs && ids->cs->muted, true)) {
+ if (!processResponse(response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, ids->cs && ids->cs->muted, true)) {
dss->releaseState(queryId);
continue;
}
dr.qTag = std::move(dq.qTag);
dr.delayMsec = dq.delayMsec;
- if (!applyRulesToResponse(cacheHit ? holders.cacheHitRespRuleactions : holders.selfAnsweredRespRuleactions, dr)) {
+ if (!applyRulesToResponse(cacheHit ? *holders.cacheHitRespRuleactions : *holders.selfAnsweredRespRuleactions, dr)) {
return false;
}
auto& ids = response.d_idstate;
static thread_local LocalStateHolder<vector<DNSDistResponseRuleAction>> localRespRuleActions = g_respruleactions.getLocal();
+ static thread_local LocalStateHolder<vector<DNSDistResponseRuleAction>> localCacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal();
DNSResponse dr = makeDNSResponseFromIDState(ids, response.d_buffer);
if (response.d_buffer.size() > d_payloadSize) {
vinfolog("Got a response of size %d over TCP, while the initial UDP payload size was %d, truncating", response.d_buffer.size(), d_payloadSize);
dnsheader cleartextDH;
memcpy(&cleartextDH, dr.getHeader(), sizeof(cleartextDH));
- if (!processResponse(response.d_buffer, localRespRuleActions, dr, false, true)) {
+ if (!processResponse(response.d_buffer, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false, true)) {
return;
}
extern GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_respruleactions;
extern GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_cachehitrespruleactions;
extern GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_selfansweredrespruleactions;
+extern GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_cacheInsertedRespRuleActions;
extern GlobalStateHolder<NetmaskGroup> g_ACL;
extern ComboAddress g_serverControl; // not changed during runtime
struct LocalHolders
{
- LocalHolders(): acl(g_ACL.getLocal()), policy(g_policy.getLocal()), ruleactions(g_ruleactions.getLocal()), cacheHitRespRuleactions(g_cachehitrespruleactions.getLocal()), selfAnsweredRespRuleactions(g_selfansweredrespruleactions.getLocal()), servers(g_dstates.getLocal()), dynNMGBlock(g_dynblockNMG.getLocal()), dynSMTBlock(g_dynblockSMT.getLocal()), pools(g_pools.getLocal())
+ LocalHolders(): acl(g_ACL.getLocal()), policy(g_policy.getLocal()), ruleactions(g_ruleactions.getLocal()), cacheHitRespRuleactions(g_cachehitrespruleactions.getLocal()), cacheInsertedRespRuleActions(g_cacheInsertedRespRuleActions.getLocal()), selfAnsweredRespRuleactions(g_selfansweredrespruleactions.getLocal()), servers(g_dstates.getLocal()), dynNMGBlock(g_dynblockNMG.getLocal()), dynSMTBlock(g_dynblockSMT.getLocal()), pools(g_pools.getLocal())
{
}
LocalStateHolder<ServerPolicy> policy;
LocalStateHolder<vector<DNSDistRuleAction> > ruleactions;
LocalStateHolder<vector<DNSDistResponseRuleAction> > cacheHitRespRuleactions;
+ LocalStateHolder<vector<DNSDistResponseRuleAction> > cacheInsertedRespRuleActions;
LocalStateHolder<vector<DNSDistResponseRuleAction> > selfAnsweredRespRuleactions;
LocalStateHolder<servers_t> servers;
LocalStateHolder<NetmaskTree<DynBlock, AddressAndPortRange> > dynNMGBlock;
void resetLuaSideEffect(); // reset to indeterminate state
bool responseContentMatches(const PacketBuffer& response, const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const std::shared_ptr<DownstreamState>& remote, unsigned int& qnameWireLength);
-bool processResponse(PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted, bool receivedOverUDP);
+bool processResponse(PacketBuffer& response, const std::vector<DNSDistResponseRuleAction>& respRuleActions, const std::vector<DNSDistResponseRuleAction>& insertedRespRuleActions, DNSResponse& dr, bool muted, bool receivedOverUDP);
bool processRulesResult(const DNSAction::Action& action, DNSQuestion& dq, std::string& ruleresult, bool& drop);
bool checkQueryHeaders(const struct dnsheader* dh, ClientState& cs);
class TCPClientThreadData
{
public:
- TCPClientThreadData(): localRespRuleActions(g_respruleactions.getLocal()), mplexer(std::unique_ptr<FDMultiplexer>(FDMultiplexer::getMultiplexerSilent()))
+ TCPClientThreadData():
+ localRespRuleActions(g_respruleactions.getLocal()), localCacheInsertedRespRuleActions(g_cacheInsertedRespRuleActions.getLocal()), mplexer(std::unique_ptr<FDMultiplexer>(FDMultiplexer::getMultiplexerSilent()))
{
}
LocalHolders holders;
- LocalStateHolder<vector<DNSDistResponseRuleAction> > localRespRuleActions;
+ LocalStateHolder<vector<DNSDistResponseRuleAction>> localRespRuleActions;
+ LocalStateHolder<vector<DNSDistResponseRuleAction>> localCacheInsertedRespRuleActions;
std::unique_ptr<FDMultiplexer> mplexer{nullptr};
int crossProtocolResponsesPipe{-1};
};
Before 1.6.0 this function used to move the last cache hit response rule to the first position, which is now handled by :func:`mvCacheHitResponseRuleToTop`.
+Functions for manipulating Cache Inserted Response Rules:
+
+.. function:: addCacheInsertedResponseAction(DNSRule, action [, options])
+
+ .. versionadded:: 1.8.0
+
+ Add a Rule and ResponseAction that is executed after a cache entry has been inserted to the existing rules.
+
+ :param DNSRule: A DNSRule, e.g. an :func:`AllRule` or a compounded bunch of rules using e.g. :func:`AndRule`
+ :param action: The action to take
+ :param table options: A table with key: value pairs with options.
+
+ Options:
+
+ * ``uuid``: string - UUID to assign to the new rule. By default a random UUID is generated for each rule.
+ * ``name``: string - Name to assign to the new rule.
+
+.. function:: mvCacheInsertedResponseRule(from, to)
+
+ .. versionadded:: 1.8.0
+
+ Move cache inserted 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.
+
+ :param int from: Rule number to move
+ :param int to: Location to more the Rule to
+
+.. function:: mvCacheInsertedResponseRuleToTop()
+
+ .. versionadded:: 1.8.0
+
+ This function moves the last cache inserted response rule to the first position.
+
+.. function:: rmCacheInsertedResponseRule(id)
+
+ .. versionadded:: 1.8.0
+
+ :param int id: The position of the rule to remove if ``id`` is numerical, its UUID or name otherwise
+
+.. function:: showCacheInsertedResponseRules([options])
+
+ .. versionadded:: 1.8.0
+
+ Show all defined cache inserted response rules, optionally displaying their UUIDs.
+
+ :param table options: A table with key: value pairs with display options.
+
+ Options:
+
+ * ``showUUIDs=false``: bool - Whether to display the UUIDs, defaults to false.
+ * ``truncateRuleWidth=-1``: int - Truncate rules output to ``truncateRuleWidth`` size. Defaults to ``-1`` to display the full rule.
+
Functions for manipulating Self-Answered Response Rules:
.. function:: addSelfAnsweredResponseAction(DNSRule, action [, options])
du->response = std::move(response.d_buffer);
du->ids = std::move(response.d_idstate);
- thread_local LocalStateHolder<vector<DNSDistResponseRuleAction>> localRespRuleActions = g_respruleactions.getLocal();
+ static thread_local LocalStateHolder<vector<DNSDistResponseRuleAction>> localRespRuleActions = g_respruleactions.getLocal();
+ static thread_local LocalStateHolder<vector<DNSDistResponseRuleAction>> localCacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal();
DNSResponse dr = makeDNSResponseFromIDState(du->ids, du->response);
dnsheader cleartextDH;
memcpy(&cleartextDH, dr.getHeader(), sizeof(cleartextDH));
- if (!processResponse(du->response, localRespRuleActions, dr, false, false)) {
+ if (!processResponse(du->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false, false)) {
du.reset();
return;
}
const dnsheader* dh = reinterpret_cast<const struct dnsheader*>(du->response.data());
if (!dh->tc) {
- thread_local LocalStateHolder<vector<DNSDistResponseRuleAction>> localRespRuleActions = g_respruleactions.getLocal();
+ static thread_local LocalStateHolder<vector<DNSDistResponseRuleAction>> localRespRuleActions = g_respruleactions.getLocal();
+ static thread_local LocalStateHolder<vector<DNSDistResponseRuleAction>> localcacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal();
DNSResponse dr = makeDNSResponseFromIDState(du->ids, du->response);
dnsheader cleartextDH;
memcpy(&cleartextDH, dr.getHeader(), sizeof(cleartextDH));
- if (!processResponse(du->response, localRespRuleActions, dr, false, true)) {
+ if (!processResponse(du->response, *localRespRuleActions, *localcacheInsertedRespRuleActions, dr, false, true)) {
return;
}
GlobalStateHolder<vector<DNSDistRuleAction> > g_ruleactions;
GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_respruleactions;
GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_cachehitrespruleactions;
+GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_cacheInsertedRespRuleActions;
GlobalStateHolder<vector<DNSDistResponseRuleAction> > g_selfansweredrespruleactions;
GlobalStateHolder<servers_t> g_dstates;
return true;
}
-static std::function<bool(PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted)> s_processResponse;
+static std::function<bool(PacketBuffer& response, DNSResponse& dr, bool muted)> s_processResponse;
-bool processResponse(PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted, bool receivedOverUDP)
+bool processResponse(PacketBuffer& response, const std::vector<DNSDistResponseRuleAction>& localRespRuleActions, const std::vector<DNSDistResponseRuleAction>& localCacheInsertedRespRuleActions, DNSResponse& dr, bool muted, bool receivedOverUDP)
{
if (s_processResponse) {
- return s_processResponse(response, localRespRuleActions, dr, muted);
+ return s_processResponse(response, dr, muted);
}
return false;
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
throw std::runtime_error("Unexpected error while processing the response");
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return false;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
s_processQuery = [](DNSQuestion& dq, ClientState& cs, LocalHolders& holders, std::shared_ptr<DownstreamState>& selectedBackend) -> ProcessQueryResult {
return ProcessQueryResult::SendAnswer;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
}
return ProcessQueryResult::Drop;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
}
return ProcessQueryResult::Drop;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = proxyEnabledBackend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = proxyEnabledBackend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = proxyEnabledBackend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend1;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
selectedBackend = backend;
return ProcessQueryResult::PassToBackend;
};
- s_processResponse = [](PacketBuffer& response, LocalStateHolder<vector<DNSDistResponseRuleAction> >& localRespRuleActions, DNSResponse& dr, bool muted) -> bool {
+ s_processResponse = [](PacketBuffer& response, DNSResponse& dr, bool muted) -> bool {
return true;
};
--- /dev/null
+#!/usr/bin/env python
+import base64
+import time
+import dns
+from dnsdisttests import DNSDistTest
+
+class TestCacheInsertedResponses(DNSDistTest):
+
+ capTTLMax = 3600
+ capTTLMin = 60
+ _config_template = """
+ pc = newPacketCache(100, {maxTTL=86400, minTTL=1})
+ getPool(""):setCache(pc)
+ addCacheInsertedResponseAction(makeRule("cacheinsertedresponses.tests.powerdns.com."), LimitTTLResponseAction(%d, %d))
+ newServer{address="127.0.0.1:%s"}
+ """
+ _config_params = ['capTTLMax', 'capTTLMin', '_testServerPort']
+
+ def testTTLSetAfterInsertion(self):
+ """
+ CacheInsertedResponse: Check that the TTL is capped after inserting into the cache
+ """
+ initialTTL = 86400
+ name = 'reduce-ttl-after-insertion.cacheinsertedresponses.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'AAAA', 'IN')
+
+ response = dns.message.make_response(query)
+ rrset = dns.rrset.from_text(name,
+ initialTTL,
+ dns.rdataclass.IN,
+ dns.rdatatype.AAAA,
+ '::1')
+ response.answer.append(rrset)
+
+ responseOnMiss = dns.message.make_response(query)
+ rrset = dns.rrset.from_text(name,
+ self.capTTLMax,
+ dns.rdataclass.IN,
+ dns.rdatatype.AAAA,
+ '::1')
+ responseOnMiss.answer.append(rrset)
+
+ # first query to fill the cache
+ (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEqual(query, receivedQuery)
+ self.assertEqual(receivedResponse, responseOnMiss)
+ self.assertLessEqual(receivedResponse.answer[0].ttl, self.capTTLMax)
+
+ # now the result should be cached
+ (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False)
+ self.assertEqual(receivedResponse, response)
+ self.assertGreater(receivedResponse.answer[0].ttl, self.capTTLMax)
+ self.assertLessEqual(receivedResponse.answer[0].ttl, initialTTL)
+
+ def testTTLRaisedAfterInsertion(self):
+ """
+ CacheInsertedResponse: Check that the TTL can be raised after inserting into the cache
+ """
+ initialTTL = 0
+ name = 'raise-ttl-after-insertion.cacheinsertedresponses.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'AAAA', 'IN')
+
+ response = dns.message.make_response(query)
+ rrset = dns.rrset.from_text(name,
+ initialTTL,
+ dns.rdataclass.IN,
+ dns.rdatatype.AAAA,
+ '::1')
+ response.answer.append(rrset)
+
+ responseOnMiss = dns.message.make_response(query)
+ rrset = dns.rrset.from_text(name,
+ self.capTTLMax,
+ dns.rdataclass.IN,
+ dns.rdatatype.AAAA,
+ '::1')
+ responseOnMiss.answer.append(rrset)
+
+ # first query to fill the cache
+ (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEqual(query, receivedQuery)
+ self.assertEqual(receivedResponse, responseOnMiss)
+ self.assertGreater(receivedResponse.answer[0].ttl, initialTTL)
+ self.assertLessEqual(receivedResponse.answer[0].ttl, self.capTTLMin)
+
+ # the result should NOT have been cached
+ (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ self.assertTrue(receivedResponse)
+ receivedQuery.id = query.id
+ self.assertEqual(query, receivedQuery)
+ self.assertEqual(receivedResponse, responseOnMiss)
+ self.assertGreater(receivedResponse.answer[0].ttl, initialTTL)
+ self.assertLessEqual(receivedResponse.answer[0].ttl, self.capTTLMin)
+