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;
}
}
+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<int>& tcpSockets)
{
int fd;
}
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;
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;
::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")="";