From: bert hubert Date: Thu, 5 Mar 2015 11:54:12 +0000 (+0100) Subject: parse whole config before daemonize now, which means we can complain to the operator X-Git-Tag: dnsdist-1.0.0-alpha1~248^2~88^2~93 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2e72cc0e29b8fa6f3564bd71ffb8c95356bfa2d2;p=thirdparty%2Fpdns.git parse whole config before daemonize now, which means we can complain to the operator fix traffic ending up in pools where it did not belong --- diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index d2220ece4d..c036e8f50a 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -7,25 +7,39 @@ using std::thread; -void setupLua(bool client) +static vector>* g_launchWork; + +vector> setupLua(bool client) { + g_launchWork= new vector>(); g_lua.writeFunction("newServer", - [](boost::variant> pvars, boost::optional qps) + [client](boost::variant> pvars, boost::optional qps) { + if(client) { + return shared_ptr(); + } if(auto address = boost::get(&pvars)) { auto ret=std::make_shared(ComboAddress(*address, 53)); - ret->tid = move(thread(responderThread, ret)); + if(qps) { ret->qps=QPSLimiter(*qps, *qps); } g_dstates.push_back(ret); + + if(g_launchWork) { + g_launchWork->push_back([ret]() { + ret->tid = move(thread(responderThread, ret)); + }); + } + else { + ret->tid = move(thread(responderThread, ret)); + } + return ret; } auto vars=boost::get>(pvars); auto ret=std::make_shared(ComboAddress(vars["address"], 53)); - - ret->tid = move(thread(responderThread, ret)); - + if(vars.count("qps")) { ret->qps=QPSLimiter(boost::lexical_cast(vars["qps"]),boost::lexical_cast(vars["qps"])); } @@ -42,6 +56,14 @@ void setupLua(bool client) ret->weight=boost::lexical_cast(vars["weight"]); } + if(g_launchWork) { + g_launchWork->push_back([ret]() { + ret->tid = move(thread(responderThread, ret)); + }); + } + else { + ret->tid = move(thread(responderThread, ret)); + } g_dstates.push_back(ret); std::stable_sort(g_dstates.begin(), g_dstates.end(), [](const decltype(ret)& a, const decltype(ret)& b) { @@ -86,6 +108,18 @@ void setupLua(bool client) g_lua.writeFunction("addACL", [](const std::string& domain) { g_ACL.addMask(domain); }); + + g_lua.writeFunction("addLocal", [client](const std::string& addr) { + if(client) + return; + try { + ComboAddress loc(addr, 53); + g_locals.push_back(loc); + } + catch(std::exception& e) { + g_outputBuffer="Error: "+string(e.what())+"\n"; + } + }); g_lua.writeFunction("setACL", [](const vector>& parts) { NetmaskGroup nmg; for(const auto& p : parts) { @@ -285,11 +319,6 @@ void setupLua(bool client) dh.qr=v; }); - std::ifstream ifs(g_vm["config"].as()); - if(!ifs) - warnlog("Unable to read configuration from '%s'", g_vm["config"].as()); - else - infolog("Read configuration from '%s'", g_vm["config"].as()); g_lua.registerFunction("tostring", &ComboAddress::toString); @@ -314,8 +343,15 @@ void setupLua(bool client) SSetsockopt(sock, SOL_SOCKET, SO_REUSEADDR, 1); SBind(sock, local); SListen(sock, 5); - thread t(controlThread, sock, local); - t.detach(); + auto launch=[sock, local]() { + thread t(controlThread, sock, local); + t.detach(); + }; + if(g_launchWork) + g_launchWork->push_back(launch); + else + launch(); + } catch(std::exception& e) { errlog("Unable to bind to control socket on %s: %s", local.toStringWithPort(), e.what()); @@ -487,6 +523,12 @@ void setupLua(bool client) string encrypted = sodEncryptSym(testmsg, g_key, sn); string decrypted = sodDecryptSym(encrypted, g_key, sn2); + sn.increment(); + sn2.increment(); + + encrypted = sodEncryptSym(testmsg, g_key, sn); + decrypted = sodDecryptSym(encrypted, g_key, sn2); + if(testmsg == decrypted) g_outputBuffer="Everything is ok!\n"; else @@ -498,6 +540,15 @@ void setupLua(bool client) }}); + std::ifstream ifs(g_vm["config"].as()); + if(!ifs) + warnlog("Unable to read configuration from '%s'", g_vm["config"].as()); + else + infolog("Read configuration from '%s'", g_vm["config"].as()); g_lua.executeCode(ifs); + auto ret=*g_launchWork; + delete g_launchWork; + g_launchWork=0; + return ret; } diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 07d7560f58..9e2610381b 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -49,10 +49,8 @@ We neglect to do recvfromto() on 0.0.0.0 Receiver is currently singlethreaded (not that bad actually) We can't compile w/o crypto - our naming is as inconsistent as only ahu can make it lack of help() we offer now way to log from Lua - our startup fails *after* fork on most cases, which is not overly helpful */ ArgvMap& arg() @@ -72,7 +70,7 @@ uint16_t g_maxOutstanding; bool g_console; NetmaskGroup g_ACL; string g_outputBuffer; - +vector g_locals; /* UDP: the grand design. Per socket we listen on for incoming queries there is one thread. Then we have a bunch of connected sockets for talking to downstream servers. @@ -268,12 +266,9 @@ ComboAddress g_serverControl{"127.0.0.1:5199"}; servers_t getDownstreamCandidates(const std::string& pool) { - if(pool.empty()) - return g_dstates; - servers_t ret; for(auto& s : g_dstates) - if(s->pools.count(pool)) + if((pool.empty() && s->pools.empty()) || s->pools.count(pool)) ret.push_back(s); return ret; @@ -800,6 +795,22 @@ void doClient(ComboAddress server) writen2(fd, (const char*)ours.value, sizeof(ours.value)); readn2(fd, (char*)theirs.value, sizeof(theirs.value)); + if(g_vm.count("command")) { + auto command = g_vm["command"].as(); + string response; + string msg=sodEncryptSym(command, g_key, ours); + putMsgLen(fd, msg.length()); + writen2(fd, msg); + uint16_t len; + getMsgLen(fd, &len); + char resp[len]; + readn2(fd, resp, len); + msg.assign(resp, len); + msg=sodDecryptSym(msg, g_key, theirs); + cout< dupper; { ifstream history(".history"); @@ -917,6 +928,7 @@ try ("help,h", "produce help message") ("config", po::value()->default_value("/etc/dnsdist.conf"), "Filename with our configuration") ("client", "be a client") + ("command,c", po::value(), "Execute this command on a running dnsdist") ("daemon", po::value()->default_value(true), "run in background") ("local", po::value >(), "Listen on which addresses") ("max-outstanding", po::value()->default_value(65535), "maximum outstanding queries per downstream") @@ -947,11 +959,36 @@ try g_policy = leastOutstandingPol; - if(g_vm.count("client")) { + if(g_vm.count("client") || g_vm.count("command")) { setupLua(true); doClient(g_serverControl); exit(EXIT_SUCCESS); } + + auto todo=setupLua(false); + + if(g_vm.count("local")) { + g_locals.clear(); + for(auto loc : g_vm["local"].as >()) + g_locals.push_back(ComboAddress(loc, 53)); + } + + if(g_locals.empty()) + g_locals.push_back(ComboAddress("0.0.0.0", 53)); + + + vector toLaunch; + for(const auto& local : g_locals) { + ClientState* cs = new ClientState; + cs->local= local; + cs->udpFD = SSocket(cs->local.sin4.sin_family, SOCK_DGRAM, 0); + if(cs->local.sin4.sin_family == AF_INET6) { + SSetsockopt(cs->udpFD, IPPROTO_IPV6, IPV6_V6ONLY, 1); + } + SBind(cs->udpFD, cs->local); + toLaunch.push_back(cs); + } + if(g_vm["daemon"].as()) { g_console=false; daemonize(); @@ -960,10 +997,13 @@ try vinfolog("Running in the foreground"); } + for(auto& t : todo) + t(); + for(auto& addr : {"127.0.0.0/8", "10.0.0.0/8", "100.64.0.0/10", "169.254.0.0/16", "192.168.0.0/16", "172.16.0.0/12", "::1/128", "fc00::/7", "fe80::/10"}) g_ACL.addMask(addr); - setupLua(false); + if(g_vm.count("remotes")) { for(const auto& address : g_vm["remotes"].as>()) { auto ret=std::make_shared(ComboAddress(address, 53)); @@ -980,28 +1020,15 @@ try } } - vector locals; - if(g_vm.count("local")) - locals = g_vm["local"].as >(); - else - locals.push_back("::"); - - for(const string& local : locals) { - ClientState* cs = new ClientState; - cs->local= ComboAddress(local, 53); - cs->udpFD = SSocket(cs->local.sin4.sin_family, SOCK_DGRAM, 0); - if(cs->local.sin4.sin_family == AF_INET6) { - SSetsockopt(cs->udpFD, IPPROTO_IPV6, IPV6_V6ONLY, 1); - } - SBind(cs->udpFD, cs->local); + for(auto& cs : toLaunch) { thread t1(udpClientThread, cs); t1.detach(); } - for(const string& local : locals) { + for(const auto& local : g_locals) { ClientState* cs = new ClientState; - cs->local= ComboAddress(local, 53); + cs->local= local; cs->tcpFD = SSocket(cs->local.sin4.sin_family, SOCK_STREAM, 0); diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 7f410a0c93..cd09f42e61 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -200,7 +200,7 @@ extern LuaContext g_lua; extern ServerPolicy g_policy; extern servers_t g_dstates; extern std::string g_outputBuffer; - +extern std::vector g_locals; struct dnsheader; std::shared_ptr firstAvailable(const servers_t& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh); std::shared_ptr leastOutstanding(const servers_t& servers, const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh); @@ -213,7 +213,8 @@ extern SuffixMatchNode g_suffixMatchNodeFilter; extern ComboAddress g_serverControl; void controlThread(int fd, ComboAddress local); extern NetmaskGroup g_ACL; -void setupLua(bool client); + +vector> setupLua(bool client); extern std::string g_key; namespace po = boost::program_options; extern po::variables_map g_vm; diff --git a/pdns/dnsdistconf.lua b/pdns/dnsdistconf.lua index 100f2de858..d77986e2f5 100644 --- a/pdns/dnsdistconf.lua +++ b/pdns/dnsdistconf.lua @@ -1,4 +1,5 @@ controlSocket("0.0.0.0") +addLocal("0.0.0.0:5200") setKey("MXNeLFWHUe4363BBKrY06cAsH8NWNb+Se2eXU5+Bb74=") -- define the good servers