]> granicus.if.org Git - pdns/commitdiff
dnsdist: Move {add,set}Local() additional parameters to a table
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 29 May 2017 12:58:08 +0000 (14:58 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 29 May 2017 13:02:21 +0000 (15:02 +0200)
pdns/README-dnsdist.md
pdns/dnsdist-console.cc
pdns/dnsdist-lua.cc
pdns/dnsdist-lua.hh
pdns/dnsdist-lua2.cc

index 1670f1b7bed2f88dd81399802c6ad8024a7b37b0..7a905e3d1ed42f8e8a06d4b4d9cba78f73e33de6 100644 (file)
@@ -999,10 +999,10 @@ the `addLocal()` and `setLocal()` directives to be able to add several identical
 local binds to `dnsdist`:
 
 ```
-addLocal("192.0.2.1:53", true, true)
-addLocal("192.0.2.1:53", true, true)
-addLocal("192.0.2.1:53", true, true)
-addLocal("192.0.2.1:53", true, true)
+addLocal("192.0.2.1:53", { reusePort=true })
+addLocal("192.0.2.1:53", { reusePort=true })
+addLocal("192.0.2.1:53", { reusePort=true })
+addLocal("192.0.2.1:53", { reusePort=true })
 ```
 
 `dnsdist` will then add four identical local binds as if they were different IPs
@@ -1341,8 +1341,8 @@ Here are all functions:
     * member `muted`: if set to true, UDP responses will not be sent for queries received on this bind. Default to false
     * member `toString()`: print the address this bind listens to
  * Network related:
-    * `addLocal(netmask, [true], [false], [TCP Fast Open queue size], [interface])`: add to addresses we listen on. Second optional parameter sets TCP or not (UDP is always enabled). Third optional parameter sets SO_REUSEPORT when available. Fourth parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. Last one specifies the network interface to use
-    * `setLocal(netmask, [true], [false], [TCP Fast Open queue size], [interface])`: reset list of addresses we listen on to this address. Second optional parameter sets TCP or not (UDP is always enabled). Third optional parameter sets SO_REUSEPORT when available. Fourth parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. Last one specifies the network interface to use
+    * `addLocal(addr, [, {doTCP=true, reusePort=false, tcpFastOpenSize=0, interface=\"\"}])`: add `addr` to the list of addresses we listen on. The second parameter is an optional table: `doTCP` sets TCP or not (UDP is always enabled), `reusePort` sets SO_REUSEPORT when available, `tcpFastOpenSize` sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0, `interface` sets the network interface to use
+    * `setLocal(addr, [, {doTCP=true, reusePort=false, tcpFastOpenSize=0, interface=\"\"}])`: reset list of addresses we listen on to this address. The second parameter is the same optional table than the one described in `addLocal()`
  * Blocking related:
     * `addDomainBlock(domain)`: block queries within this domain
  * Carbon/Graphite/Metronome statistics related:
@@ -1631,7 +1631,7 @@ instantiate a server with additional parameters
     * `setTCPSendTimeout(n)`: set the write timeout on TCP connections from the client, in seconds
     * `setUDPTimeout(n)`: set the maximum time dnsdist will wait for a response from a backend over UDP, in seconds. Defaults to 2
  * DNSCrypt related:
-    * `addDNSCryptBind("127.0.0.1:8443", "provider name", "/path/to/resolver.cert", "/path/to/resolver.key", [false], [TCP Fast Open queue size], [interface]):` listen to incoming DNSCrypt queries on 127.0.0.1 port 8443, with a provider name of "provider name", using a resolver certificate and associated key stored respectively in the `resolver.cert` and `resolver.key` files. The fifth optional parameter sets SO_REUSEPORT when available. The sixth parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. The last one specifies the network interface to use
+    * `addDNSCryptBind("127.0.0.1:8443", "provider name", "/path/to/resolver.cert", "/path/to/resolver.key", [, {doTCP=true, reusePort=false, tcpFastOpenSize=0, interface=\"\"}]):` listen to incoming DNSCrypt queries on 127.0.0.1 port 8443, with a provider name of "provider name", using a resolver certificate and associated key stored respectively in the `resolver.cert` and `resolver.key` files. The fifth parameter is the same optional table than the one described in `addLocal()`, except that TCP is always enabled
     * `generateDNSCryptProviderKeys("/path/to/providerPublic.key", "/path/to/providerPrivate.key"):` generate a new provider keypair
     * `generateDNSCryptCertificate("/path/to/providerPrivate.key", "/path/to/resolver.cert", "/path/to/resolver.key", serial, validFrom, validUntil):` generate a new resolver private key and related certificate, valid from the `validFrom` UNIX timestamp until the `validUntil` one, signed with the provider private key
     * `printDNSCryptProviderFingerprint("/path/to/providerPublic.key")`: display the fingerprint of the provided resolver public key
index 73e0be0275e8d7a7826c5ed63b0beec3b4dfdaaa..56ef0c419bae628f965516929b14bcb088f925c3 100644 (file)
@@ -275,11 +275,11 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
   { "addAnyTCRule", true, "", "generate TC=1 answers to ANY queries received over UDP, moving them to TCP" },
   { "addDelay", true, "domain, n", "delay answers within that domain by n milliseconds" },
   { "addDisableValidationRule", true, "DNS rule", "set the CD flags to 1 for all queries matching the specified domain" },
-  { "addDNSCryptBind", true, "\"127.0.0.1:8443\", \"provider name\", \"/path/to/resolver.cert\", \"/path/to/resolver.key\", [false], [TCP Fast Open queue size], [interface]", "listen to incoming DNSCrypt queries on 127.0.0.1 port 8443, with a provider name of `provider name`, using a resolver certificate and associated key stored respectively in the `resolver.cert` and `resolver.key` files. The fifth optional parameter sets SO_REUSEPORT when available. The sixth parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. The last one specifies the network interface to use" },
+  { "addDNSCryptBind", true, "\"127.0.0.1:8443\", \"provider name\", \"/path/to/resolver.cert\", \"/path/to/resolver.key\", {reusePort=false, tcpFastOpenSize=0, interface=\"\"}", "listen to incoming DNSCrypt queries on 127.0.0.1 port 8443, with a provider name of `provider name`, using a resolver certificate and associated key stored respectively in the `resolver.cert` and `resolver.key` files. The fifth optional parameter is a table of parameters" },
   { "addDomainBlock", true, "domain", "block queries within this domain" },
   { "addDomainSpoof", true, "domain, ip[, ip6]", "generate answers for A/AAAA/ANY queries using the ip parameters" },
   { "addDynBlocks", true, "addresses, message[, seconds[, action]]", "block the set of addresses with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)" },
-  { "addLocal", true, "netmask, [true], [false], [TCP Fast Open queue size], [interface]", "add to addresses we listen on. Second optional parameter sets TCP or not. Third optional parameter sets SO_REUSEPORT when available. Fourth optional parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. Last one specifies the network interface to use" },
+  { "addLocal", true, "addr [, {doTCP=true, reusePort=false, tcpFastOpenSize=0, interface=\"\"}]", "add `addr` to the list of addresses we listen on" },
   { "addLuaAction", true, "x, func", "where 'x' is all the combinations from `addPoolRule`, and func is a function with the parameter `dq`, which returns an action to be taken on this packet. Good for rare packets but where you want to do a lot of processing" },
   { "addLuaResponseAction", true, "x, func", "where 'x' is all the combinations from `addPoolRule`, and func is a function with the parameter `dr`, which returns an action to be taken on this response packet. Good for rare packets but where you want to do a lot of processing" },
   { "addNoRecurseRule", true, "domain", "clear the RD flag for all queries matching the specified domain" },
@@ -333,7 +333,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
   { "newQPSLimiter", true, "rate, burst", "configure a QPS limiter with that rate and that burst capacity" },
   { "newRemoteLogger", true, "address:port [, timeout=2, maxQueuedEntries=100, reconnectWaitTime=1]", "create a Remote Logger object, to use with `RemoteLogAction()` and `RemoteLogResponseAction()`" },
   { "newRuleAction", true, "DNS rule, DNS action", "return a pair of DNS Rule and DNS Action, to be used with `setRules()`" },
-  { "newServer", true, "{address=\"ip:port\", qps=1000, order=1, weight=10, pool=\"abuse\", retries=5, tcpConnectTimeout=5, tcpSendTimeout=30, tcpRecvTimeout=30, checkName=\"a.root-servers.net.\", checkType=\"A\", maxCheckFailures=1, mustResolve=false, useClientSubnet=true, source=\"address|interface name|address@interface\"", "instantiate a server" },
+  { "newServer", true, "{address=\"ip:port\", qps=1000, order=1, weight=10, pool=\"abuse\", retries=5, tcpConnectTimeout=5, tcpSendTimeout=30, tcpRecvTimeout=30, checkName=\"a.root-servers.net.\", checkType=\"A\", maxCheckFailures=1, mustResolve=false, useClientSubnet=true, source=\"address|interface name|address@interface\"}", "instantiate a server" },
   { "newServerPolicy", true, "name, function", "create a policy object from a Lua function" },
   { "newSuffixMatchNode", true, "", "returns a new SuffixMatchNode" },
   { "NoRecurseAction", true, "", "strip RD bit from the question, let it go through" },
@@ -362,7 +362,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
   { "setECSSourcePrefixV4", true, "prefix-length", "the EDNS Client Subnet prefix-length used for IPv4 queries" },
   { "setECSSourcePrefixV6", true, "prefix-length", "the EDNS Client Subnet prefix-length used for IPv6 queries" },
   { "setKey", true, "key", "set access key to that key" },
-  { "setLocal", true, "netmask, [true], [false], [TCP Fast Open queue size], [interface]", "reset list of addresses we listen on to this address. Second optional parameter sets TCP or not. Third optional parameter sets SO_REUSEPORT when available. Fourth parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. Last one specifies the network interface to use" },
+  { "setLocal", true, "addr [, {doTCP=true, reusePort=false, tcpFastOpenSize=0, interface=\"\"}]", "reset the list of addresses we listen on to this address" },
   { "setMaxTCPClientThreads", true, "n", "set the maximum of TCP client threads, handling TCP connections" },
   { "setMaxTCPConnectionDuration", true, "n", "set the maximum duration of an incoming TCP connection, in seconds. 0 means unlimited" },
   { "setMaxTCPConnectionsPerClient", true, "n", "set the maximum number of TCP connections per client. 0 means unlimited" },
index 67028e84d0cddb5869d51c9a74fb563861016ed1..89ce577f2453abcc18aca500a6024dc82b3175d7 100644 (file)
@@ -177,6 +177,24 @@ std::unordered_map<int, vector<boost::variant<string,double>>> getGenResponses(u
   return ret;
 }
 
+void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface)
+{
+  if (vars) {
+    if (vars->count("doTCP")) {
+      doTCP = boost::get<bool>((*vars)["doTCP"]);
+    }
+    if (vars->count("reusePort")) {
+      reusePort = boost::get<bool>((*vars)["reusePort"]);
+    }
+    if (vars->count("tcpFastOpenQueueSize")) {
+      tcpFastOpenQueueSize = boost::get<int>((*vars)["tcpFastOpenQueueSize"]);
+    }
+    if (vars->count("interface")) {
+      interface = boost::get<std::string>((*vars)["interface"]);
+    }
+  }
+}
+
 vector<std::function<void(void)>> setupLua(bool client, const std::string& config)
 {
   g_launchWork= new vector<std::function<void(void)>>();
@@ -602,7 +620,7 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
       g_ACL.modify([domain](NetmaskGroup& nmg) { nmg.addMask(domain); });
     });
 
