From: Otto Date: Fri, 22 Jan 2021 11:34:03 +0000 (+0100) Subject: Use separate settings for tcp-fast-open (passive) and tcp-fast-open-connect (active) X-Git-Tag: rec-4.5.0-beta1^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bffc1e7cdef8eef6682934a1ab95e3c07f59bfa5;p=thirdparty%2Fpdns.git Use separate settings for tcp-fast-open (passive) and tcp-fast-open-connect (active) Also warn if things cannot work due to kernel settings and go back to async connect() now that OpenBSD handles that properly. --- diff --git a/pdns/lwres.cc b/pdns/lwres.cc index 465699b478..1d981fede8 100644 --- a/pdns/lwres.cc +++ b/pdns/lwres.cc @@ -327,14 +327,20 @@ LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int Socket s(ip.sin4.sin_family, SOCK_STREAM); s.setNonBlocking(); - ComboAddress local = pdns::getQueryLocalAddress(ip.sin4.sin_family, 0); - if (SyncRes::s_tcp_fast_open > 0) { - s.setFastOpenConnect(); + // v6 tcp does not seem to have fast open + if (ip.sin4.sin_family == AF_INET && SyncRes::s_tcp_fast_open_connect) { + try { + s.setFastOpenConnect(); + } + catch (const NetworkError& e) { + g_log << Logger::Error << "tcp-fast-connect enabled but returned error: " << e.what() << endl; + } } + ComboAddress local = pdns::getQueryLocalAddress(ip.sin4.sin_family, 0); s.bind(local); - s.connect(ip, g_networkTimeoutMsec * 1000); // needed for fastopen EINPROGRESS and better anyway than the system wide connect timeout + s.connect(ip); uint16_t tlen=htons(vpacket.size()); char *lenP=(char*)&tlen; diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 58546cd921..921235a733 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -3222,6 +3222,27 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var) } } +static void checkFastOpenSysctl(bool active) +{ +#ifdef __linux__ + string line; + if (readFileIfThere("/proc/sys/net/ipv4/tcp_fastopen", &line)) { + int flag = std::stoi(line); + if (active && !(flag & 1)) { + g_log << Logger::Error << "tcp-fast-open-connect enabled but net.ipv4.tcp_fastopen does not allow it" << endl; + } + if (!active && !(flag & 2)) { + g_log << Logger::Error << "tcp-fast-open enabled but net.ipv4.tcp_fastopen does not allow it" << endl; + } + } + else { + g_log << Logger::Error << "Cannot determine if kernel setting allow fast-open" << endl; + } +#else + g_log << Logger::Error << "Cannot determine if kernel setting allow fast-open" << endl; +#endif +} + static void makeTCPServerSockets(deferredAdd_t& deferredAdds, std::set& tcpSockets) { int fd; @@ -3291,6 +3312,7 @@ static void makeTCPServerSockets(deferredAdd_t& deferredAdds, std::set& tcp } if (SyncRes::s_tcp_fast_open > 0) { + checkFastOpenSysctl(false); #ifdef TCP_FASTOPEN if (setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN, &SyncRes::s_tcp_fast_open, sizeof SyncRes::s_tcp_fast_open) < 0) { int err = errno; @@ -4670,8 +4692,13 @@ static int serviceMain(int argc, char*argv[]) SyncRes::s_maxdepth=::arg().asNum("max-recursion-depth"); SyncRes::s_rootNXTrust = ::arg().mustDo( "root-nx-trust"); SyncRes::s_refresh_ttlperc = ::arg().asNum("refresh-on-ttl-perc"); - SyncRes::s_tcp_fast_open = ::arg().asNum("tcp-fast-open"); RecursorPacketCache::s_refresh_ttlperc = SyncRes::s_refresh_ttlperc; + SyncRes::s_tcp_fast_open = ::arg().asNum("tcp-fast-open"); + SyncRes::s_tcp_fast_open_connect = ::arg().mustDo("tcp-fast-open-connect"); + + if (SyncRes::s_tcp_fast_open_connect) { + checkFastOpenSysctl(true); + } if(SyncRes::s_serverID.empty()) { SyncRes::s_serverID = myHostname; @@ -5554,6 +5581,7 @@ int main(int argc, char **argv) ::arg().set("stats-snmp-disabled-list", "List of statistics that are prevented from being exported via SNMP")=defaultBlacklistedStats; ::arg().set("tcp-fast-open", "Enable TCP Fast Open support on the listening sockets, using the supplied numerical value as the queue size")="0"; + ::arg().set("tcp-fast-open-connect", "Enable TCP Fast Open support on outgoing sockets")="no"; ::arg().set("nsec3-max-iterations", "Maximum number of iterations allowed for an NSEC3 record")="2500"; ::arg().set("cpu-map", "Thread to CPU mapping, space separated thread-id=cpu1,cpu2..cpuN pairs")=""; diff --git a/pdns/syncres.cc b/pdns/syncres.cc index 08619eed24..6170cdac1f 100644 --- a/pdns/syncres.cc +++ b/pdns/syncres.cc @@ -99,6 +99,7 @@ bool SyncRes::s_qnameminimization; SyncRes::HardenNXD SyncRes::s_hardenNXD; unsigned int SyncRes::s_refresh_ttlperc; int SyncRes::s_tcp_fast_open; +bool SyncRes::s_tcp_fast_open_connect; #define LOG(x) if(d_lm == Log) { g_log < d_discardedPolicies; DNSFilterEngine::Policy d_appliedPolicy;