#include "dnsparser.hh"
#include "syncres.hh"
#include "namespaces.hh"
-
+#include "rec_channel.hh"
#if !defined(HAVE_LUA)
RecursorLua4::RecursorLua4(const std::string &fname)
{
addRecord(type, content, DNSResourceRecord::ANSWER, ttl, name);
}
-
+
+struct DynMetric
+{
+ std::atomic<unsigned long>* ptr;
+ void inc() { (*ptr)++; }
+ void incBy(unsigned int by) { (*ptr)+= by; }
+ unsigned long get() { return *ptr; }
+ void set(unsigned long val) { *ptr =val; }
+};
+
RecursorLua4::RecursorLua4(const std::string& fname)
{
d_lw = new LuaContext;
for(const auto& n : QType::names)
pd.push_back({n.first, n.second});
d_lw->writeVariable("pdns", pd);
+
+ d_lw->writeFunction("getMetric", [](const std::string& str) {
+ return DynMetric{getDynMetric(str)};
+ });
+
+ d_lw->registerFunction("inc", &DynMetric::inc);
+ d_lw->registerFunction("incBy", &DynMetric::incBy);
+ d_lw->registerFunction("set", &DynMetric::set);
+ d_lw->registerFunction("get", &DynMetric::get);
+
ifstream ifs(fname);
if(!ifs) {
/*
PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2002-2012 PowerDNS.COM BV
+ Copyright (C) 2002-2015 PowerDNS.COM BV
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2
magic2 = newDN("www.magic2.com")
+
+magicMetric = getMetric("magic")
+
-- shows the various ways of blocking, dropping, changing questions
-- return false to say you did not take over the question, but we'll still listen to 'variable'
-- to selectively disable the cache
function preresolve(dq)
print("Got question for "..dq.qname:toString().." from "..dq.remoteaddr:toString().." to "..dq.localaddr:toString())
+ loc = newCA("127.0.0.1")
+ if(dq.remoteaddr:equal(loc))
+ then
+ print("Query from loopback")
+ end
+
-- note that the comparisons below are CaSe InSensiTivE and you don't have to worry about trailing dots
if(dq.qname:equal("magic.com"))
then
+ magicMetric:inc()
print("Magic!")
else
print("not magic..")
badips = newNMG()
-badips:addMask("127.0.0.0/8")
+badips:addMask("127.1.0.0/16")
-- this check is applied before any packet parsing is done
function ipfilter(loc, rem)
std::vector<ComboAddress>* pleaseGetServfailRemotes();
std::vector<ComboAddress>* pleaseGetLargeAnswerRemotes();
DNSName getRegisteredName(const DNSName& dom);
+std::atomic<unsigned long>* getDynMetric(const std::string& str);
#endif
map<string, const uint32_t*> d_get32bitpointers;
map<string, const uint64_t*> d_get64bitpointers;
map<string, function< uint32_t() > > d_get32bitmembers;
-
+pthread_mutex_t d_dynmetricslock = PTHREAD_MUTEX_INITIALIZER;
+map<string, std::atomic<unsigned long>* > d_dynmetrics;
void addGetStat(const string& name, const uint32_t* place)
{
d_get32bitpointers[name]=place;
d_get32bitmembers[name]=f;
}
+std::atomic<unsigned long>* getDynMetric(const std::string& str)
+{
+ Lock l(&d_dynmetricslock);
+ auto f = d_dynmetrics.find(str);
+ if(f != d_dynmetrics.end())
+ return f->second;
+
+ auto ret = new std::atomic<unsigned long>();
+ d_dynmetrics[str]= ret;
+ return ret;
+}
+
optional<uint64_t> get(const string& name)
{
optional<uint64_t> ret;
if(d_get32bitmembers.count(name))
return d_get32bitmembers.find(name)->second();
+ Lock l(&d_dynmetricslock);
+ auto f =rplookup(d_dynmetrics, name);
+ if(f)
+ return (*f)->load();
+
return ret;
}
continue; // too slow for 'get-all'
ret.insert(make_pair(the32bitmembers.first, std::to_string(the32bitmembers.second())));
}
+ Lock l(&d_dynmetricslock);
+ for(const auto& a : d_dynmetrics)
+ ret.insert({a.first, std::to_string(*a.second)});
return ret;
}