From: Remi Gacogne Date: Fri, 4 Feb 2022 14:27:19 +0000 (+0100) Subject: dnsdist: Separate config from running members in DownstreamState X-Git-Tag: rec-4.7.0-alpha1~9^2~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8cf75ac21dde5fc1c8cd2af50951651f3058a5f3;p=thirdparty%2Fpdns.git dnsdist: Separate config from running members in DownstreamState --- diff --git a/pdns/dnsdist-carbon.cc b/pdns/dnsdist-carbon.cc index cb0bc5fdf4..cdad9dd69a 100644 --- a/pdns/dnsdist-carbon.cc +++ b/pdns/dnsdist-carbon.cc @@ -83,13 +83,13 @@ void carbonDumpThread() } auto states = g_dstates.getLocal(); for(const auto& state : *states) { - string serverName = state->getName().empty() ? state->remote.toStringWithPort() : state->getName(); + string serverName = state->getName().empty() ? state->d_config.remote.toStringWithPort() : state->getName(); boost::replace_all(serverName, ".", "_"); const string base = namespace_name + "." + hostname + "." + instance_name + ".servers." + serverName + "."; str<queries.load() << " " << now << "\r\n"; str<responses.load() << " " << now << "\r\n"; str<reuseds.load() << " " << now << "\r\n"; - str<availability != DownstreamState::Availability::Down ? state->latencyUsec/1000.0 : 0) << " " << now << "\r\n"; + str<d_config.availability != DownstreamState::Availability::Down ? state->latencyUsec/1000.0 : 0) << " " << now << "\r\n"; str<sendErrors.load() << " " << now << "\r\n"; str<outstanding.load() << " " << now << "\r\n"; str<tcpDiedSendingQuery.load() << " " << now << "\r\n"; diff --git a/pdns/dnsdist-lua-bindings.cc b/pdns/dnsdist-lua-bindings.cc index c5b66c6d18..123e3a73ff 100644 --- a/pdns/dnsdist-lua-bindings.cc +++ b/pdns/dnsdist-lua-bindings.cc @@ -105,13 +105,13 @@ void setupLuaBindings(LuaContext& luaCtx, bool client) auto localPools = g_pools.getCopy(); addServerToPool(localPools, pool, s); g_pools.setState(localPools); - s->pools.insert(pool); + s->d_config.pools.insert(pool); }); luaCtx.registerFunction::*)(string)>("rmPool", [](std::shared_ptr s, string pool) { auto localPools = g_pools.getCopy(); removeServerFromPool(localPools, pool, s); g_pools.setState(localPools); - s->pools.erase(pool); + s->d_config.pools.erase(pool); }); luaCtx.registerFunction("getOutstanding", [](const DownstreamState& s) { return s.outstanding.load(); }); luaCtx.registerFunction("getDrops", [](const DownstreamState& s) { return s.reuseds.load(); }); @@ -129,12 +129,15 @@ void setupLuaBindings(LuaContext& luaCtx, bool client) luaCtx.registerFunction("getNameWithAddr", [](const DownstreamState& s) { return s.getNameWithAddr(); }); luaCtx.registerMember("upStatus", &DownstreamState::upStatus); luaCtx.registerMember("weight", - [](const DownstreamState& s) -> int {return s.weight;}, - [](DownstreamState& s, int newWeight) {s.setWeight(newWeight);} + [](const DownstreamState& s) -> int {return s.d_config.d_weight;}, + [](DownstreamState& s, int newWeight) { s.setWeight(newWeight); } + ); + luaCtx.registerMember("order", + [](const DownstreamState& s) -> int {return s.d_config.order; }, + [](DownstreamState& s, int newOrder) { s.d_config.order = newOrder; } ); - luaCtx.registerMember("order", &DownstreamState::order); luaCtx.registerMember("name", [](const DownstreamState& backend) -> const std::string { return backend.getName(); }, [](DownstreamState& backend, const std::string& newName) { backend.setName(newName); }); - luaCtx.registerFunction("getID", [](const DownstreamState& s) { return boost::uuids::to_string(s.id); }); + luaCtx.registerFunction("getID", [](const DownstreamState& s) { return boost::uuids::to_string(*s.d_config.id); }); #endif /* DISABLE_DOWNSTREAM_BINDINGS */ #ifndef DISABLE_DNSHEADER_BINDINGS diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index c81ea6a147..94d2381f92 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -627,7 +627,7 @@ void setupLuaInspection(LuaContext& luaCtx) auto states = g_dstates.getLocal(); counter = 0; for(const auto& s : *states) { - ret << (fmt % counter % s->getName() % s->remote.toStringWithPort() % s->tcpCurrentConnections % s->tcpMaxConcurrentConnections % s->tcpDiedSendingQuery % s->tcpDiedReadingResponse % s->tcpGaveUp % s->tcpReadTimeouts % s->tcpWriteTimeouts % s->tcpConnectTimeouts % s->tcpNewConnections % s->tcpReusedConnections % s->tlsResumptions % s->tcpAvgQueriesPerConnection % s->tcpAvgConnectionDuration) << endl; + ret << (fmt % counter % s->getName() % s->d_config.remote.toStringWithPort() % s->tcpCurrentConnections % s->tcpMaxConcurrentConnections % s->tcpDiedSendingQuery % s->tcpDiedReadingResponse % s->tcpGaveUp % s->tcpReadTimeouts % s->tcpWriteTimeouts % s->tcpConnectTimeouts % s->tcpNewConnections % s->tcpReusedConnections % s->tlsResumptions % s->tcpAvgQueriesPerConnection % s->tcpAvgConnectionDuration) << endl; ++counter; } diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 24cfe202b0..755e146e66 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -346,11 +346,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) return std::shared_ptr(); } - ComboAddress sourceAddr; - std::string sourceItfName; - unsigned int sourceItf = 0; - size_t numberOfSockets = 1; - std::set cpus; + DownstreamState::Config config; if (vars.count("source")) { /* handle source in the following forms: @@ -366,7 +362,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) if (pos == std::string::npos) { /* no '@', try to parse that as a valid v4/v6 address */ try { - sourceAddr = ComboAddress(source); + config.sourceAddr = ComboAddress(source); parsed = true; } catch (...) { @@ -375,18 +371,18 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) if (parsed == false) { /* try to parse as interface name, or v4/v6@itf */ - sourceItfName = source.substr(pos == std::string::npos ? 0 : pos + 1); - unsigned int itfIdx = if_nametoindex(sourceItfName.c_str()); + config.sourceItfName = source.substr(pos == std::string::npos ? 0 : pos + 1); + unsigned int itfIdx = if_nametoindex(config.sourceItfName.c_str()); if (itfIdx != 0) { if (pos == 0 || pos == std::string::npos) { /* "eth0" or "@eth0" */ - sourceItf = itfIdx; + config.sourceItf = itfIdx; } else { /* "192.0.2.1@eth0" */ - sourceAddr = ComboAddress(source.substr(0, pos)); - sourceItf = itfIdx; + config.sourceAddr = ComboAddress(source.substr(0, pos)); + config.sourceItf = itfIdx; } #ifdef SO_BINDTODEVICE /* we need to retain CAP_NET_RAW to be able to set SO_BINDTODEVICE in the health checks */ @@ -394,77 +390,68 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) #endif } else { - warnlog("Dismissing source %s because '%s' is not a valid interface name", source, sourceItfName); + warnlog("Dismissing source %s because '%s' is not a valid interface name", source, config.sourceItfName); } } } if (vars.count("sockets")) { - numberOfSockets = std::stoul(boost::get(vars["sockets"])); - if (numberOfSockets == 0) { + config.d_numberOfSockets = std::stoul(boost::get(vars["sockets"])); + if (config.d_numberOfSockets == 0) { warnlog("Dismissing invalid number of sockets '%s', using 1 instead", boost::get(vars["sockets"])); - numberOfSockets = 1; + config.d_numberOfSockets = 1; } } - // create but don't connect the socket in client or check-config modes - auto ret = std::make_shared(serverAddr, sourceAddr, sourceItf, sourceItfName); - if (!(client || configCheck)) { - infolog("Added downstream server %s", serverAddr.toStringWithPort()); - } - if (vars.count("qps")) { - int qpsVal = std::stoi(boost::get(vars["qps"])); - ret->qps = QPSLimiter(qpsVal, qpsVal); + config.d_qpsLimit = std::stoi(boost::get(vars["qps"])); } if (vars.count("order")) { - ret->order = std::stoi(boost::get(vars["order"])); + config.order = std::stoi(boost::get(vars["order"])); } if (vars.count("weight")) { try { - int weightVal = std::stoi(boost::get(vars["weight"])); + config.d_weight = std::stoi(boost::get(vars["weight"])); - if (weightVal < 1) { + if (config.d_weight < 1) { errlog("Error creating new server: downstream weight value must be greater than 0."); - return ret; + return std::shared_ptr(); } - - ret->setWeight(weightVal); } catch (const std::exception& e) { // std::stoi will throw an exception if the string isn't in a value int range errlog("Error creating new server: downstream weight value must be between %s and %s", 1, std::numeric_limits::max()); - return ret; + return std::shared_ptr(); } } if (vars.count("retries")) { - ret->d_retries = std::stoi(boost::get(vars["retries"])); + config.d_retries = std::stoi(boost::get(vars["retries"])); } if (vars.count("checkInterval")) { - ret->checkInterval = static_cast(std::stoul(boost::get(vars["checkInterval"]))); + config.checkInterval = static_cast(std::stoul(boost::get(vars["checkInterval"]))); } if (vars.count("tcpConnectTimeout")) { - ret->tcpConnectTimeout = std::stoi(boost::get(vars["tcpConnectTimeout"])); + config.tcpConnectTimeout = std::stoi(boost::get(vars["tcpConnectTimeout"])); } if (vars.count("tcpSendTimeout")) { - ret->tcpSendTimeout = std::stoi(boost::get(vars["tcpSendTimeout"])); + config.tcpSendTimeout = std::stoi(boost::get(vars["tcpSendTimeout"])); } if (vars.count("tcpRecvTimeout")) { - ret->tcpRecvTimeout = std::stoi(boost::get(vars["tcpRecvTimeout"])); + config.tcpRecvTimeout = std::stoi(boost::get(vars["tcpRecvTimeout"])); } if (vars.count("tcpFastOpen")) { bool fastOpen = boost::get(vars["tcpFastOpen"]); if (fastOpen) { #ifdef MSG_FASTOPEN - ret->tcpFastOpen = true; + config.tcpFastOpen = true; #else warnlog("TCP Fast Open has been configured on downstream server %s but is not supported", boost::get(vars["address"])); #endif @@ -472,91 +459,92 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } if (vars.count("maxInFlight")) { - ret->d_maxInFlightQueriesPerConn = std::stoi(boost::get(vars["maxInFlight"])); + config.d_maxInFlightQueriesPerConn = std::stoi(boost::get(vars["maxInFlight"])); } if (vars.count("name")) { - ret->setName(boost::get(vars["name"])); + config.name = boost::get(vars["name"]); } if (vars.count("id")) { - ret->setId(boost::uuids::string_generator()(boost::get(vars["id"]))); + config.id = boost::uuids::string_generator()(boost::get(vars["id"])); } if (vars.count("checkName")) { - ret->checkName = DNSName(boost::get(vars["checkName"])); + config.checkName = DNSName(boost::get(vars["checkName"])); } if (vars.count("checkType")) { - ret->checkType = boost::get(vars["checkType"]); + config.checkType = boost::get(vars["checkType"]); } if (vars.count("checkClass")) { - ret->checkClass = std::stoi(boost::get(vars["checkClass"])); + config.checkClass = std::stoi(boost::get(vars["checkClass"])); } if (vars.count("checkFunction")) { - ret->checkFunction = boost::get(vars["checkFunction"]); + config.checkFunction = boost::get(vars["checkFunction"]); } if (vars.count("checkTimeout")) { - ret->checkTimeout = std::stoi(boost::get(vars["checkTimeout"])); + config.checkTimeout = std::stoi(boost::get(vars["checkTimeout"])); } if (vars.count("checkTCP")) { - ret->d_tcpCheck = boost::get(vars.at("checkTCP")); + config.d_tcpCheck = boost::get(vars.at("checkTCP")); } if (vars.count("setCD")) { - ret->setCD = boost::get(vars["setCD"]); + config.setCD = boost::get(vars["setCD"]); } if (vars.count("mustResolve")) { - ret->mustResolve = boost::get(vars["mustResolve"]); + config.mustResolve = boost::get(vars["mustResolve"]); } if (vars.count("useClientSubnet")) { - ret->useECS = boost::get(vars["useClientSubnet"]); + config.useECS = boost::get(vars["useClientSubnet"]); } if (vars.count("useProxyProtocol")) { - ret->useProxyProtocol = boost::get(vars["useProxyProtocol"]); + config.useProxyProtocol = boost::get(vars["useProxyProtocol"]); } if (vars.count("disableZeroScope")) { - ret->disableZeroScope = boost::get(vars["disableZeroScope"]); + config.disableZeroScope = boost::get(vars["disableZeroScope"]); } if (vars.count("ipBindAddrNoPort")) { - ret->ipBindAddrNoPort = boost::get(vars["ipBindAddrNoPort"]); + config.ipBindAddrNoPort = boost::get(vars["ipBindAddrNoPort"]); } if (vars.count("addXPF")) { - ret->xpfRRCode = std::stoi(boost::get(vars["addXPF"])); + config.xpfRRCode = std::stoi(boost::get(vars["addXPF"])); } if (vars.count("maxCheckFailures")) { - ret->maxCheckFailures = std::stoi(boost::get(vars["maxCheckFailures"])); + config.maxCheckFailures = std::stoi(boost::get(vars["maxCheckFailures"])); } if (vars.count("rise")) { - ret->minRiseSuccesses = std::stoi(boost::get(vars["rise"])); + config.minRiseSuccesses = std::stoi(boost::get(vars["rise"])); } if (vars.count("reconnectOnUp")) { - ret->reconnectOnUp = boost::get(vars["reconnectOnUp"]); + config.reconnectOnUp = boost::get(vars["reconnectOnUp"]); } if (vars.count("cpus")) { for (const auto& cpu : boost::get>>(vars["cpus"])) { - cpus.insert(std::stoi(cpu.second)); + config.d_cpus.insert(std::stoi(cpu.second)); } } if (vars.count("tcpOnly")) { - ret->d_tcpOnly = boost::get(vars.at("tcpOnly")); + config.d_tcpOnly = boost::get(vars.at("tcpOnly")); } + std::shared_ptr tlsCtx; if (vars.count("tls")) { TLSContextParameters tlsParams; std::string ciphers; @@ -583,58 +571,47 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) tlsParams.d_enableRenegotiation = boost::get(vars.at("enableRenegotiation")); } if (vars.count("subjectName")) { - ret->d_tlsSubjectName = boost::get(vars.at("subjectName")); + config.d_tlsSubjectName = boost::get(vars.at("subjectName")); } - ret->d_tlsCtx = getTLSContext(tlsParams); + tlsCtx = getTLSContext(tlsParams); if (vars.count("dohPath")) { #ifdef HAVE_NGHTTP2 - ret->d_dohPath = boost::get(vars.at("dohPath")); - if (ret->d_tlsCtx) { - setupDoHClientProtocolNegotiation(ret->d_tlsCtx); - } - - if (g_configurationDone && g_outgoingDoHWorkerThreads && *g_outgoingDoHWorkerThreads == 0) { - throw std::runtime_error("Error: setOutgoingDoHWorkerThreads() is set to 0 so no outgoing DoH worker thread is available to serve queries"); - } - - if (!g_outgoingDoHWorkerThreads || *g_outgoingDoHWorkerThreads == 0) { - g_outgoingDoHWorkerThreads = 1; - } + config.d_dohPath = boost::get(vars.at("dohPath")); if (vars.count("addXForwardedHeaders")) { - ret->d_addXForwardedHeaders = boost::get(vars.at("addXForwardedHeaders")); + config.d_addXForwardedHeaders = boost::get(vars.at("addXForwardedHeaders")); } #else /* HAVE_NGHTTP2 */ - throw std::runtime_error("Outgoing DNS over HTTPS support requested (via 'dohPath' on newServer()) but nghttp2 support is not available"); + throw std::runtime_error("Outgoing DNS over HTTPS support requested (via 'dohPath' on newServer()) but nghttp2 support is not available"); #endif /* HAVE_NGHTTP2 */ } - else { - setupDoTProtocolNegotiation(ret->d_tlsCtx); - } } - if (!ret->isTCPOnly() && !(client || configCheck)) { - if (!IsAnyAddress(ret->remote)) { - ret->connectUDPSockets(numberOfSockets); - } - } - - /* this needs to be done _AFTER_ the order has been set, - since the server are kept ordered inside the pool */ - auto localPools = g_pools.getCopy(); if (vars.count("pool")) { if (auto* pool = boost::get(&vars["pool"])) { - ret->pools.insert(*pool); + config.pools.insert(*pool); } else { auto pools = boost::get>>(vars["pool"]); for (auto& p : pools) { - ret->pools.insert(p.second); + config.pools.insert(p.second); } } - for (const auto& poolName : ret->pools) { + } + + // create but don't connect the socket in client or check-config modes + auto ret = std::make_shared(std::move(config), std::move(tlsCtx), !(client || configCheck)); + if (!(client || configCheck)) { + infolog("Added downstream server %s", serverAddr.toStringWithPort()); + } + + /* this needs to be done _AFTER_ the order has been set, + since the server are kept ordered inside the pool */ + auto localPools = g_pools.getCopy(); + if (!ret->d_config.pools.empty()) { + for (const auto& poolName : ret->d_config.pools) { addServerToPool(localPools, poolName, ret); } } @@ -644,28 +621,20 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) g_pools.setState(localPools); if (ret->connected) { - ret->threadStarted.test_and_set(); - if (g_launchWork) { - g_launchWork->push_back([ret, cpus]() { - ret->tid = thread(responderThread, ret); - if (!cpus.empty()) { - mapThreadToCPUList(ret->tid.native_handle(), cpus); - } + g_launchWork->push_back([&ret]() { + ret->start(); }); } else { - ret->tid = thread(responderThread, ret); - if (!cpus.empty()) { - mapThreadToCPUList(ret->tid.native_handle(), cpus); - } + ret->start(); } } auto states = g_dstates.getCopy(); states.push_back(ret); std::stable_sort(states.begin(), states.end(), [](const decltype(ret)& a, const decltype(ret)& b) { - return a->order < b->order; + return a->d_config.order < b->d_config.order; }); g_dstates.setState(states); return ret; @@ -682,7 +651,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) else if (auto str = boost::get(&var)) { const auto uuid = getUniqueID(*str); for (auto& state : states) { - if (state->id == uuid) { + if (*state->d_config.id == uuid) { server = state; } } @@ -695,7 +664,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) throw std::runtime_error("unable to locate the requested server"); } auto localPools = g_pools.getCopy(); - for (const string& poolName : server->pools) { + for (const string& poolName : server->d_config.pools) { removeServerFromPool(localPools, poolName, server); } /* the server might also be in the default pool */ @@ -902,16 +871,17 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) for (const auto& s : *states) { string status = s->getStatus(); string pools; - for (auto& p : s->pools) { - if (!pools.empty()) + for (const auto& p : s->d_config.pools) { + if (!pools.empty()) { pools += " "; + } pools += p; } if (showUUIDs) { - ret << (fmt % counter % s->getName() % s->remote.toStringWithPort() % status % s->queryLoad % s->qps.getRate() % s->order % s->weight % s->queries.load() % s->reuseds.load() % (s->dropRate) % (s->latencyUsec / 1000.0) % s->outstanding.load() % pools % s->id) << endl; + ret << (fmt % counter % s->getName() % s->d_config.remote.toStringWithPort() % status % s->queryLoad % s->qps.getRate() % s->d_config.order % s->d_config.d_weight % s->queries.load() % s->reuseds.load() % (s->dropRate) % (s->latencyUsec / 1000.0) % s->outstanding.load() % pools % *s->d_config.id) << endl; } else { - ret << (fmt % counter % s->getName() % s->remote.toStringWithPort() % status % s->queryLoad % s->qps.getRate() % s->order % s->weight % s->queries.load() % s->reuseds.load() % (s->dropRate) % (s->latencyUsec / 1000.0) % s->outstanding.load() % pools) << endl; + ret << (fmt % counter % s->getName() % s->d_config.remote.toStringWithPort() % status % s->queryLoad % s->qps.getRate() % s->d_config.order % s->d_config.d_weight % s->queries.load() % s->reuseds.load() % (s->dropRate) % (s->latencyUsec / 1000.0) % s->outstanding.load() % pools) << endl; } totQPS += s->queryLoad; totQueries += s->queries.load(); @@ -960,7 +930,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) if (auto str = boost::get(&i)) { const auto uuid = getUniqueID(*str); for (auto& state : states) { - if (state->id == uuid) { + if (*state->d_config.id == uuid) { return state; } } @@ -1671,7 +1641,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) servers += server.second->getName(); servers += " "; } - servers += server.second->remote.toStringWithPort(); + servers += server.second->d_config.remote.toStringWithPort(); } ret << (fmt % name % cache % policy % servers) << endl; diff --git a/pdns/dnsdist-snmp.cc b/pdns/dnsdist-snmp.cc index 4da43eed86..1f102e2408 100644 --- a/pdns/dnsdist-snmp.cc +++ b/pdns/dnsdist-snmp.cc @@ -307,7 +307,7 @@ static int backendStatTable_handler(netsnmp_mib_handler* handler, break; case COLUMN_BACKENDWEIGHT: DNSDistSNMPAgent::setCounter64Value(request, - server->weight); + server->d_config.d_weight); break; case COLUMN_BACKENDOUTSTANDING: DNSDistSNMPAgent::setCounter64Value(request, @@ -331,7 +331,7 @@ static int backendStatTable_handler(netsnmp_mib_handler* handler, } case COLUMN_BACKENDADDRESS: { - std::string addr(server->remote.toStringWithPort()); + std::string addr(server->d_config.remote.toStringWithPort()); snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, addr.c_str(), @@ -341,10 +341,11 @@ static int backendStatTable_handler(netsnmp_mib_handler* handler, case COLUMN_BACKENDPOOLS: { std::string pools; - for(auto& p : server->pools) { - if(!pools.empty()) + for (const auto& p : server->d_config.pools) { + if (!pools.empty()) { pools+=" "; - pools+=p; + } + pools += p; } snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, @@ -359,7 +360,7 @@ static int backendStatTable_handler(netsnmp_mib_handler* handler, DNSDistSNMPAgent::setCounter64Value(request, server->queries.load()); break; case COLUMN_BACKENDORDER: - DNSDistSNMPAgent::setCounter64Value(request, server->order); + DNSDistSNMPAgent::setCounter64Value(request, server->d_config.order); break; default: netsnmp_set_request_error(reqinfo, @@ -377,7 +378,7 @@ static int backendStatTable_handler(netsnmp_mib_handler* handler, bool DNSDistSNMPAgent::sendBackendStatusChangeTrap(const std::shared_ptr& dss) { #ifdef HAVE_NET_SNMP - const string backendAddress = dss->remote.toStringWithPort(); + const string backendAddress = dss->d_config.remote.toStringWithPort(); const string backendStatus = dss->getStatus(); netsnmp_variable_list* varList = nullptr; diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 330076d27a..2d5d024cb9 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -118,7 +118,7 @@ std::shared_ptr IncomingTCPConnectionState::getDownstrea if (!downstream) { /* we don't have a connection to this backend owned yet, let's get one (it might not be a fresh one, though) */ downstream = t_downstreamTCPConnectionsManager.getConnectionToDownstream(d_threadData.mplexer, ds, now, std::string()); - if (ds->useProxyProtocol) { + if (ds->d_config.useProxyProtocol) { registerOwnedDownstreamConnection(downstream); } } @@ -254,9 +254,9 @@ static void handleResponseSent(std::shared_ptr& stat const auto& ds = currentResponse.d_connection->getDS(); const auto& ids = currentResponse.d_idstate; double udiff = ids.sentTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (%s, %d bytes), took %f usec", ds->remote.toStringWithPort(), ids.origRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), currentResponse.d_buffer.size(), udiff); + vinfolog("Got answer from %s, relayed to %s (%s, %d bytes), took %f usec", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), currentResponse.d_buffer.size(), udiff); - ::handleResponseSent(ids, udiff, state->d_ci.remote, ds->remote, static_cast(currentResponse.d_buffer.size()), currentResponse.d_cleartextDH, ds->getProtocol()); + ::handleResponseSent(ids, udiff, state->d_ci.remote, ds->d_config.remote, static_cast(currentResponse.d_buffer.size()), currentResponse.d_cleartextDH, ds->getProtocol()); updateTCPLatency(ds, udiff); } @@ -489,7 +489,7 @@ void IncomingTCPConnectionState::handleResponse(const struct timeval& now, TCPRe { std::shared_ptr state = shared_from_this(); - if (response.d_connection && response.d_connection->getDS() && response.d_connection->getDS()->useProxyProtocol) { + if (response.d_connection && response.d_connection->getDS() && response.d_connection->getDS()->d_config.useProxyProtocol) { // if we have added a TCP Proxy Protocol payload to a connection, don't release it to the general pool as no one else will be able to use it anyway if (!response.d_connection->willBeReusable(true)) { // if it can't be reused even by us, well @@ -770,7 +770,7 @@ static void handleQuery(std::shared_ptr& state, cons /* we need to do this _before_ creating the cross protocol query because after that the buffer will have been moved */ - if (ds->useProxyProtocol) { + if (ds->d_config.useProxyProtocol) { proxyProtocolPayload = getProxyProtocolPayload(dq); } @@ -786,7 +786,7 @@ static void handleQuery(std::shared_ptr& state, cons auto downstreamConnection = state->getDownstreamConnection(ds, dq.proxyProtocolValues, now); - if (ds->useProxyProtocol) { + if (ds->d_config.useProxyProtocol) { /* if we ever sent a TLV over a connection, we can never go back */ if (!state->d_proxyProtocolPayloadHasTLV) { state->d_proxyProtocolPayloadHasTLV = dq.proxyProtocolValues && !dq.proxyProtocolValues->empty(); diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index 6e9afc9f2a..7398cf019d 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -536,15 +536,17 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) for (const auto& state : *states) { string serverName; - if (state->getName().empty()) - serverName = state->remote.toStringWithPort(); - else + if (state->getName().empty()) { + serverName = state->d_config.remote.toStringWithPort(); + } + else { serverName = state->getName(); + } boost::replace_all(serverName, ".", "_"); const std::string label = boost::str(boost::format("{server=\"%1%\",address=\"%2%\"}") - % serverName % state->remote.toStringWithPort()); + % serverName % state->d_config.remote.toStringWithPort()); output << statesbase << "status" << label << " " << (state->isUp() ? "1" : "0") << "\n"; output << statesbase << "queries" << label << " " << state->queries.load() << "\n"; @@ -554,8 +556,8 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) output << statesbase << "latency" << label << " " << state->latencyUsec/1000.0 << "\n"; output << statesbase << "senderrors" << label << " " << state->sendErrors.load() << "\n"; output << statesbase << "outstanding" << label << " " << state->outstanding.load() << "\n"; - output << statesbase << "order" << label << " " << state->order << "\n"; - output << statesbase << "weight" << label << " " << state->weight << "\n"; + output << statesbase << "order" << label << " " << state->d_config.order << "\n"; + output << statesbase << "weight" << label << " " << state->d_config.d_weight << "\n"; output << statesbase << "tcpdiedsendingquery" << label << " " << state->tcpDiedSendingQuery << "\n"; output << statesbase << "tcpdiedreadingresponse" << label << " " << state->tcpDiedReadingResponse << "\n"; output << statesbase << "tcpgaveup" << label << " " << state->tcpGaveUp << "\n"; @@ -922,10 +924,10 @@ static void handleJSONStats(const YaHTTP::Request& req, YaHTTP::Response& resp) static void addServerToJSON(Json::array& servers, int id, const std::shared_ptr& a) { string status; - if (a->availability == DownstreamState::Availability::Up) { + if (a->d_config.availability == DownstreamState::Availability::Up) { status = "UP"; } - else if (a->availability == DownstreamState::Availability::Down) { + else if (a->d_config.availability == DownstreamState::Availability::Down) { status = "DOWN"; } else { @@ -933,21 +935,21 @@ static void addServerToJSON(Json::array& servers, int id, const std::shared_ptr< } Json::array pools; - for(const auto& p: a->pools) { + for (const auto& p: a->d_config.pools) { pools.push_back(p); } Json::object server { {"id", id}, {"name", a->getName()}, - {"address", a->remote.toStringWithPort()}, + {"address", a->d_config.remote.toStringWithPort()}, {"state", status}, {"qps", (double)a->queryLoad}, {"qpsLimit", (double)a->qps.getRate()}, {"outstanding", (double)a->outstanding}, {"reuseds", (double)a->reuseds}, - {"weight", (double)a->weight}, - {"order", (double)a->order}, + {"weight", (double)a->d_config.d_weight}, + {"order", (double)a->d_config.order}, {"pools", pools}, {"latency", (double)(a->latencyUsec/1000.0)}, {"queries", (double)a->queries}, @@ -970,7 +972,7 @@ static void addServerToJSON(Json::array& servers, int id, const std::shared_ptr< }; /* sending a latency for a DOWN server doesn't make sense */ - if (a->availability == DownstreamState::Availability::Down) { + if (a->d_config.availability == DownstreamState::Availability::Down) { server["latency"] = nullptr; } diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 813ec9fd03..5aa8bc81c7 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -623,7 +623,7 @@ void responderThread(std::shared_ptr dss) int origFD = ids->origFD; unsigned int qnameWireLength = 0; - if (fd != ids->backendFD || !responseContentMatches(response, ids->qname, ids->qtype, ids->qclass, dss->remote, qnameWireLength)) { + if (fd != ids->backendFD || !responseContentMatches(response, ids->qname, ids->qtype, ids->qclass, dss->d_config.remote, qnameWireLength)) { continue; } @@ -681,9 +681,9 @@ void responderThread(std::shared_ptr dss) } double udiff = ids->sentTime.udiff(); - vinfolog("Got answer from %s, relayed to %s, took %f usec", dss->remote.toStringWithPort(), ids->origRemote.toStringWithPort(), udiff); + vinfolog("Got answer from %s, relayed to %s, took %f usec", dss->d_config.remote.toStringWithPort(), ids->origRemote.toStringWithPort(), udiff); - handleResponseSent(*ids, udiff, *dr.remote, dss->remote, static_cast(got), cleartextDH, dss->getProtocol()); + handleResponseSent(*ids, udiff, *dr.remote, dss->d_config.remote, static_cast(got), cleartextDH, dss->getProtocol()); dss->releaseState(queryId); dss->latencyUsec = (127.0 * dss->latencyUsec / 128.0) + udiff/128.0; @@ -692,7 +692,7 @@ void responderThread(std::shared_ptr dss) } } catch (const std::exception& e){ - vinfolog("Got an error in UDP responder thread while parsing a response from %s, id %d: %s", dss->remote.toStringWithPort(), queryId, e.what()); + vinfolog("Got an error in UDP responder thread while parsing a response from %s, id %d: %s", dss->d_config.remote.toStringWithPort(), queryId, e.what()); } } } @@ -1006,22 +1006,22 @@ ssize_t udpClientSendRequestToBackend(const std::shared_ptr& ss { ssize_t result; - if (ss->sourceItf == 0) { + if (ss->d_config.sourceItf == 0) { result = send(sd, request.data(), request.size(), 0); } else { struct msghdr msgh; struct iovec iov; cmsgbuf_aligned cbuf; - ComboAddress remote(ss->remote); + ComboAddress remote(ss->d_config.remote); fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), const_cast(reinterpret_cast(request.data())), request.size(), &remote); - addCMsgSrcAddr(&msgh, &cbuf, &ss->sourceAddr, ss->sourceItf); + addCMsgSrcAddr(&msgh, &cbuf, &ss->d_config.sourceAddr, ss->d_config.sourceItf); result = sendmsg(sd, &msgh, 0); } if (result == -1) { int savederrno = errno; - vinfolog("Error sending request to backend %s: %d", ss->remote.toStringWithPort(), savederrno); + vinfolog("Error sending request to backend %s: %d", ss->d_config.remote.toStringWithPort(), savederrno); /* This might sound silly, but on Linux send() might fail with EINVAL if the interface the socket was bound to doesn't exist anymore. @@ -1209,11 +1209,11 @@ ProcessQueryResult processQuery(DNSQuestion& dq, ClientState& cs, LocalHolders& dq.dnssecOK = (getEDNSZ(dq) & EDNS_HEADER_FLAG_DO); } - if (dq.useECS && ((selectedBackend && selectedBackend->useECS) || (!selectedBackend && serverPool->getECS()))) { + if (dq.useECS && ((selectedBackend && selectedBackend->d_config.useECS) || (!selectedBackend && serverPool->getECS()))) { // we special case our cache in case a downstream explicitly gave us a universally valid response with a 0 scope // we need ECS parsing (parseECS) to be true so we can be sure that the initial incoming query did not have an existing // ECS option, which would make it unsuitable for the zero-scope feature. - if (dq.packetCache && !dq.skipCache && (!selectedBackend || !selectedBackend->disableZeroScope) && dq.packetCache->isECSParsingEnabled()) { + if (dq.packetCache && !dq.skipCache && (!selectedBackend || !selectedBackend->d_config.disableZeroScope) && dq.packetCache->isECSParsingEnabled()) { if (dq.packetCache->get(dq, dq.getHeader()->id, &dq.cacheKeyNoECS, dq.subnet, dq.dnssecOK, !dq.overTCP(), allowExpired)) { if (!prepareOutgoingResponse(holders, cs, dq, true)) { @@ -1288,8 +1288,8 @@ ProcessQueryResult processQuery(DNSQuestion& dq, ClientState& cs, LocalHolders& /* save the DNS flags as sent to the backend so we can cache the answer with the right flags later */ dq.cacheFlags = *getFlagsFromDNSHeader(dq.getHeader()); - if (dq.addXPF && selectedBackend->xpfRRCode != 0) { - addXPF(dq, selectedBackend->xpfRRCode); + if (dq.addXPF && selectedBackend->d_config.xpfRRCode != 0) { + addXPF(dq, selectedBackend->d_config.xpfRRCode); } selectedBackend->incQueriesCount(); @@ -1357,9 +1357,9 @@ public: } double udiff = ids.sentTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (UDP), took %f usec", d_ds->remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff); + vinfolog("Got answer from %s, relayed to %s (UDP), took %f usec", d_ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff); - handleResponseSent(ids, udiff, *dr.remote, d_ds->remote, response.d_buffer.size(), cleartextDH, d_ds->getProtocol()); + handleResponseSent(ids, udiff, *dr.remote, d_ds->d_config.remote, response.d_buffer.size(), cleartextDH, d_ds->getProtocol()); d_ds->latencyUsec = (127.0 * d_ds->latencyUsec / 128.0) + udiff/128.0; @@ -1503,7 +1503,7 @@ static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct std::string proxyProtocolPayload; /* we need to do this _before_ creating the cross protocol query because after that the buffer will have been moved */ - if (ss->useProxyProtocol) { + if (ss->d_config.useProxyProtocol) { proxyProtocolPayload = getProxyProtocolPayload(dq); } @@ -1544,7 +1544,7 @@ static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct dh = dq.getHeader(); dh->id = idOffset; - if (ss->useProxyProtocol) { + if (ss->d_config.useProxyProtocol) { addProxyProtocol(dq); } @@ -1829,13 +1829,13 @@ static void healthChecksThread() auto mplexer = std::unique_ptr(FDMultiplexer::getMultiplexerSilent()); auto states = g_dstates.getLocal(); // this points to the actual shared_ptrs! for(auto& dss : *states) { - if (++dss->lastCheck < dss->checkInterval) { + if (++dss->lastCheck < dss->d_config.checkInterval) { continue; } dss->lastCheck = 0; - if (dss->availability == DownstreamState::Availability::Auto) { + if (dss->d_config.availability == DownstreamState::Availability::Auto) { if (!queueHealthCheck(mplexer, dss)) { updateHealthCheckResult(dss, false, false); } @@ -2419,8 +2419,8 @@ int main(int argc, char** argv) // pre compute hashes auto backends = g_dstates.getLocal(); for (auto& backend: *backends) { - if (backend->weight < 100) { - vinfolog("Warning, the backend '%s' has a very low weight (%d), which will not yield a good distribution of queries with the 'chashed' policy. Please consider raising it to at least '100'.", backend->getName(), backend->weight); + if (backend->d_config.d_weight < 100) { + vinfolog("Warning, the backend '%s' has a very low weight (%d), which will not yield a good distribution of queries with the 'chashed' policy. Please consider raising it to at least '100'.", backend->getName(), backend->d_config.d_weight); } backend->hash(); @@ -2566,13 +2566,12 @@ int main(int argc, char** argv) createPoolIfNotExists(localPools, ""); if (g_cmdLine.remotes.size()) { for (const auto& address : g_cmdLine.remotes) { - auto ret = std::make_shared(ComboAddress(address, 53)); - ret->connectUDPSockets(1); + DownstreamState::Config config; + config.remote = ComboAddress(address, 53); + auto ret = std::make_shared(std::move(config), nullptr, true); addServerToPool(localPools, "", ret); - if (ret->connected && !ret->threadStarted.test_and_set()) { - ret->tid = thread(responderThread, ret); - } - g_dstates.modify([ret](servers_t& servers) { servers.push_back(ret); }); + ret->start(); + g_dstates.modify([&ret](servers_t& servers) { servers.push_back(std::move(ret)); }); } } g_pools.setState(localPools); @@ -2585,8 +2584,8 @@ int main(int argc, char** argv) checkFileDescriptorsLimits(udpBindsCount, tcpBindsCount); auto mplexer = std::unique_ptr(FDMultiplexer::getMultiplexerSilent()); - for(auto& dss : g_dstates.getCopy()) { // it is a copy, but the internal shared_ptrs are the real deal - if (dss->availability == DownstreamState::Availability::Auto) { + for (auto& dss : g_dstates.getCopy()) { // it is a copy, but the internal shared_ptrs are the real deal + if (dss->d_config.availability == DownstreamState::Availability::Auto) { if (!queueHealthCheck(mplexer, dss, true)) { dss->setUpStatus(false); warnlog("Marking downstream %s as 'down'", dss->getNameWithAddr()); diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index ad8ab3d2ad..8757183970 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -688,15 +688,77 @@ struct ClientState struct CrossProtocolQuery; -struct DownstreamState +struct DownstreamState: public std::enable_shared_from_this { + DownstreamState(const DownstreamState&) = delete; + DownstreamState(DownstreamState&&) = default; + DownstreamState& operator=(const DownstreamState&) = delete; + DownstreamState& operator=(DownstreamState&&) = default; + typedef std::function(const DNSName&, uint16_t, uint16_t, dnsheader*)> checkfunc_t; + enum class Availability : uint8_t { Up, Down, Auto}; + + struct Config + { + Config() + { + } + Config(const ComboAddress& remote_): remote(remote_) + { + } + + set pools; + std::set d_cpus; + checkfunc_t checkFunction; + std::optional id; + DNSName checkName{"a.root-servers.net."}; + ComboAddress remote; + ComboAddress sourceAddr; + std::string sourceItfName; + std::string d_tlsSubjectName; + std::string d_dohPath; + std::string name; + std::string nameWithAddr; + size_t d_numberOfSockets{1}; + size_t d_maxInFlightQueriesPerConn{1}; + size_t d_tcpConcurrentConnectionsLimit{0}; + int order{1}; + int d_weight{1}; + int tcpConnectTimeout{5}; + int tcpRecvTimeout{30}; + int tcpSendTimeout{30}; + int d_qpsLimit{0}; + unsigned int checkInterval{1}; + unsigned int sourceItf{0}; + QType checkType{QType::A}; + uint16_t checkClass{QClass::IN}; + uint16_t d_retries{5}; + uint16_t xpfRRCode{0}; + uint16_t checkTimeout{1000}; /* in milliseconds */ + uint8_t maxCheckFailures{1}; + uint8_t minRiseSuccesses{1}; + Availability availability{Availability::Auto}; + bool mustResolve{false}; + bool useECS{false}; + bool useProxyProtocol{false}; + bool setCD{false}; + bool disableZeroScope{false}; + bool tcpFastOpen{false}; + bool ipBindAddrNoPort{true}; + bool reconnectOnUp{false}; + bool d_tcpCheck{false}; + bool d_tcpOnly{false}; + bool d_addXForwardedHeaders{false}; // for DoH backends + }; + + DownstreamState(DownstreamState::Config&& config, std::shared_ptr tlsCtx, bool connect); + DownstreamState(const ComboAddress& remote): DownstreamState(DownstreamState::Config(remote), nullptr, false) + { + } - DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf, const std::string& sourceItfName); - DownstreamState(const ComboAddress& remote_): DownstreamState(remote_, ComboAddress(), 0, std::string()) {} ~DownstreamState(); - void connectUDPSockets(size_t numberOfSockets); + Config d_config; stat_t sendErrors{0}; stat_t outstanding{0}; stat_t reuseds{0}; @@ -725,116 +787,96 @@ struct DownstreamState pdns::stat_t_trait tcpAvgConnectionDuration{0.0}; pdns::stat_t_trait queryLoad{0.0}; pdns::stat_t_trait dropRate{0.0}; - boost::uuids::uuid id; - const ComboAddress remote; - const ComboAddress sourceAddr; + SharedLockGuarded> hashes; LockGuarded> mplexer{nullptr}; - const std::string sourceItfName; - std::string d_tlsSubjectName; - std::string d_dohPath; private: - std::string name; - std::string nameWithAddr; LockGuarded> d_idStatesMap; vector idStates; public: std::shared_ptr d_tlsCtx{nullptr}; std::vector sockets; - set pools; - std::mutex connectLock; - std::thread tid; - checkfunc_t checkFunction; - DNSName checkName{"a.root-servers.net."}; StopWatch sw; QPSLimiter qps; std::atomic idOffset{0}; size_t socketsOffset{0}; - size_t d_maxInFlightQueriesPerConn{1}; - size_t d_tcpConcurrentConnectionsLimit{0}; double latencyUsec{0.0}; double latencyUsecTCP{0.0}; - int order{1}; - int weight{1}; - int tcpConnectTimeout{5}; - int tcpRecvTimeout{30}; - int tcpSendTimeout{30}; - unsigned int checkInterval{1}; unsigned int lastCheck{0}; - const unsigned int sourceItf{0}; - QType checkType{QType::A}; - uint16_t checkClass{QClass::IN}; - uint16_t d_retries{5}; - uint16_t xpfRRCode{0}; - uint16_t checkTimeout{1000}; /* in milliseconds */ uint8_t currentCheckFailures{0}; uint8_t consecutiveSuccessfulChecks{0}; - uint8_t maxCheckFailures{1}; - uint8_t minRiseSuccesses{1}; - enum class Availability : uint8_t { Up, Down, Auto} availability{Availability::Auto}; -private: - bool d_stopped{false}; -public: std::atomic hashesComputed{false}; - bool mustResolve{false}; - bool upStatus{false}; - bool useECS{false}; - bool useProxyProtocol{false}; - bool setCD{false}; - bool disableZeroScope{false}; std::atomic connected{false}; + bool upStatus{false}; + +private: + void connectUDPSockets(); + + std::thread tid; + std::mutex connectLock; std::atomic_flag threadStarted; - bool tcpFastOpen{false}; - bool ipBindAddrNoPort{true}; - bool reconnectOnUp{false}; - bool d_tcpCheck{false}; - bool d_tcpOnly{false}; - bool d_addXForwardedHeaders{false}; // for DoH backends + bool d_stopped{false}; +public: + + void start(); bool isUp() const { - if(availability == Availability::Down) + if (d_config.availability == Availability::Down) { return false; - if(availability == Availability::Up) + } + else if (d_config.availability == Availability::Up) { return true; + } return upStatus; } - void setUp() { availability = Availability::Up; } + + void setUp() { + d_config.availability = Availability::Up; + } + void setUpStatus(bool newStatus) { upStatus = newStatus; - if (!upStatus) + if (!upStatus) { latencyUsec = 0.0; + } } void setDown() { - availability = Availability::Down; + d_config.availability = Availability::Down; latencyUsec = 0.0; } - void setAuto() { availability = Availability::Auto; } + void setAuto() { + d_config.availability = Availability::Auto; + } const string& getName() const { - return name; + return d_config.name; } const string& getNameWithAddr() const { - return nameWithAddr; + return d_config.nameWithAddr; } void setName(const std::string& newName) { - name = newName; - nameWithAddr = newName.empty() ? remote.toStringWithPort() : (name + " (" + remote.toStringWithPort()+ ")"); + d_config.name = newName; + d_config.nameWithAddr = newName.empty() ? d_config.remote.toStringWithPort() : (d_config.name + " (" + d_config.remote.toStringWithPort()+ ")"); } string getStatus() const { string status; - if(availability == DownstreamState::Availability::Up) + if (d_config.availability == DownstreamState::Availability::Up) { status = "UP"; - else if(availability == DownstreamState::Availability::Down) + } + else if (d_config.availability == DownstreamState::Availability::Down) { status = "DOWN"; - else + } + else { status = (upStatus ? "up" : "down"); + } return status; } + bool reconnect(); void hash(); void setId(const boost::uuids::uuid& newId); @@ -846,7 +888,7 @@ public: } const boost::uuids::uuid& getID() const { - return id; + return *d_config.id; } void updateTCPMetrics(size_t nbQueries, uint64_t durationMs) @@ -865,17 +907,17 @@ public: bool doHealthcheckOverTCP() const { - return d_tcpOnly || d_tcpCheck || d_tlsCtx != nullptr; + return d_config.d_tcpOnly || d_config.d_tcpCheck || d_tlsCtx != nullptr; } bool isTCPOnly() const { - return d_tcpOnly || d_tlsCtx != nullptr; + return d_config.d_tcpOnly || d_tlsCtx != nullptr; } bool isDoH() const { - return !d_dohPath.empty(); + return !d_config.d_dohPath.empty(); } bool passCrossProtocolQuery(std::unique_ptr&& cpq); @@ -906,7 +948,7 @@ public: private: void handleTimeout(IDState& ids); }; -using servers_t =vector>; +using servers_t = vector>; void responderThread(std::shared_ptr state); extern LockGuarded g_lua; diff --git a/pdns/dnsdistdist/dnsdist-backend.cc b/pdns/dnsdistdist/dnsdist-backend.cc index 88631b1d63..a039ee6f07 100644 --- a/pdns/dnsdistdist/dnsdist-backend.cc +++ b/pdns/dnsdistdist/dnsdist-backend.cc @@ -27,10 +27,9 @@ #include "dnsdist-tcp.hh" #include "dolog.hh" - bool DownstreamState::passCrossProtocolQuery(std::unique_ptr&& cpq) { - if (d_dohPath.empty()) { + if (d_config.d_dohPath.empty()) { return g_tcpclientthreads && g_tcpclientthreads->passCrossProtocolQueryToThread(std::move(cpq)); } else { @@ -57,30 +56,30 @@ bool DownstreamState::reconnect() close(fd); fd = -1; } - if (!IsAnyAddress(remote)) { - fd = SSocket(remote.sin4.sin_family, SOCK_DGRAM, 0); - if (!IsAnyAddress(sourceAddr)) { + if (!IsAnyAddress(d_config.remote)) { + fd = SSocket(d_config.remote.sin4.sin_family, SOCK_DGRAM, 0); + if (!IsAnyAddress(d_config.sourceAddr)) { SSetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1); - if (!sourceItfName.empty()) { + if (!d_config.sourceItfName.empty()) { #ifdef SO_BINDTODEVICE - int res = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, sourceItfName.c_str(), sourceItfName.length()); + int res = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, d_config.sourceItfName.c_str(), d_config.sourceItfName.length()); if (res != 0) { - infolog("Error setting up the interface on backend socket '%s': %s", remote.toStringWithPort(), stringerror()); + infolog("Error setting up the interface on backend socket '%s': %s", d_config.remote.toStringWithPort(), stringerror()); } #endif } - SBind(fd, sourceAddr); + SBind(fd, d_config.sourceAddr); } try { - SConnect(fd, remote); + SConnect(fd, d_config.remote); if (sockets.size() > 1) { (*mplexer.lock())->addReadFD(fd, [](int, boost::any) {}); } connected = true; } catch(const std::runtime_error& error) { - infolog("Error connecting to new server with address %s: %s", remote.toStringWithPort(), error.what()); + infolog("Error connecting to new server with address %s: %s", d_config.remote.toStringWithPort(), error.what()); connected = false; break; } @@ -130,13 +129,14 @@ void DownstreamState::stop() void DownstreamState::hash() { - vinfolog("Computing hashes for id=%s and weight=%d", id, weight); - auto w = weight; + vinfolog("Computing hashes for id=%s and weight=%d", *d_config.id, d_config.d_weight); + auto w = d_config.d_weight; + auto idStr = boost::str(boost::format("%s") % *d_config.id); auto lockedHashes = hashes.write_lock(); lockedHashes->clear(); lockedHashes->reserve(w); while (w > 0) { - std::string uuid = boost::str(boost::format("%s-%d") % id % w); + std::string uuid = boost::str(boost::format("%s-%d") % idStr % w); unsigned int wshash = burtleCI(reinterpret_cast(uuid.c_str()), uuid.size(), g_hashperturb); lockedHashes->push_back(wshash); --w; @@ -147,7 +147,7 @@ void DownstreamState::hash() void DownstreamState::setId(const boost::uuids::uuid& newId) { - id = newId; + d_config.id = newId; // compute hashes only if already done if (hashesComputed) { hash(); @@ -160,21 +160,78 @@ void DownstreamState::setWeight(int newWeight) errlog("Error setting server's weight: downstream weight value must be greater than 0."); return ; } - weight = newWeight; + + d_config.d_weight = newWeight; + if (hashesComputed) { hash(); } } -DownstreamState::DownstreamState(const ComboAddress& remote_, const ComboAddress& sourceAddr_, unsigned int sourceItf_, const std::string& sourceItfName_): remote(remote_), sourceAddr(sourceAddr_), sourceItfName(sourceItfName_), name(remote_.toStringWithPort()), nameWithAddr(remote_.toStringWithPort()), sourceItf(sourceItf_) +DownstreamState::DownstreamState(DownstreamState::Config&& config, std::shared_ptr tlsCtx, bool connect): d_config(std::move(config)), d_tlsCtx(std::move(tlsCtx)) { - id = getUniqueID(); threadStarted.clear(); + if (d_config.d_qpsLimit > 0) { + qps = QPSLimiter(d_config.d_qpsLimit, d_config.d_qpsLimit); + } + + if (d_config.id) { + setId(*d_config.id); + } + else { + d_config.id = getUniqueID(); + } + + if (d_config.d_weight > 0) { + setWeight(d_config.d_weight); + } + + setName(d_config.name); + + if (d_tlsCtx) { + if (!d_config.d_dohPath.empty()) { +#ifdef HAVE_NGHTTP2 + setupDoHClientProtocolNegotiation(d_tlsCtx); + + if (g_configurationDone && g_outgoingDoHWorkerThreads && *g_outgoingDoHWorkerThreads == 0) { + throw std::runtime_error("Error: setOutgoingDoHWorkerThreads() is set to 0 so no outgoing DoH worker thread is available to serve queries"); + } + + if (!g_outgoingDoHWorkerThreads || *g_outgoingDoHWorkerThreads == 0) { + g_outgoingDoHWorkerThreads = 1; + } +#endif /* HAVE_NGHTTP2 */ + } + else { + setupDoTProtocolNegotiation(d_tlsCtx); + } + } + + if (connect && !isTCPOnly()) { + if (!IsAnyAddress(d_config.remote)) { + connectUDPSockets(); + } + } + sw.start(); } -void DownstreamState::connectUDPSockets(size_t numberOfSockets) + +void DownstreamState::start() +{ + if (connected && !threadStarted.test_and_set()) { + tid = std::thread(responderThread, shared_from_this()); + + if (!d_config.d_cpus.empty()) { + mapThreadToCPUList(tid.native_handle(), d_config.d_cpus); + } + + tid.detach(); + } +} + +void DownstreamState::connectUDPSockets() { if (s_randomizeIDs) { idStates.clear(); @@ -182,7 +239,7 @@ void DownstreamState::connectUDPSockets(size_t numberOfSockets) else { idStates.resize(g_maxOutstanding); } - sockets.resize(numberOfSockets); + sockets.resize(d_config.d_numberOfSockets); if (sockets.size() > 1) { *(mplexer.lock()) = std::unique_ptr(FDMultiplexer::getMultiplexerSilent()); @@ -203,12 +260,6 @@ DownstreamState::~DownstreamState() fd = -1; } } - - // we need to either detach or join the thread before it - // is destroyed - if (threadStarted.test_and_set()) { - tid.detach(); - } } void DownstreamState::incCurrentConnectionsCount() @@ -275,7 +326,7 @@ void DownstreamState::handleTimeout(IDState& ids) --outstanding; ++g_stats.downstreamTimeouts; // this is an 'actively' discovered timeout vinfolog("Had a downstream timeout from %s (%s) for query for %s|%s from %s", - remote.toStringWithPort(), getName(), + d_config.remote.toStringWithPort(), getName(), ids.qname.toLogString(), QType(ids.qtype).toString(), ids.origRemote.toStringWithPort()); struct timespec ts; @@ -285,7 +336,7 @@ void DownstreamState::handleTimeout(IDState& ids) memset(&fake, 0, sizeof(fake)); fake.id = ids.origID; - g_rings.insertResponse(ts, ids.origRemote, ids.qname, ids.qtype, std::numeric_limits::max(), 0, fake, remote, getProtocol()); + g_rings.insertResponse(ts, ids.origRemote, ids.qname, ids.qtype, std::numeric_limits::max(), 0, fake, d_config.remote, getProtocol()); } void DownstreamState::handleTimeouts() @@ -452,7 +503,7 @@ void ServerPool::addServer(shared_ptr& server) newServers->emplace_back(++count, server); /* we need to reorder based on the server 'order' */ std::stable_sort(newServers->begin(), newServers->end(), [](const std::pair >& a, const std::pair >& b) { - return a.second->order < b.second->order; + return a.second->d_config.order < b.second->d_config.order; }); /* and now we need to renumber for Lua (custom policies) */ size_t idx = 1; diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index a8c82d85a4..d46ec532b3 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -70,7 +70,7 @@ void updateHealthCheckResult(const std::shared_ptr& dss, bool i if (!dss->upStatus) { /* we were marked as down */ dss->consecutiveSuccessfulChecks++; - if (dss->consecutiveSuccessfulChecks < dss->minRiseSuccesses) { + if (dss->consecutiveSuccessfulChecks < dss->d_config.minRiseSuccesses) { /* if we need more than one successful check to rise and we didn't reach the threshold yet, let's stay down */ @@ -85,7 +85,7 @@ void updateHealthCheckResult(const std::shared_ptr& dss, bool i if (dss->upStatus) { /* we are currently up */ dss->currentCheckFailures++; - if (dss->currentCheckFailures < dss->maxCheckFailures) { + if (dss->currentCheckFailures < dss->d_config.maxCheckFailures) { /* we need more than one failure to be marked as down, and we did not reach the threshold yet, let's stay up */ newState = true; @@ -96,12 +96,9 @@ void updateHealthCheckResult(const std::shared_ptr& dss, bool i if (newState != dss->upStatus) { warnlog("Marking downstream %s as '%s'", dss->getNameWithAddr(), newState ? "up" : "down"); - if (newState && !dss->isTCPOnly() && (!dss->connected || dss->reconnectOnUp)) { + if (newState && !dss->isTCPOnly() && (!dss->connected || dss->d_config.reconnectOnUp)) { newState = dss->reconnect(); - - if (dss->connected && !dss->threadStarted.test_and_set()) { - dss->tid = std::thread(responderThread, dss); - } + dss->start(); } dss->setUpStatus(newState); @@ -146,7 +143,7 @@ static bool handleResponse(std::shared_ptr& data) return false; } - if (ds->mustResolve && (responseHeader->rcode == RCode::NXDomain || responseHeader->rcode == RCode::Refused)) { + if (ds->d_config.mustResolve && (responseHeader->rcode == RCode::NXDomain || responseHeader->rcode == RCode::Refused)) { if (g_verboseHealthChecks) { infolog("Backend %s responded to health check with %s while mustResolve is set", ds->getNameWithAddr(), responseHeader->rcode == RCode::NXDomain ? "NXDomain" : "Refused"); } @@ -229,21 +226,21 @@ static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) data->d_mplexer.removeReadFD(fd); ComboAddress from; - from.sin4.sin_family = data->d_ds->remote.sin4.sin_family; + from.sin4.sin_family = data->d_ds->d_config.remote.sin4.sin_family; auto fromlen = from.getSocklen(); data->d_buffer.resize(512); auto got = recvfrom(data->d_udpSocket.getHandle(), &data->d_buffer.at(0), data->d_buffer.size(), 0, reinterpret_cast(&from), &fromlen); if (got < 0) { if (g_verboseHealthChecks) { - infolog("Error receiving health check response from %s: %s", data->d_ds->remote.toStringWithPort(), stringerror()); + infolog("Error receiving health check response from %s: %s", data->d_ds->d_config.remote.toStringWithPort(), stringerror()); } updateHealthCheckResult(data->d_ds, data->d_initial, false); } /* we are using a connected socket but hey.. */ - if (from != data->d_ds->remote) { + if (from != data->d_ds->d_config.remote) { if (g_verboseHealthChecks) { - infolog("Invalid health check response received from %s, expecting one from %s", from.toStringWithPort(), data->d_ds->remote.toStringWithPort()); + infolog("Invalid health check response received from %s, expecting one from %s", from.toStringWithPort(), data->d_ds->d_config.remote.toStringWithPort()); } updateHealthCheckResult(data->d_ds, data->d_initial, false); } @@ -327,9 +324,9 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared try { uint16_t queryID = dnsdist::getRandomDNSID(); - DNSName checkName = ds->checkName; - uint16_t checkType = ds->checkType.getCode(); - uint16_t checkClass = ds->checkClass; + DNSName checkName = ds->d_config.checkName; + uint16_t checkType = ds->d_config.checkType.getCode(); + uint16_t checkClass = ds->d_config.checkClass; dnsheader checkHeader; memset(&checkHeader, 0, sizeof(checkHeader)); @@ -337,13 +334,13 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared checkHeader.id = queryID; checkHeader.rd = true; - if (ds->setCD) { + if (ds->d_config.setCD) { checkHeader.cd = true; } - if (ds->checkFunction) { + if (ds->d_config.checkFunction) { auto lock = g_lua.lock(); - auto ret = ds->checkFunction(checkName, checkType, checkClass, &checkHeader); + auto ret = ds->d_config.checkFunction(checkName, checkType, checkClass, &checkHeader); checkName = std::get<0>(ret); checkType = std::get<1>(ret); checkClass = std::get<2>(ret); @@ -358,7 +355,7 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared uint16_t packetSize = packet.size(); std::string proxyProtocolPayload; size_t proxyProtocolPayloadSize = 0; - if (ds->useProxyProtocol) { + if (ds->d_config.useProxyProtocol) { proxyProtocolPayload = makeLocalProxyHeader(); proxyProtocolPayloadSize = proxyProtocolPayload.size(); if (!ds->isDoH()) { @@ -366,41 +363,41 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared } } - Socket sock(ds->remote.sin4.sin_family, ds->doHealthcheckOverTCP() ? SOCK_STREAM : SOCK_DGRAM); + Socket sock(ds->d_config.remote.sin4.sin_family, ds->doHealthcheckOverTCP() ? SOCK_STREAM : SOCK_DGRAM); sock.setNonBlocking(); - if (!IsAnyAddress(ds->sourceAddr)) { + if (!IsAnyAddress(ds->d_config.sourceAddr)) { sock.setReuseAddr(); #ifdef IP_BIND_ADDRESS_NO_PORT - if (ds->ipBindAddrNoPort) { + if (ds->d_config.ipBindAddrNoPort) { SSetsockopt(sock.getHandle(), SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1); } #endif - if (!ds->sourceItfName.empty()) { + if (!ds->d_config.sourceItfName.empty()) { #ifdef SO_BINDTODEVICE - int res = setsockopt(sock.getHandle(), SOL_SOCKET, SO_BINDTODEVICE, ds->sourceItfName.c_str(), ds->sourceItfName.length()); + int res = setsockopt(sock.getHandle(), SOL_SOCKET, SO_BINDTODEVICE, ds->d_config.sourceItfName.c_str(), ds->d_config.sourceItfName.length()); if (res != 0 && g_verboseHealthChecks) { infolog("Error setting SO_BINDTODEVICE on the health check socket for backend '%s': %s", ds->getNameWithAddr(), stringerror()); } #endif } - sock.bind(ds->sourceAddr); + sock.bind(ds->d_config.sourceAddr); } auto data = std::make_shared(*mplexer, ds, std::move(checkName), checkType, checkClass, queryID); data->d_initial = initialCheck; gettimeofday(&data->d_ttd, nullptr); - data->d_ttd.tv_sec += ds->checkTimeout / 1000; /* ms to seconds */ - data->d_ttd.tv_usec += (ds->checkTimeout % 1000) * 1000; /* remaining ms to us */ + data->d_ttd.tv_sec += ds->d_config.checkTimeout / 1000; /* ms to seconds */ + data->d_ttd.tv_usec += (ds->d_config.checkTimeout % 1000) * 1000; /* remaining ms to us */ if (data->d_ttd.tv_usec > 1000000) { ++data->d_ttd.tv_sec; data->d_ttd.tv_usec -= 1000000; } if (!ds->doHealthcheckOverTCP()) { - sock.connect(ds->remote); + sock.connect(ds->d_config.remote); data->d_udpSocket = std::move(sock); ssize_t sent = udpClientSendRequestToBackend(ds, data->d_udpSocket.getHandle(), packet, true); if (sent < 0) { @@ -423,7 +420,7 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared } else { time_t now = time(nullptr); - data->d_tcpHandler = std::make_unique(ds->d_tlsSubjectName, sock.releaseHandle(), timeval{ds->checkTimeout,0}, ds->d_tlsCtx, now); + data->d_tcpHandler = std::make_unique(ds->d_config.d_tlsSubjectName, sock.releaseHandle(), timeval{ds->d_config.checkTimeout,0}, ds->d_tlsCtx, now); data->d_ioState = std::make_unique(*mplexer, data->d_tcpHandler->getDescriptor()); if (ds->d_tlsCtx) { try { @@ -436,7 +433,7 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared vinfolog("Unable to restore a TLS session for the DoT healthcheck: %s", e.what()); } } - data->d_tcpHandler->tryConnect(ds->tcpFastOpen, ds->remote); + data->d_tcpHandler->tryConnect(ds->d_config.tcpFastOpen, ds->d_config.remote); const uint8_t sizeBytes[] = { static_cast(packetSize / 256), static_cast(packetSize % 256) }; packet.insert(packet.begin() + proxyProtocolPayloadSize, sizeBytes, sizeBytes + 2); diff --git a/pdns/dnsdistdist/dnsdist-lbpolicies.cc b/pdns/dnsdistdist/dnsdist-lbpolicies.cc index 39d465c7b8..eb5a3aa3ae 100644 --- a/pdns/dnsdistdist/dnsdist-lbpolicies.cc +++ b/pdns/dnsdistdist/dnsdist-lbpolicies.cc @@ -43,7 +43,7 @@ shared_ptr leastOutstanding(const ServerPolicy::NumberedServerV size_t position = 0; for(const auto& d : servers) { if(d.second->isUp()) { - poss.emplace_back(std::make_tuple(d.second->outstanding.load(), d.second->order, d.second->latencyUsec), position); + poss.emplace_back(std::make_tuple(d.second->outstanding.load(), d.second->d_config.order, d.second->latencyUsec), position); } ++position; } @@ -83,7 +83,7 @@ static shared_ptr valrandom(unsigned int val, const ServerPolic for (const auto& pair : servers) { if (pair.second->isUp()) { currentLoad += pair.second->outstanding; - totalWeight += pair.second->weight; + totalWeight += pair.second->d_config.d_weight; } } @@ -93,12 +93,12 @@ static shared_ptr valrandom(unsigned int val, const ServerPolic } for (const auto& d : servers) { // w=1, w=10 -> 1, 11 - if (d.second->isUp() && (g_weightedBalancingFactor == 0 || (d.second->outstanding <= (targetLoad * d.second->weight)))) { + if (d.second->isUp() && (g_weightedBalancingFactor == 0 || (d.second->outstanding <= (targetLoad * d.second->d_config.d_weight)))) { // Don't overflow sum when adding high weights - if (d.second->weight > max - sum) { + if (d.second->d_config.d_weight > max - sum) { sum = max; } else { - sum += d.second->weight; + sum += d.second->d_config.d_weight; } poss.emplace_back(sum, d.first); @@ -151,7 +151,7 @@ shared_ptr chashedFromHash(const ServerPolicy::NumberedServerVe for (const auto& pair : servers) { if (pair.second->isUp()) { currentLoad += pair.second->outstanding; - totalWeight += pair.second->weight; + totalWeight += pair.second->d_config.d_weight; } } @@ -161,7 +161,7 @@ shared_ptr chashedFromHash(const ServerPolicy::NumberedServerVe } for (const auto& d: servers) { - if (d.second->isUp() && (g_consistentHashBalancingFactor == 0 || d.second->outstanding <= (targetLoad * d.second->weight))) { + if (d.second->isUp() && (g_consistentHashBalancingFactor == 0 || d.second->outstanding <= (targetLoad * d.second->d_config.d_weight))) { // make sure hashes have been computed if (!d.second->hashesComputed) { d.second->hash(); diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index ab5a273ca6..420e13f933 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -564,12 +564,12 @@ uint64_t dnsdist_ffi_server_get_outstanding(const dnsdist_ffi_server_t* server) int dnsdist_ffi_server_get_weight(const dnsdist_ffi_server_t* server) { - return server->server->weight; + return server->server->d_config.d_weight; } int dnsdist_ffi_server_get_order(const dnsdist_ffi_server_t* server) { - return server->server->order; + return server->server->d_config.order; } double dnsdist_ffi_server_get_latency(const dnsdist_ffi_server_t* server) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 9d5781e332..8e2b9d95af 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -246,7 +246,7 @@ void DoHConnectionToBackend::queueQuery(std::shared_ptr& sender, { auto payloadSize = std::to_string(query.d_buffer.size()); - bool addXForwarded = d_ds->d_addXForwardedHeaders; + bool addXForwarded = d_ds->d_config.d_addXForwardedHeaders; /* We use nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME and nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE to avoid a copy and lowercasing but we need to make sure that the data will outlive the request (nghttp2_on_frame_send_callback called), and that it is already lowercased. */ @@ -259,8 +259,8 @@ void DoHConnectionToBackend::queueQuery(std::shared_ptr& sender, /* Pseudo-headers need to come first (rfc7540 8.1.2.1) */ addStaticHeader(headers, "method-name", "method-value"); addStaticHeader(headers, "scheme-name", "scheme-value"); - addDynamicHeader(headers, "authority-name", d_ds->d_tlsSubjectName); - addDynamicHeader(headers, "path-name", d_ds->d_dohPath); + addDynamicHeader(headers, "authority-name", d_ds->d_config.d_tlsSubjectName); + addDynamicHeader(headers, "path-name", d_ds->d_config.d_dohPath); addStaticHeader(headers, "accept-name", "accept-value"); addStaticHeader(headers, "content-type-name", "content-type-value"); addStaticHeader(headers, "user-agent-name", "user-agent-value"); @@ -716,7 +716,7 @@ int DoHConnectionToBackend::on_stream_close_callback(nghttp2_session* session, i conn->d_currentStreams.erase(stream->first); // cerr<<"Query has "<d_ds->d_retries<d_ds->d_retries) { + if (request.d_query.d_downstreamFailures < conn->d_ds->d_config.d_retries) { // cerr<<"in "<<__PRETTY_FUNCTION__<<", looking for a connection to send a query of size "<d_mplexer, conn->d_ds, now, std::string(conn->d_proxyProtocolPayload)); diff --git a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc index 9c636d227c..ebb63a99c8 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc +++ b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc @@ -72,37 +72,37 @@ bool ConnectionToBackend::reconnect() DEBUGLOG("Opening TCP connection to backend "<getNameWithAddr()); ++d_ds->tcpNewConnections; try { - auto socket = std::make_unique(d_ds->remote.sin4.sin_family, SOCK_STREAM, 0); + auto socket = std::make_unique(d_ds->d_config.remote.sin4.sin_family, SOCK_STREAM, 0); DEBUGLOG("result of socket() is "<getHandle()); - if (!IsAnyAddress(d_ds->sourceAddr)) { + if (!IsAnyAddress(d_ds->d_config.sourceAddr)) { SSetsockopt(socket->getHandle(), SOL_SOCKET, SO_REUSEADDR, 1); #ifdef IP_BIND_ADDRESS_NO_PORT - if (d_ds->ipBindAddrNoPort) { + if (d_ds->d_config.ipBindAddrNoPort) { SSetsockopt(socket->getHandle(), SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1); } #endif #ifdef SO_BINDTODEVICE - if (!d_ds->sourceItfName.empty()) { - int res = setsockopt(socket->getHandle(), SOL_SOCKET, SO_BINDTODEVICE, d_ds->sourceItfName.c_str(), d_ds->sourceItfName.length()); + if (!d_ds->d_config.sourceItfName.empty()) { + int res = setsockopt(socket->getHandle(), SOL_SOCKET, SO_BINDTODEVICE, d_ds->d_config.sourceItfName.c_str(), d_ds->d_config.sourceItfName.length()); if (res != 0) { vinfolog("Error setting up the interface on backend TCP socket '%s': %s", d_ds->getNameWithAddr(), stringerror()); } } #endif - socket->bind(d_ds->sourceAddr, false); + socket->bind(d_ds->d_config.sourceAddr, false); } socket->setNonBlocking(); gettimeofday(&d_connectionStartTime, nullptr); - auto handler = std::make_unique(d_ds->d_tlsSubjectName, socket->releaseHandle(), timeval{0,0}, d_ds->d_tlsCtx, d_connectionStartTime.tv_sec); + auto handler = std::make_unique(d_ds->d_config.d_tlsSubjectName, socket->releaseHandle(), timeval{0,0}, d_ds->d_tlsCtx, d_connectionStartTime.tv_sec); if (!tlsSession && d_ds->d_tlsCtx) { tlsSession = g_sessionCache.getSession(d_ds->getID(), d_connectionStartTime.tv_sec); } if (tlsSession) { handler->setTLSSession(tlsSession); } - handler->tryConnect(d_ds->tcpFastOpen && isFastOpenEnabled(), d_ds->remote); + handler->tryConnect(d_ds->d_config.tcpFastOpen && isFastOpenEnabled(), d_ds->d_config.remote); d_queries = 0; d_handler = std::move(handler); @@ -112,12 +112,12 @@ bool ConnectionToBackend::reconnect() catch (const std::runtime_error& e) { vinfolog("Connection to downstream server %s failed: %s", d_ds->getName(), e.what()); d_downstreamFailures++; - if (d_downstreamFailures >= d_ds->d_retries) { + if (d_downstreamFailures >= d_ds->d_config.d_retries) { throw; } } } - while (d_downstreamFailures < d_ds->d_retries); + while (d_downstreamFailures < d_ds->d_config.d_retries); return false; } @@ -129,8 +129,7 @@ TCPConnectionToBackend::~TCPConnectionToBackend() } } -void TCPConnectionToBackend::release() -{ +void TCPConnectionToBackend::release(){ d_ds->outstanding -= d_pendingResponses.size(); d_pendingResponses.clear(); @@ -337,7 +336,7 @@ void TCPConnectionToBackend::handleIO(std::shared_ptr& c DEBUGLOG("connection died, number of failures is "<d_downstreamFailures<<", retries is "<d_ds->d_retries); - if (conn->d_downstreamFailures < conn->d_ds->d_retries) { + if (conn->d_downstreamFailures < conn->d_ds->d_config.d_retries) { conn->d_ioState.reset(); ioGuard.release(); diff --git a/pdns/dnsdistdist/dnsdist-tcp-downstream.hh b/pdns/dnsdistdist/dnsdist-tcp-downstream.hh index da403655bc..7c041784d4 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-downstream.hh +++ b/pdns/dnsdistdist/dnsdist-tcp-downstream.hh @@ -15,7 +15,7 @@ class ConnectionToBackend : public std::enable_shared_from_this { public: - ConnectionToBackend(const std::shared_ptr& ds, std::unique_ptr& mplexer, const struct timeval& now): d_connectionStartTime(now), d_lastDataReceivedTime(now), d_ds(ds), d_mplexer(mplexer), d_enableFastOpen(ds->tcpFastOpen) + ConnectionToBackend(const std::shared_ptr& ds, std::unique_ptr& mplexer, const struct timeval& now): d_connectionStartTime(now), d_lastDataReceivedTime(now), d_ds(ds), d_mplexer(mplexer), d_enableFastOpen(ds->d_config.tcpFastOpen) { reconnect(); } @@ -48,7 +48,7 @@ public: const ComboAddress& getRemote() const { - return d_ds->remote; + return d_ds->d_config.remote; } const std::string& getBackendName() const @@ -88,7 +88,7 @@ public: - it cannot be reused for a different client - we might have different TLV values for each query */ - if (d_ds && d_ds->useProxyProtocol == true && !sameClient) { + if (d_ds && d_ds->d_config.useProxyProtocol == true && !sameClient) { return false; } @@ -110,7 +110,7 @@ public: return false; } - if (d_ds && d_ds->useProxyProtocol == true) { + if (d_ds && d_ds->d_config.useProxyProtocol == true) { return sameClient; } @@ -151,13 +151,13 @@ protected: if (d_ds == nullptr) { throw std::runtime_error("getBackendReadTTD() without any backend selected"); } - if (d_ds->checkTimeout == 0) { + if (d_ds->d_config.checkTimeout == 0) { return boost::none; } struct timeval res = now; - res.tv_sec += d_ds->checkTimeout / 1000; /* ms to s */ - res.tv_usec += (d_ds->checkTimeout % 1000) / 1000; /* remaining ms to µs */ + res.tv_sec += d_ds->d_config.checkTimeout / 1000; /* ms to s */ + res.tv_usec += (d_ds->d_config.checkTimeout % 1000) / 1000; /* remaining ms to µs */ return res; } @@ -167,12 +167,12 @@ protected: if (d_ds == nullptr) { throw std::runtime_error("getBackendReadTTD() without any backend selected"); } - if (d_ds->tcpRecvTimeout == 0) { + if (d_ds->d_config.tcpRecvTimeout == 0) { return boost::none; } struct timeval res = now; - res.tv_sec += d_ds->tcpRecvTimeout; + res.tv_sec += d_ds->d_config.tcpRecvTimeout; return res; } @@ -182,12 +182,12 @@ protected: if (d_ds == nullptr) { throw std::runtime_error("getBackendWriteTTD() called without any backend selected"); } - if (d_ds->tcpSendTimeout == 0) { + if (d_ds->d_config.tcpSendTimeout == 0) { return boost::none; } struct timeval res = now; - res.tv_sec += d_ds->tcpSendTimeout; + res.tv_sec += d_ds->d_config.tcpSendTimeout; return res; } @@ -197,12 +197,12 @@ protected: if (d_ds == nullptr) { throw std::runtime_error("getBackendConnectTTD() called without any backend selected"); } - if (d_ds->tcpConnectTimeout == 0) { + if (d_ds->d_config.tcpConnectTimeout == 0) { return boost::none; } struct timeval res = now; - res.tv_sec += d_ds->tcpConnectTimeout; + res.tv_sec += d_ds->d_config.tcpConnectTimeout; return res; } @@ -247,7 +247,7 @@ public: bool reachedMaxConcurrentQueries() const override { const size_t concurrent = d_pendingQueries.size() + d_pendingResponses.size(); - if (concurrent > 0 && concurrent >= d_ds->d_maxInFlightQueriesPerConn) { + if (concurrent > 0 && concurrent >= d_ds->d_config.d_maxInFlightQueriesPerConn) { return true; } return false; @@ -284,7 +284,7 @@ private: void notifyAllQueriesFailed(const struct timeval& now, FailureReason reason); bool needProxyProtocolPayload() const { - return !d_proxyProtocolPayloadSent && (d_ds && d_ds->useProxyProtocol); + return !d_proxyProtocolPayloadSent && (d_ds && d_ds->d_config.useProxyProtocol); } class PendingRequest @@ -350,7 +350,7 @@ public: cleanupClosedConnections(now); - const bool haveProxyProtocol = ds->useProxyProtocol || !proxyProtocolPayload.empty(); + const bool haveProxyProtocol = ds->d_config.useProxyProtocol || !proxyProtocolPayload.empty(); if (!haveProxyProtocol) { const auto& it = d_downstreamConnections.find(backendId); if (it != d_downstreamConnections.end()) { diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index dc8ef14001..9f55553777 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -467,9 +467,9 @@ public: } double udiff = du->ids.sentTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (https), took %f usec", du->downstream->remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); + vinfolog("Got answer from %s, relayed to %s (https), took %f usec", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); - handleResponseSent(du->ids, udiff, *dr.remote, du->downstream->remote, du->response.size(), cleartextDH, du->downstream->getProtocol()); + handleResponseSent(du->ids, udiff, *dr.remote, du->downstream->d_config.remote, du->response.size(), cleartextDH, du->downstream->getProtocol()); ++g_stats.responses; if (du->ids.cs) { @@ -636,7 +636,7 @@ static void processDOHQuery(DOHUnitUniquePtr&& du) std::string proxyProtocolPayload; /* we need to do this _before_ creating the cross protocol query because after that the buffer will have been moved */ - if (du->downstream->useProxyProtocol) { + if (du->downstream->d_config.useProxyProtocol) { proxyProtocolPayload = getProxyProtocolPayload(dq); } @@ -693,7 +693,7 @@ static void processDOHQuery(DOHUnitUniquePtr&& du) ids->destHarvested = false; } - if (du->downstream->useProxyProtocol) { + if (du->downstream->d_config.useProxyProtocol) { size_t payloadSize = 0; if (addProxyProtocol(dq)) { du->proxyProtocolPayloadSize = payloadSize; @@ -1642,9 +1642,9 @@ void handleUDPResponseForDoH(DOHUnitUniquePtr&& du, PacketBuffer&& udpResponse, } double udiff = du->ids.sentTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (https), took %f usec", du->downstream->remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); + vinfolog("Got answer from %s, relayed to %s (https), took %f usec", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); - handleResponseSent(du->ids, udiff, *dr.remote, du->downstream->remote, du->response.size(), cleartextDH, du->downstream->getProtocol()); + handleResponseSent(du->ids, udiff, *dr.remote, du->downstream->d_config.remote, du->response.size(), cleartextDH, du->downstream->getProtocol()); ++g_stats.responses; if (du->ids.cs) { diff --git a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc index 32d6f2edda..3ae268d27a 100644 --- a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc @@ -92,7 +92,17 @@ DNSAction::Action SpoofAction::operator()(DNSQuestion* dq, std::string* ruleresu return DNSAction::Action::None; } +bool setupDoTProtocolNegotiation(std::shared_ptr&) +{ + return true; +} + +void responderThread(std::shared_ptr dss) +{ +} + string g_outputBuffer; +std::atomic g_configurationDone{false}; static DNSQuestion getDQ(const DNSName* providedName = nullptr) { @@ -200,8 +210,8 @@ BOOST_AUTO_TEST_CASE(test_firstAvailableWithOrderAndQPS) { we need to keep them ordered!). However the first server has a QPS limit at 10 qps, so any query above that should be routed to the second server. */ - servers.at(0).second->order = 1; - servers.at(1).second->order = 2; + servers.at(0).second->d_config.order = 1; + servers.at(1).second->d_config.order = 2; servers.at(0).second->qps = QPSLimiter(qpsLimit, qpsLimit); /* mark the servers as 'up' */ servers.at(0).second->setUp(); @@ -361,16 +371,16 @@ BOOST_AUTO_TEST_CASE(test_wrandom) { /* reset */ for (auto& entry : serversMap) { entry.second = 0; - BOOST_CHECK_EQUAL(entry.first->weight, 1); + BOOST_CHECK_EQUAL(entry.first->d_config.d_weight, 1); } /* reset */ for (auto& entry : serversMap) { entry.second = 0; - BOOST_CHECK_EQUAL(entry.first->weight, 1); + BOOST_CHECK_EQUAL(entry.first->d_config.d_weight, 1); } /* change the weight of the last server to 100, default is 1 */ - servers.at(servers.size()-1).second->weight = 100; + servers.at(servers.size()-1).second->d_config.d_weight = 100; for (size_t idx = 0; idx < 1000; idx++) { auto server = pol.getSelectedBackend(servers, dq); @@ -382,12 +392,12 @@ BOOST_AUTO_TEST_CASE(test_wrandom) { uint64_t totalW = 0; for (const auto& entry : serversMap) { total += entry.second; - totalW += entry.first->weight; + totalW += entry.first->d_config.d_weight; } BOOST_CHECK_EQUAL(total, 1000U); auto last = servers.at(servers.size()-1).second; const auto got = serversMap[last]; - float expected = (1000 * 1.0 * last->weight) / totalW; + float expected = (1000 * 1.0 * last->d_config.d_weight) / totalW; BOOST_CHECK_GT(got, expected / 2); BOOST_CHECK_LT(got, expected * 2); } @@ -429,7 +439,7 @@ BOOST_AUTO_TEST_CASE(test_whashed) { /* reset */ for (auto& entry : serversMap) { entry.second = 0; - BOOST_CHECK_EQUAL(entry.first->weight, 1); + BOOST_CHECK_EQUAL(entry.first->d_config.d_weight, 1); } /* request 1000 times the same name, we should go to the same server every time */ @@ -444,7 +454,7 @@ BOOST_AUTO_TEST_CASE(test_whashed) { /* reset */ for (auto& entry : serversMap) { entry.second = 0; - BOOST_CHECK_EQUAL(entry.first->weight, 1); + BOOST_CHECK_EQUAL(entry.first->d_config.d_weight, 1); } /* change the weight of the last server to 100, default is 1 */ servers.at(servers.size()-1).second->setWeight(100); @@ -460,12 +470,12 @@ BOOST_AUTO_TEST_CASE(test_whashed) { uint64_t totalW = 0; for (const auto& entry : serversMap) { total += entry.second; - totalW += entry.first->weight; + totalW += entry.first->d_config.d_weight; } BOOST_CHECK_EQUAL(total, names.size()); auto last = servers.at(servers.size()-1).second; const auto got = serversMap[last]; - float expected = (names.size() * 1.0 * last->weight) / totalW; + float expected = (names.size() * 1.0 * last->d_config.d_weight) / totalW; BOOST_CHECK_GT(got, expected / 2); BOOST_CHECK_LT(got, expected * 2); } @@ -514,7 +524,7 @@ BOOST_AUTO_TEST_CASE(test_chashed) { /* reset */ for (auto& entry : serversMap) { entry.second = 0; - BOOST_CHECK_EQUAL(entry.first->weight, 1000); + BOOST_CHECK_EQUAL(entry.first->d_config.d_weight, 1000); } /* request 1000 times the same name, we should go to the same server every time */ @@ -529,7 +539,7 @@ BOOST_AUTO_TEST_CASE(test_chashed) { /* reset */ for (auto& entry : serversMap) { entry.second = 0; - BOOST_CHECK_EQUAL(entry.first->weight, 1000); + BOOST_CHECK_EQUAL(entry.first->d_config.d_weight, 1000); } /* change the weight of the last server to 100000, others stay at 1000 */ servers.at(servers.size()-1).second->setWeight(100000); @@ -545,12 +555,12 @@ BOOST_AUTO_TEST_CASE(test_chashed) { uint64_t totalW = 0; for (const auto& entry : serversMap) { total += entry.second; - totalW += entry.first->weight; + totalW += entry.first->d_config.d_weight; } BOOST_CHECK_EQUAL(total, names.size()); auto last = servers.at(servers.size()-1).second; const auto got = serversMap[last]; - float expected = (names.size() * 1.0 * last->weight) / totalW; + float expected = (names.size() * 1.0 * last->d_config.d_weight) / totalW; BOOST_CHECK_GT(got, expected / 2); BOOST_CHECK_LT(got, expected * 2); diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc index 87f79286b9..8e1bd912c7 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc @@ -724,9 +724,9 @@ BOOST_FIXTURE_TEST_CASE(test_SingleQuery, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; auto sender = std::make_shared(); sender->d_id = counter; @@ -781,9 +781,9 @@ BOOST_FIXTURE_TEST_CASE(test_ConcurrentQueries, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -870,9 +870,9 @@ BOOST_FIXTURE_TEST_CASE(test_ConnectionReuse, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -999,9 +999,9 @@ BOOST_FIXTURE_TEST_CASE(test_InvalidDNSAnswer, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; auto sender = std::make_shared(); sender->d_id = counter; @@ -1059,9 +1059,9 @@ BOOST_FIXTURE_TEST_CASE(test_TimeoutWhileWriting, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -1121,7 +1121,7 @@ BOOST_FIXTURE_TEST_CASE(test_TimeoutWhileWriting, TestFixture) } struct timeval later = now; - later.tv_sec += backend->tcpSendTimeout + 1; + later.tv_sec += backend->d_config.tcpSendTimeout + 1; auto expiredConns = handleH2Timeouts(*s_mplexer, later); BOOST_CHECK_EQUAL(expiredConns, 1U); @@ -1146,9 +1146,9 @@ BOOST_FIXTURE_TEST_CASE(test_TimeoutWhileReading, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -1209,7 +1209,7 @@ BOOST_FIXTURE_TEST_CASE(test_TimeoutWhileReading, TestFixture) } struct timeval later = now; - later.tv_sec += backend->tcpRecvTimeout + 1; + later.tv_sec += backend->d_config.tcpRecvTimeout + 1; auto expiredConns = handleH2Timeouts(*s_mplexer, later); BOOST_CHECK_EQUAL(expiredConns, 1U); @@ -1233,9 +1233,9 @@ BOOST_FIXTURE_TEST_CASE(test_ShortWrite, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -1320,9 +1320,9 @@ BOOST_FIXTURE_TEST_CASE(test_ShortRead, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -1414,9 +1414,9 @@ BOOST_FIXTURE_TEST_CASE(test_ConnectionClosedWhileReading, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -1500,9 +1500,9 @@ BOOST_FIXTURE_TEST_CASE(test_ConnectionClosedWhileWriting, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -1594,11 +1594,11 @@ BOOST_FIXTURE_TEST_CASE(test_GoAwayFromServer, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; /* set the number of reconnection attempts to a low value to not waste time */ - backend->d_retries = 1; + backend->d_config.d_retries = 1; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -1705,9 +1705,9 @@ BOOST_FIXTURE_TEST_CASE(test_HTTP500FromServer, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -1798,9 +1798,9 @@ BOOST_FIXTURE_TEST_CASE(test_WrongStreamID, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; @@ -1873,7 +1873,7 @@ BOOST_FIXTURE_TEST_CASE(test_WrongStreamID, TestFixture) } struct timeval later = now; - later.tv_sec += backend->tcpRecvTimeout + 1; + later.tv_sec += backend->d_config.tcpRecvTimeout + 1; auto expiredConns = handleH2Timeouts(*s_mplexer, later); BOOST_CHECK_EQUAL(expiredConns, 1U); @@ -1899,10 +1899,10 @@ BOOST_FIXTURE_TEST_CASE(test_ProxyProtocol, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; - backend->d_tlsSubjectName = "backend.powerdns.com"; - backend->d_dohPath = "/dns-query"; - backend->d_addXForwardedHeaders = true; - backend->useProxyProtocol = true; + backend->d_config.d_tlsSubjectName = "backend.powerdns.com"; + backend->d_config.d_dohPath = "/dns-query"; + backend->d_config.d_addXForwardedHeaders = true; + backend->d_config.useProxyProtocol = true; size_t numberOfQueries = 2; std::vector, InternalQuery>> queries; diff --git a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc index 9198955bfe..9f24135848 100644 --- a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc +++ b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc @@ -1265,7 +1265,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); IncomingTCPConnectionState::handleIO(state, now); struct timeval later = now; - later.tv_sec += backend->tcpSendTimeout + 1; + later.tv_sec += backend->d_config.tcpSendTimeout + 1; auto expiredWriteConns = threadData.mplexer->getTimeouts(later, true); BOOST_CHECK_EQUAL(expiredWriteConns.size(), 1U); for (const auto& cbData : expiredWriteConns) { @@ -1311,7 +1311,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); IncomingTCPConnectionState::handleIO(state, now); struct timeval later = now; - later.tv_sec += backend->tcpRecvTimeout + 1; + later.tv_sec += backend->d_config.tcpRecvTimeout + 1; auto expiredConns = threadData.mplexer->getTimeouts(later, false); BOOST_CHECK_EQUAL(expiredConns.size(), 1U); for (const auto& cbData : expiredConns) { @@ -1535,7 +1535,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); IncomingTCPConnectionState::handleIO(state, now); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); - BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size() * backend->d_retries); + BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size() * backend->d_config.d_retries); BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ @@ -1596,7 +1596,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) IncomingTCPConnectionState::handleIO(state, now); BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size()); BOOST_CHECK(s_writeBuffer == query); - BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size() * backend->d_retries); + BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size() * backend->d_config.d_retries); BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ @@ -1725,9 +1725,9 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; /* enable out-of-order on the backend side as well */ - backend->d_maxInFlightQueriesPerConn = 65536; + backend->d_config.d_maxInFlightQueriesPerConn = 65536; /* shorter than the client one */ - backend->tcpRecvTimeout = 1; + backend->d_config.tcpRecvTimeout = 1; TCPClientThreadData threadData; threadData.mplexer = std::make_unique(); @@ -2024,7 +2024,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) } struct timeval later = now; - later.tv_sec += backend->tcpRecvTimeout + 1; + later.tv_sec += backend->d_config.tcpRecvTimeout + 1; auto expiredConns = threadData.mplexer->getTimeouts(later, false); BOOST_CHECK_EQUAL(expiredConns.size(), 1U); for (const auto& cbData : expiredConns) { @@ -2279,7 +2279,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) } struct timeval later = now; - later.tv_sec += backend->tcpRecvTimeout + 1; + later.tv_sec += backend->d_config.tcpRecvTimeout + 1; auto expiredConns = threadData.mplexer->getTimeouts(later, false); BOOST_CHECK_EQUAL(expiredConns.size(), 1U); for (const auto& cbData : expiredConns) { @@ -2395,7 +2395,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) appendPayloadEditingID(expectedWriteBuffer, responses.at(4), 4); /* make sure that the backend's timeout is longer than the client's */ - backend->tcpRecvTimeout = 30; + backend->d_config.tcpRecvTimeout = 30; bool timeout = false; int backendDescriptor = -1; @@ -3127,8 +3127,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) auto proxyEnabledBackend = std::make_shared(getBackendAddress("42", 53)); proxyEnabledBackend->d_tlsCtx = tlsCtx; /* enable out-of-order on the backend side as well */ - proxyEnabledBackend->d_maxInFlightQueriesPerConn = 65536; - proxyEnabledBackend->useProxyProtocol = true; + proxyEnabledBackend->d_config.d_maxInFlightQueriesPerConn = 65536; + proxyEnabledBackend->d_config.useProxyProtocol = true; expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), proxyPayload.begin(), proxyPayload.end()); appendPayloadEditingID(expectedBackendWriteBuffer, queries.at(0), 0); @@ -3254,8 +3254,8 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) auto proxyEnabledBackend = std::make_shared(getBackendAddress("42", 53)); proxyEnabledBackend->d_tlsCtx = tlsCtx; /* enable out-of-order on the backend side as well */ - proxyEnabledBackend->d_maxInFlightQueriesPerConn = 65536; - proxyEnabledBackend->useProxyProtocol = true; + proxyEnabledBackend->d_config.d_maxInFlightQueriesPerConn = 65536; + proxyEnabledBackend->d_config.useProxyProtocol = true; expectedBackendWriteBuffer.insert(expectedBackendWriteBuffer.end(), proxyPayload.begin(), proxyPayload.end()); appendPayloadEditingID(expectedBackendWriteBuffer, queries.at(0), 0); @@ -3334,7 +3334,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) s_readBuffer.insert(s_readBuffer.end(), queries.at(2).begin(), queries.at(2).end()); /* make sure that the backend's timeout is shorter than the client's */ - backend->tcpConnectTimeout = 1; + backend->d_config.tcpConnectTimeout = 1; g_tcpRecvTimeout = 5; bool timeout = false; @@ -3378,7 +3378,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) } struct timeval later = now; - later.tv_sec += backend->tcpConnectTimeout + 1; + later.tv_sec += backend->d_config.tcpConnectTimeout + 1; auto expiredConns = threadData.mplexer->getTimeouts(later, true); BOOST_CHECK_EQUAL(expiredConns.size(), 1U); for (const auto& cbData : expiredConns) { @@ -3393,7 +3393,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* restore */ - backend->tcpSendTimeout = 30; + backend->d_config.tcpSendTimeout = 30; g_tcpRecvTimeout = 2; /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ @@ -3436,7 +3436,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) auto backend1 = std::make_shared(getBackendAddress("42", 53)); backend1->d_tlsCtx = tlsCtx; /* only two queries in flight! */ - backend1->d_maxInFlightQueriesPerConn = 2; + backend1->d_config.d_maxInFlightQueriesPerConn = 2; int backend1Desc = -1; int backend2Desc = -1; @@ -3688,7 +3688,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendNotOOOR) auto backend = std::make_shared(getBackendAddress("42", 53)); backend->d_tlsCtx = tlsCtx; /* shorter than the client one */ - backend->tcpRecvTimeout = 1; + backend->d_config.tcpRecvTimeout = 1; TCPClientThreadData threadData; threadData.mplexer = std::make_unique();