-  g_lua.writeFunction("setLocal", [client](const std::string& addr, boost::optional<bool> doTCP, boost::optional<bool> reusePort, boost::optional<int> tcpFastOpenQueueSize, boost::optional<std::string> interface) {
+  g_lua.writeFunction("setLocal", [client](const std::string& addr, boost::optional<localbind_t> vars) {
       setLuaSideEffect();
       if(client)
        return;
@@ -610,17 +628,24 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
         g_outputBuffer="setLocal cannot be used at runtime!\n";
         return;
       }
+      bool doTCP = true;
+      bool reusePort = false;
+      int tcpFastOpenQueueSize = 0;
+      std::string interface;
+
+      parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface);
+
       try {
        ComboAddress loc(addr, 53);
        g_locals.clear();
-       g_locals.push_back(std::make_tuple(loc, doTCP ? *doTCP : true, reusePort ? *reusePort : false, tcpFastOpenQueueSize ? *tcpFastOpenQueueSize : 0, interface ? *interface : "")); /// only works pre-startup, so no sync necessary
+       g_locals.push_back(std::make_tuple(loc, doTCP, reusePort, tcpFastOpenQueueSize, interface)); /// only works pre-startup, so no sync necessary
       }
       catch(std::exception& e) {
        g_outputBuffer="Error: "+string(e.what())+"\n";
       }
     });
 
