{"Delay", (int)DNSAction::Action::Delay}}
);
+ g_lua.writeVariable("DNSResponseAction", std::unordered_map<string,int>{
+ {"None",(int)DNSResponseAction::Action::None}}
+ );
+
vector<pair<string, int> > dd;
for(const auto& n : QType::names)
dd.push_back({n.first, n.second});
g_lua.writeFunction("setECSOverride", [](bool override) { g_ECSOverride=override; });
- g_lua.writeFunction("addResponseAction", [](luadnsrule_t var, std::shared_ptr<DNSAction> ea) {
+ g_lua.writeFunction("addResponseAction", [](luadnsrule_t var, std::shared_ptr<DNSResponseAction> ea) {
setLuaSideEffect();
auto rule=makeRule(var);
g_resprulactions.modify([rule, ea](decltype(g_resprulactions)::value_type& rulactions){
return std::shared_ptr<DNSAction>(new RemoteLogAction(logger));
});
g_lua.writeFunction("RemoteLogResponseAction", [](std::shared_ptr<RemoteLogger> logger) {
- return std::shared_ptr<DNSAction>(new RemoteLogResponseAction(logger));
+ return std::shared_ptr<DNSResponseAction>(new RemoteLogResponseAction(logger));
});
g_lua.writeFunction("newRemoteLogger", [client](const std::string& remote) {
return std::make_shared<RemoteLogger>(ComboAddress(remote));
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
- if (!processQuery(localDynBlockNMG, localRulactions, blockFilter, dq, ci.remote, poolname, &delayMsec, now)) {
+ if (!processQuery(localDynBlockNMG, localRulactions, blockFilter, dq, poolname, &delayMsec, now)) {
goto drop;
}
break;
}
- DNSQuestion dr(&rqname, rqtype, rqclass, &ci.cs->local, &ci.remote, dh, responseSize, responseLen, true);
+ DNSQuestion dr(&qname, qtype, qclass, &ci.cs->local, &ci.remote, dh, responseSize, responseLen, true);
#ifdef HAVE_PROTOBUF
dr.uniqueId = dq.uniqueId;
#endif
- for(const auto& lr : *localRespRulactions) {
- if(lr.first->matches(&dr)) {
- lr.first->d_matches++;
- /* for now we only support actions returning None */
- (*lr.second)(&dr, &ruleresult);
- }
+ if (!processResponse(localRespRulactions, dr)) {
+ break;
}
if (packetCache && !dq.skipCache) {
If all downstreams are over QPS, we pick the fastest server */
GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > > g_rulactions;
-GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > > g_resprulactions;
+GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSResponseAction> > > > g_resprulactions;
Rings g_rings;
GlobalStateHolder<servers_t> g_dstates;
dh->id = ids->origID;
uint16_t addRoom = 0;
- DNSQuestion dq(&ids->qname, ids->qtype, ids->qclass, &ids->origDest, &ids->origRemote, dh, sizeof(packet), responseLen, false);
+ DNSQuestion dr(&ids->qname, ids->qtype, ids->qclass, &ids->origDest, &ids->origRemote, dh, sizeof(packet), responseLen, false);
#ifdef HAVE_PROTOBUF
- dq.uniqueId = ids->uniqueId;
+ dr.uniqueId = ids->uniqueId;
#endif
- string ruleresult;
- for(const auto& lr : *localRespRulactions) {
- if(lr.first->matches(&dq)) {
- lr.first->d_matches++;
- /* for now we only support actions returning None */
- (*lr.second)(&dq, &ruleresult);
- }
+ if (!processResponse(localRespRulactions, dr)) {
+ break;
}
#ifdef HAVE_DNSCRYPT
}
}
-bool processQuery(LocalStateHolder<NetmaskTree<DynBlock> >& localDynBlock, LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, const ComboAddress& remote, string& poolname, int* delayMsec, const struct timespec& now)
+bool processQuery(LocalStateHolder<NetmaskTree<DynBlock> >& localDynBlock, LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, string& poolname, int* delayMsec, const struct timespec& now)
{
{
WriteLock wl(&g_rings.queryLock);
- g_rings.queryRing.push_back({now,remote,*dq.qname,dq.len,dq.qtype,*dq.dh});
+ g_rings.queryRing.push_back({now,*dq.remote,*dq.qname,dq.len,dq.qtype,*dq.dh});
}
- if(auto got=localDynBlock->lookup(remote)) {
+ if(auto got=localDynBlock->lookup(*dq.remote)) {
if(now < got->second.until) {
- vinfolog("Query from %s dropped because of dynamic block", remote.toStringWithPort());
+ vinfolog("Query from %s dropped because of dynamic block", dq.remote->toStringWithPort());
g_stats.dynBlocked++;
got->second.blocks++;
return false;
return true;
}
+bool processResponse(LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSResponseAction> > > >& localRespRulactions, DNSQuestion& dr)
+{
+ std::string ruleresult;
+ for(const auto& lr : *localRespRulactions) {
+ if(lr.first->matches(&dr)) {
+ lr.first->d_matches++;
+ /* for now we only support actions returning None */
+ (*lr.second)(&dr, &ruleresult);
+ }
+ }
+
+ return true;
+}
+
static ssize_t udpClientSendRequestToBackend(DownstreamState* ss, const int sd, const char* request, const size_t requestLen)
{
if (ss->sourceItf == 0) {
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
- if (!processQuery(localDynBlock, localRulactions, blockFilter, dq, remote, poolname, &delayMsec, now))
+ if (!processQuery(localDynBlock, localRulactions, blockFilter, dq, poolname, &delayMsec, now))
{
continue;
}
virtual string toString() const = 0;
};
+class DNSResponseAction
+{
+public:
+ enum class Action { None };
+ virtual Action operator()(DNSQuestion*, string* ruleresult) const =0;
+ virtual string toString() const = 0;
+};
+
using NumberedServerVector = NumberedVector<shared_ptr<DownstreamState>>;
typedef std::function<shared_ptr<DownstreamState>(const NumberedServerVector& servers, const DNSQuestion*)> policyfunc_t;
extern GlobalStateHolder<servers_t> g_dstates;
extern GlobalStateHolder<pools_t> g_pools;
extern GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > > g_rulactions;
-extern GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > > g_resprulactions;
+extern GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSResponseAction> > > > g_resprulactions;
extern GlobalStateHolder<NetmaskGroup> g_ACL;
extern ComboAddress g_serverControl; // not changed during runtime
void resetLuaSideEffect(); // reset to indeterminate state
bool responseContentMatches(const char* response, const uint16_t responseLen, const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& remote);
-bool processQuery(LocalStateHolder<NetmaskTree<DynBlock> >& localDynBlock, LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, const ComboAddress& remote, string& poolname, int* delayMsec, const struct timespec& now);
+bool processQuery(LocalStateHolder<NetmaskTree<DynBlock> >& localDynBlock, LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, string& poolname, int* delayMsec, const struct timespec& now);
+bool processResponse(LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSResponseAction> > > >& localRespRulactions, DNSQuestion& dq);
bool fixUpResponse(char** response, uint16_t* responseLen, size_t* responseSize, const DNSName& qname, uint16_t origFlags, bool ednsAdded, std::vector<uint8_t>& rewrittenResponse, uint16_t addRoom);
void restoreFlags(struct dnsheader* dh, uint16_t origFlags);
std::shared_ptr<RemoteLogger> d_logger;
};
-class RemoteLogResponseAction : public DNSAction, public boost::noncopyable
+class RemoteLogResponseAction : public DNSResponseAction, public boost::noncopyable
{
public:
RemoteLogResponseAction(std::shared_ptr<RemoteLogger> logger): d_logger(logger)
{
}
- DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
+ DNSResponseAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
{
d_logger->logResponse(*dq);
return Action::None;