From: bert hubert Date: Sun, 29 Nov 2015 10:51:00 +0000 (+0100) Subject: the day you new that would be arriving: a Lua configuration file for Recursor. Also... X-Git-Tag: dnsdist-1.0.0-alpha1~173 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e61e7f77b3c39c10b1b0bf33b75bc1f475f7c3e;p=thirdparty%2Fpdns.git the day you new that would be arriving: a Lua configuration file for Recursor. Also implements sortlist & makes Lua mandatory (for now) in Recursor --- diff --git a/build-scripts/dist-recursor b/build-scripts/dist-recursor index 5c23043088..42e398c1bc 100755 --- a/build-scripts/dist-recursor +++ b/build-scripts/dist-recursor @@ -38,7 +38,7 @@ ws-recursor.hh ws-api.hh secpoll-recursor.hh \ responsestats.hh webserver.hh dnsname.hh dnspacket.hh ednssubnet.hh \ filterpo.hh rpzloader.hh ixfr.hh gss_context.hh resolver.hh dnssecinfra.hh \ dnsseckeeper.hh statbag.hh ueberbackend.hh sha.hh dnsbackend.hh comment.hh \ -validate.hh validate-recursor.hh" +validate.hh validate-recursor.hh sortlist.hh" CFILES="syncres.cc iputils.cc misc.cc unix_utility.cc qtype.cc \ logger.cc arguments.cc lwres.cc pdns_recursor.cc lua-iputils.cc \ @@ -50,7 +50,8 @@ devpollmplexer.cc recpacketcache.cc dns.cc reczones.cc base32.cc nsecrecords.cc dnslabeltext.cc json.cc ws-recursor.cc ws-api.cc version.cc dns_random.cc \ responsestats.cc webserver.cc rec-carbon.cc secpoll-recursor.cc dnsname.cc \ filterpo.cc rpzloader.cc ixfr.cc dnssecinfra.cc gss_context.cc resolver.cc \ -ednssubnet.cc validate.cc validate-recursor.cc mbedtlssigners.cc" +ednssubnet.cc validate.cc validate-recursor.cc mbedtlssigners.cc rec-lua-conf.cc \ +sortlist.cc" ./mkpubsuffixcc @@ -81,6 +82,9 @@ cp -a ../ext/mbedtls/library/{aes.c,base64.c,md.c,md_wrap.c,md5.c,sha1.c,sha256. cp -a ../ext/mbedtls/library/{rsa.c,bignum.c,oid.c,asn1parse.c,ctr_drbg.c,entropy.c,entropy_poll.c,timing.c} $DIRNAME/ext/mbedtls/library cp -a ../ext/yahttp/ $DIRNAME/ext/yahttp + +mkdir -p $DIRNAME/ext/luawrapper/include +cp ../ext/luawrapper/include/LuaContext.hpp $DIRNAME/ext/luawrapper/include echo '#include "../../../config.h"' > $DIRNAME/ext/yahttp/yahttp/yahttp-config.h mkdir $DIRNAME/rrd cp tools/rrd/{create,update,makegraphs,index.html} $DIRNAME/rrd diff --git a/pdns/Makefile-recursor b/pdns/Makefile-recursor index 436a56e32d..d32a8a8046 100644 --- a/pdns/Makefile-recursor +++ b/pdns/Makefile-recursor @@ -32,7 +32,8 @@ reczones.o base32.o nsecrecords.o json.o ws-recursor.o ws-api.o \ version.o responsestats.o webserver.o ext/yahttp/yahttp/reqresp.o ext/yahttp/yahttp/router.o \ rec-carbon.o secpoll-recursor.o lua-iputils.o iputils.o dnsname.o \ rpzloader.o filterpo.o resolver.o ixfr.o dnssecinfra.o gss_context.o \ -ednssubnet.o validate.o validate-recursor.o mbedtlssigners.o +ednssubnet.o validate.o validate-recursor.o mbedtlssigners.o \ +rec-lua-conf.o sortlist.o REC_CONTROL_OBJECTS=rec_channel.o rec_control.o arguments.o misc.o \ unix_utility.o logger.o qtype.o dnslabeltext.o dnsname.o diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 315e84a427..7dcb6b5b39 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1128,6 +1128,7 @@ pdns_recursor_SOURCES = \ rec-carbon.cc \ rec_channel.cc rec_channel.hh \ rec_channel_rec.cc \ + rec-lua-conf.cc \ recpacketcache.cc recpacketcache.hh \ recursor_cache.cc recursor_cache.hh \ reczones.cc \ @@ -1139,6 +1140,7 @@ pdns_recursor_SOURCES = \ secpoll-recursor.hh \ selectmplexer.cc \ sillyrecords.cc \ + sortlist.cc sortlist.hh \ statbag.cc \ syncres.cc syncres.hh \ unix_utility.cc \ diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 8346d56693..8c1e09d376 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -23,6 +23,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif + #include #include #include @@ -49,6 +50,8 @@ #include "syncres.hh" #include #include +#include "sortlist.hh" +extern SortList g_sortlist; #include "sstuff.hh" #include #include @@ -81,7 +84,7 @@ #include "statbag.hh" StatBag S; #endif - +void loadRecursorLuaConfig(const std::string& fname); __thread FDMultiplexer* t_fdm; __thread unsigned int t_id; unsigned int g_maxTCPPerClient; @@ -816,6 +819,10 @@ void startDoResolve(void *p) if(ret.size()) { orderAndShuffle(ret); + if(auto sl = g_sortlist.getOrderCmp(dc->d_remote)) { + sort(ret.begin(), ret.end(), *sl); + variableAnswer=true; + } for(auto i=ret.cbegin(); i!=ret.cend(); ++i) { pw.startRecord(i->d_name, i->d_type, i->d_ttl, i->d_class, i->d_place); minTTL = min(minTTL, i->d_ttl); @@ -2551,6 +2558,7 @@ int main(int argc, char **argv) ::arg().set("auth-zones", "Zones for which we have authoritative data, comma separated domain=file pairs ")=""; ::arg().set("rpz-files", "RPZ files to load in order, domain or domain=policy pairs separated by commas")=""; ::arg().set("rpz-masters", "RPZ master servers, address:name pairs separated by commas")=""; + ::arg().set("lua-config-file", "More powerful configuration options")=""; ::arg().set("forward-zones", "Zones for which we forward queries, comma separated domain=ip pairs")=""; ::arg().set("forward-zones-recurse", "Zones for which we forward queries with recursion bit, comma separated domain=ip pairs")=""; @@ -2600,6 +2608,8 @@ int main(int argc, char **argv) ::arg().parse(argc,argv); + loadRecursorLuaConfig(::arg()["lua-config-file"]); + ::arg().set("delegation-only")=toLower(::arg()["delegation-only"]); if(::arg().asNum("threads")==1) diff --git a/pdns/rec-lua-conf.cc b/pdns/rec-lua-conf.cc new file mode 100644 index 0000000000..1dabe6e7c0 --- /dev/null +++ b/pdns/rec-lua-conf.cc @@ -0,0 +1,58 @@ +#include "ext/luawrapper/include/LuaContext.hpp" +#include +#include "namespaces.hh" +#include "logger.hh" +#include "sortlist.hh" + +SortList g_sortlist; +void loadRecursorLuaConfig(const std::string& fname) +{ + LuaContext Lua; + if(fname.empty()) + return; + ifstream ifs(fname); + if(!ifs) { + theL()<<"Unable to read configuration file from '"< > > > > argvec_t; + Lua.writeFunction("addSortList", + [](const std::string& formask_, + const boost::variant& masks, + boost::optional order_) + { + try { + Netmask formask(formask_); + int order = order_ ? (*order_) : g_sortlist.getMaxOrder(formask)+1; + if(auto str = boost::get(&masks)) + g_sortlist.addEntry(formask, Netmask(*str), order); + else { + + auto vec = boost::get(&masks); + for(const auto& e : *vec) { + if(auto s = boost::get(&e.second)) { + g_sortlist.addEntry(formask, Netmask(*s), order); + } + else { + const auto& v =boost::get > >(e.second); + for(const auto& e : v) + g_sortlist.addEntry(formask, Netmask(e.second), order); + } + ++order; + } + } + } + catch(std::exception& e) { + theL()<first == formask) { + for(const auto& o : place->second.d_orders) + order = std::max(order, o->second); // aki, shouldn't this be o.second? + } + + return order; +} + +void SortList::addEntry(const Netmask& formask, const Netmask& valmask, int order) +{ + if(order < 0) { + order=getMaxOrder(formask); + ++order; + } + // cout<<"Adding for netmask "< SortList::getOrderCmp(const ComboAddress& who) +{ + if(!d_sortlist.match(who)) { + return std::unique_ptr(); + } + auto fnd = d_sortlist.lookup(who); + // cerr<<"Returning sort order for "<second.d_orders.size()<<" entries"<(fnd->second); +} + +bool SortListOrderCmp::operator()(const ComboAddress& a, const ComboAddress& b) const +{ + int aOrder=std::numeric_limits::max(); + int bOrder=aOrder; + + if(d_slo.d_orders.match(a)) + aOrder = d_slo.d_orders[a]; + if(d_slo.d_orders.match(b)) + bOrder = d_slo.d_orders[b]; + + return aOrder < bOrder; +} + +static ComboAddress getAddr(const DNSRecord& dr) +{ + if(auto addr=getRR(dr)) { + return addr->getCA(); + } + else + return getRR(dr)->getCA(); +} +bool SortListOrderCmp::operator()(const DNSRecord& ar, const DNSRecord& br) const +{ + if(ar.d_type < br.d_type) + return true; + if(ar.d_type > br.d_type) + return false; + + if(ar.d_type != QType::A && ar.d_type != QType::AAAA) + return false; // all other types are equal among themselves + + int aOrder=std::numeric_limits::max(); + int bOrder=aOrder; + + ComboAddress a=getAddr(ar), b=getAddr(br); + + if(d_slo.d_orders.match(a)) + aOrder = d_slo.d_orders.lookup(a)->second; + else { + // cout<<"Could not find anything for "<second; + else { + // cout<<"Could not find anything for "< d_orders; +}; + + +struct SortListOrderCmp +{ + SortListOrderCmp(SortListOrder slo) : d_slo(slo) {} + bool operator()(const ComboAddress& a, const ComboAddress& b) const; + bool operator()(const DNSRecord& a, const DNSRecord& b) const; + const SortListOrder d_slo; +}; + +class SortList { +public: + void clear(); + void addEntry(const Netmask& covers, const Netmask& answermask, int order=-1); + int getMaxOrder(const Netmask& formask) const; + std::unique_ptr getOrderCmp(const ComboAddress& who); +private: + + NetmaskTree d_sortlist; +};