From: Remi Gacogne Date: Sat, 25 Jun 2016 14:22:45 +0000 (+0200) Subject: dnsdist: Add server-side TCP Fast Open support X-Git-Tag: rec-4.0.2~48^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e284f319034b50cbbeed6db50769bd97b29ba8a;p=thirdparty%2Fpdns.git dnsdist: Add server-side TCP Fast Open support --- diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index 85e394a051..3370ff255d 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -1142,8 +1142,8 @@ Here are all functions: * member `attachFilter(BPFFilter)`: attach a BPF Filter to this bind * member `toString()`: print the address this bind listens to * Network related: - * `addLocal(netmask, [true], [false])`: add to addresses we listen on. Second optional parameter sets TCP/IP or not. Third optional parameter sets SO_REUSEPORT when available. - * `setLocal(netmask, [true], [false])`: reset list of addresses we listen on to this address. Second optional parameter sets TCP/IP or not. Third optional parameter sets SO_REUSEPORT when available. + * `addLocal(netmask, [true], [false], [TCP Fast Open queue size])`: add to addresses we listen on. Second optional parameter sets TCP/IP or not. Third optional parameter sets SO_REUSEPORT when available. Last parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. + * `setLocal(netmask, [true], [false], [TCP Fast Open queue size])`: reset list of addresses we listen on to this address. Second optional parameter sets TCP/IP or not. Third optional parameter sets SO_REUSEPORT when available. Last parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. * Blocking related: * `addDomainBlock(domain)`: block queries within this domain * Carbon/Graphite/Metronome statistics related: @@ -1366,7 +1366,7 @@ instantiate a server with additional parameters * `setCacheCleaningDelay(n)`: set the interval in seconds between two runs of the cache cleaning algorithm, removing expired entries * `setStaleCacheEntriesTTL(n)`: allows using cache entries expired for at most `n` seconds when no backend available to answer for a query * DNSCrypt related: - * `addDNSCryptBind("127.0.0.1:8443", "provider name", "/path/to/resolver.cert", "/path/to/resolver.key", [false]):` 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 last optional parameter sets SO_REUSEPORT when available + * `addDNSCryptBind("127.0.0.1:8443", "provider name", "/path/to/resolver.cert", "/path/to/resolver.key", [false], [TCP Fast Open queue size]):` 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 last parameter sets the TCP Fast Open queue size, enabling TCP Fast Open when available and the value is larger than 0. * `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` 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 diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index c2c25d90b4..43972283ea 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -482,7 +482,7 @@ vector> 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 doTCP, boost::optional reusePort) { + g_lua.writeFunction("setLocal", [client](const std::string& addr, boost::optional doTCP, boost::optional reusePort, boost::optional tcpFastOpenQueueSize) { setLuaSideEffect(); if(client) return; @@ -493,14 +493,14 @@ vector> setupLua(bool client, const std::string& confi try { ComboAddress loc(addr, 53); g_locals.clear(); - g_locals.push_back(std::make_tuple(loc, doTCP ? *doTCP : true, reusePort ? *reusePort : false)); /// only works pre-startup, so no sync necessary + g_locals.push_back(std::make_tuple(loc, doTCP ? *doTCP : true, reusePort ? *reusePort : false, tcpFastOpenQueueSize ? *tcpFastOpenQueueSize : 0)); /// 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 doTCP, boost::optional reusePort) { + g_lua.writeFunction("addLocal", [client](const std::string& addr, boost::optional doTCP, boost::optional reusePort, boost::optional tcpFastOpenQueueSize) { setLuaSideEffect(); if(client) return; @@ -510,7 +510,7 @@ vector> setupLua(bool client, const std::string& confi } try { ComboAddress loc(addr, 53); - g_locals.push_back(std::make_tuple(loc, doTCP ? *doTCP : true, reusePort ? *reusePort : false)); /// only works pre-startup, so no sync necessary + g_locals.push_back(std::make_tuple(loc, doTCP ? *doTCP : true, reusePort ? *reusePort : false, tcpFastOpenQueueSize ? *tcpFastOpenQueueSize : 0)); /// only works pre-startup, so no sync necessary } catch(std::exception& e) { g_outputBuffer="Error: "+string(e.what())+"\n"; diff --git a/pdns/dnsdist-lua2.cc b/pdns/dnsdist-lua2.cc index bd72fd468a..27a495ae9d 100644 --- a/pdns/dnsdist-lua2.cc +++ b/pdns/dnsdist-lua2.cc @@ -452,7 +452,7 @@ 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 reusePort) { + g_lua.writeFunction("addDNSCryptBind", [](const std::string& addr, const std::string& providerName, const std::string& certFile, const std::string keyFile, boost::optional reusePort, boost::optional tcpFastOpenQueueSize) { if (g_configurationDone) { g_outputBuffer="addDNSCryptBind cannot be used at runtime!\n"; return; @@ -460,7 +460,7 @@ void moreLua(bool client) #ifdef HAVE_DNSCRYPT try { DnsCryptContext ctx(providerName, certFile, keyFile); - g_dnsCryptLocals.push_back(std::make_tuple(ComboAddress(addr, 443), ctx, reusePort ? *reusePort : false)); + g_dnsCryptLocals.push_back(std::make_tuple(ComboAddress(addr, 443), ctx, reusePort ? *reusePort : false, tcpFastOpenQueueSize ? *tcpFastOpenQueueSize : 0)); } catch(std::exception& e) { errlog(e.what()); diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index f3129ea024..7b911fb118 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -73,9 +73,9 @@ bool g_syslog{true}; GlobalStateHolder g_ACL; string g_outputBuffer; -vector> g_locals; +vector> g_locals; #ifdef HAVE_DNSCRYPT -std::vector> g_dnsCryptLocals; +std::vector> g_dnsCryptLocals; #endif #ifdef HAVE_EBPF shared_ptr g_defaultBPFFilter; @@ -1636,11 +1636,11 @@ try if(g_cmdLine.locals.size()) { g_locals.clear(); for(auto loc : g_cmdLine.locals) - g_locals.push_back(std::make_tuple(ComboAddress(loc, 53), true, false)); + g_locals.push_back(std::make_tuple(ComboAddress(loc, 53), true, false, 0)); } if(g_locals.empty()) - g_locals.push_back(std::make_tuple(ComboAddress("127.0.0.1", 53), true, false)); + g_locals.push_back(std::make_tuple(ComboAddress("127.0.0.1", 53), true, false, 0)); g_configurationDone = true; @@ -1699,6 +1699,11 @@ try SSetsockopt(cs->tcpFD, SOL_SOCKET, SO_REUSEADDR, 1); #ifdef TCP_DEFER_ACCEPT SSetsockopt(cs->tcpFD, SOL_TCP,TCP_DEFER_ACCEPT, 1); +#endif +#ifdef TCP_FASTOPEN + if (std::get<3>(local) > 0) { + SSetsockopt(cs->tcpFD, SOL_TCP, TCP_FASTOPEN, std::get<3>(local)); + } #endif if(cs->local.sin4.sin_family == AF_INET6) { SSetsockopt(cs->tcpFD, IPPROTO_IPV6, IPV6_V6ONLY, 1); @@ -1762,6 +1767,11 @@ try #ifdef TCP_DEFER_ACCEPT SSetsockopt(cs->tcpFD, SOL_TCP,TCP_DEFER_ACCEPT, 1); #endif +#ifdef TCP_FASTOPEN + if (std::get<3>(dcLocal) > 0) { + SSetsockopt(cs->tcpFD, SOL_TCP, TCP_FASTOPEN, std::get<3>(dcLocal)); + } +#endif #ifdef SO_REUSEPORT if (std::get<2>(dcLocal)) { SSetsockopt(cs->tcpFD, SOL_SOCKET, SO_REUSEPORT, 1); diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 53f110959e..d754c8e786 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -578,7 +578,7 @@ extern GlobalStateHolder g_ACL; extern ComboAddress g_serverControl; // not changed during runtime -extern std::vector> g_locals; // not changed at runtime (we hope XXX) +extern std::vector> g_locals; // not changed at runtime (we hope XXX) extern vector g_frontends; extern std::string g_key; // in theory needs locking extern bool g_truncateTC; @@ -642,7 +642,7 @@ bool fixUpResponse(char** response, uint16_t* responseLen, size_t* responseSize, void restoreFlags(struct dnsheader* dh, uint16_t origFlags); #ifdef HAVE_DNSCRYPT -extern std::vector> g_dnsCryptLocals; +extern std::vector> g_dnsCryptLocals; int handleDnsCryptQuery(DnsCryptContext* ctx, char* packet, uint16_t len, std::shared_ptr& query, uint16_t* decryptedQueryLen, bool tcp, std::vector& reponse); bool encryptResponse(char* response, uint16_t* responseLen, size_t responseSize, bool tcp, std::shared_ptr dnsCryptQuery);