From: Y7n05h Date: Sun, 3 Apr 2022 04:05:51 +0000 (+0800) Subject: dnsdist: Add setTCPFastOpenKey() X-Git-Tag: rec-4.7.0-beta1~14^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=be5e1fca0aca624e2cec9a723bd3b2764ff5b33b;p=thirdparty%2Fpdns.git dnsdist: Add setTCPFastOpenKey() Signed-off-by: Y7n05h --- diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index 5d66c21bcf..3a3073e3db 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -685,6 +685,7 @@ const std::vector g_consoleKeywords{ { "setStaleCacheEntriesTTL", true, "n", "allows using cache entries expired for at most n seconds when there is no backend available to answer for a query" }, { "setSyslogFacility", true, "facility", "set the syslog logging facility to 'facility'. Defaults to LOG_DAEMON" }, { "setTCPDownstreamCleanupInterval", true, "interval", "minimum interval in seconds between two cleanups of the idle TCP downstream connections" }, + { "setTCPFastOpenKey", true, "string", "TCP Fast Open Key" }, { "setTCPDownstreamMaxIdleTime", true, "time", "Maximum time in seconds that a downstream TCP connection to a backend might stay idle" }, { "setTCPInternalPipeBufferSize", true, "size", "Set the size in bytes of the internal buffer of the pipes used internally to distribute connections to TCP (and DoT) workers threads" }, { "setTCPRecvTimeout", true, "n", "set the read timeout on TCP connections from the client, in seconds" }, diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index d7458a2c5b..1ea0da2d68 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -30,6 +30,7 @@ #include #include #include +#include #include "dnsdist.hh" #include "dnsdist-carbon.hh" @@ -1987,6 +1988,19 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) }); luaCtx.writeFunction("setTCPInternalPipeBufferSize", [](uint64_t size) { g_tcpInternalPipeBufferSize = size; }); + luaCtx.writeFunction("setTCPFastOpenKey", [](const std::string& keyString) { + setLuaSideEffect(); + unsigned int key[4] = {}; + auto ret = sscanf(keyString.c_str(), "%x-%x-%x-%x", &key[0], &key[1], &key[2], &key[3]); + if (ret != 4) { + g_outputBuffer = "Invalid value passed to setTCPFastOpenKey()!\n"; + return; + } + extern vector g_TCPFastOpenKey; + for (const auto i : key) { + g_TCPFastOpenKey.push_back(i); + } + }); #ifdef HAVE_NET_SNMP luaCtx.writeFunction("snmpAgent", [client, configCheck](bool enableTraps, boost::optional daemonSocket) { diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index e1036faa03..bf98eb1286 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -111,7 +111,7 @@ std::vector > g_dynBPFFilters; std::vector> g_frontends; GlobalStateHolder g_pools; size_t g_udpVectorSize{1}; - +std::vector g_TCPFastOpenKey; /* 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. We send directly to those sockets. @@ -1983,6 +1983,11 @@ static void setUpLocalBind(std::unique_ptr& cs) if (cs->fastOpenQueueSize > 0) { #ifdef TCP_FASTOPEN SSetsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, cs->fastOpenQueueSize); + if (!g_TCPFastOpenKey.empty()) { + auto res = setsockopt(fd, IPPROTO_IP, TCP_FASTOPEN_KEY, g_TCPFastOpenKey.data(), g_TCPFastOpenKey.size() * sizeof(g_TCPFastOpenKey[0])); + if (res == -1) + throw runtime_error("setsockopt for level IPPROTO_TCP and opname TCP_FASTOPEN_KEY failed: " + stringerror()); + } #else if (warn) { warnlog("TCP Fast Open has been configured on local address '%s' but is not supported", cs->local.toStringWithPort());