-  g_lua.writeFunction("addLocal", [client](const std::string& addr, boost::optional<bool> doTCP, boost::optional<bool> reusePort, boost::optional<int> tcpFastOpenQueueSize, boost::optional<std::string> interface) {
+  g_lua.writeFunction("addLocal", [client](const std::string& addr, boost::optional<localbind_t> vars) {
       setLuaSideEffect();
       if(client)
        return;
@@ -628,9 +653,16 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
         g_outputBuffer="addLocal cannot be used at runtime!\n";
         return;
       }
+      bool doTCP = true;
+      bool reusePort = false;
+      int tcpFastOpenQueueSize = 0;
+      std::string interface;
+
+      parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface);
+
       try {
        ComboAddress loc(addr, 53);
-       g_locals.push_back(std::make_tuple(loc, doTCP ? *doTCP : true, reusePort ? *reusePort : false, tcpFastOpenQueueSize ? *tcpFastOpenQueueSize : 0, interface ? *interface : "")); /// only works pre-startup, so no sync necessary
+       g_locals.push_back(std::make_tuple(loc, doTCP, reusePort, tcpFastOpenQueueSize, interface)); /// only works pre-startup, so no sync necessary
       }
       catch(std::exception& e) {
        g_outputBuffer="Error: "+string(e.what())+"\n";
index 5a91e69549a5a3e0a8ec087daa4159631cf66cdd..30a3f9a56e84e7b7ebea803e79b27b5ebd9b894c 100644 (file)
@@ -21,5 +21,8 @@
  */
 #pragma once
 
+typedef std::unordered_map<std::string, boost::variant<bool, int, std::string> > localbind_t;
+void parseLocalBindVars(boost::optional<localbind_t> vars, bool& doTCP, bool& reusePort, int& tcpFastOpenQueueSize, std::string& interface);
+
 typedef boost::variant<string, vector<pair<int, string>>, std::shared_ptr<DNSRule>, DNSName, vector<pair<int, DNSName> > > luadnsrule_t;
 std::shared_ptr<DNSRule> makeRule(const luadnsrule_t& var);
index 37ee13458604838751136626dc72bb2638d1b48d..a07632e8daade1b7ca1e78fd6ef0ee29975e1001 100644 (file)
@@ -512,15 +512,22 @@ void moreLua(bool client)
       }
     });
 
-  g_lua.writeFunction("addDNSCryptBind", [](const std::string& addr, const std::string& providerName, const std::string& certFile, const std::string keyFile, boost::optional<bool> reusePort, boost::optional<int> tcpFastOpenQueueSize, boost::optional<std::string> interface) {
+  g_lua.writeFunction("addDNSCryptBind", [](const std::string& addr, const std::string& providerName, const std::string& certFile, const std::string keyFile, boost::optional<localbind_t> vars) {
       if (g_configurationDone) {
         g_outputBuffer="addDNSCryptBind cannot be used at runtime!\n";
         return;
       }
 #ifdef HAVE_DNSCRYPT
+      bool doTCP = true;
+      bool reusePort = false;
+      int tcpFastOpenQueueSize = 0;
+      std::string interface;
+
+      parseLocalBindVars(vars, doTCP, reusePort, tcpFastOpenQueueSize, interface);
+
       try {
         DnsCryptContext ctx(providerName, certFile, keyFile);
-        g_dnsCryptLocals.push_back(std::make_tuple(ComboAddress(addr, 443), ctx, reusePort ? *reusePort : false, tcpFastOpenQueueSize ? *tcpFastOpenQueueSize : 0, interface ? *interface : ""));
+        g_dnsCryptLocals.push_back(std::make_tuple(ComboAddress(addr, 443), ctx, reusePort, tcpFastOpenQueueSize, interface));
       }
       catch(std::exception& e) {
         errlog(e.what());