while (true) {
bool shouldWait = true;
int timeout = -1;
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
{
auto content = data->d_content.lock();
if (data->d_done) {
try {
uint8_t consecutiveFailures = 0;
do {
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
DTime dtimer;
dtimer.set();
if (doOneCarbonExport(endpoint)) {
static ImmutableConfiguration s_immutableConfiguration;
static std::atomic<bool> s_immutableConfigurationDone{false};
-const RuntimeConfiguration& getCurrentRuntimeConfiguration()
+static const RuntimeConfiguration& getCurrentRuntimeConfigurationInternal(bool refresh)
{
static thread_local auto t_threadLocalConfiguration = s_currentRuntimeConfiguration.getLocal();
- return *t_threadLocalConfiguration;
+ return t_threadLocalConfiguration.get(!refresh);
+}
+
+const RuntimeConfiguration& getCurrentRuntimeConfiguration()
+{
+ return getCurrentRuntimeConfigurationInternal(false);
+}
+
+const RuntimeConfiguration& refreshLocalRuntimeConfiguration()
+{
+ return getCurrentRuntimeConfigurationInternal(true);
}
void updateRuntimeConfiguration(const std::function<void(RuntimeConfiguration&)>& mutator)
{
s_currentRuntimeConfiguration.modify(mutator);
+ /* refresh the local "cache" right away */
+ refreshLocalRuntimeConfiguration();
}
void updateImmutableConfiguration(const std::function<void(ImmutableConfiguration&)>& mutator)
};
/* Be careful not to hold on this for too long, it can be invalidated
- by the next call to getCurrentRuntimeConfiguration() from the
+ by the next call to refreshLocalRuntimeConfiguration() from the
same thread, so better be sure that any function you are not calling
- while holding to this reference does not call getCurrentRuntimeConfiguration()
+ while holding to this reference does not call refreshLocalRuntimeConfiguration
itself. When in doubt, better call getCurrentRuntimeConfiguration() twice.
*/
const RuntimeConfiguration& getCurrentRuntimeConfiguration();
+const RuntimeConfiguration& refreshLocalRuntimeConfiguration();
+
/* Get the runtime-immutable configuration */
const ImmutableConfiguration& getImmutableConfiguration();
/* Update the runtime-immutable part of the configuration. This function can only be called
line = dnsdist::crypto::authenticated::decryptSym(line, consoleKey, readingNonce);
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
string response;
try {
bool withReturn = true;
infolog("Accepting control connections on %s", local.toStringWithPort());
while ((sock = SAccept(acceptFD.getHandle(), client)) >= 0) {
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
const auto& consoleKey = dnsdist::configuration::getCurrentRuntimeConfiguration().d_consoleKey;
FDWrapper socket(sock);
if (!dnsdist::crypto::authenticated::isValidKey(consoleKey)) {
{
setThreadName("dnsdist/discove");
while (true) {
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
time_t now = time(nullptr);
auto upgradeables = *(s_upgradeableBackends.lock());
return;
}
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
data.d_running = true;
if (data.d_sockets.empty()) {
throw runtime_error("NetworkListener started with no sockets");
for (;;) {
try {
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
context.executeCode(code);
errlog("Lua thread exited, restarting in 5 seconds");
}
for (;;) {
data.mplexer->run(&now, 1000);
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
if (now.tv_sec > lastTimeoutScan) {
lastTimeoutScan = now.tv_sec;
#include "dnsdist-resolver.hh"
#include "iputils.hh"
+#include "threadname.hh"
namespace dnsdist::resolver
{
void asynchronousResolver(const std::string& hostname, const std::function<void(const std::string& hostname, std::vector<ComboAddress>& ips)>& callback)
{
+ setThreadName("dnsdist/resolve");
addrinfo hints{};
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_ADDRCONFIG;
bool removeRecordsAndSetRCode(DNSQuestion& dnsQuestion, uint8_t rcode)
{
auto [hadEDNS, dnssecOK] = getEDNSStatusInQuery(dnsQuestion);
-
dnsdist::PacketMangling::editDNSHeaderFromPacket(dnsQuestion.getMutableData(), [rcode](dnsheader& header) {
header.rcode = rcode;
header.qr = true;
for (;;) {
data.mplexer->run(&now);
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
try {
t_downstreamTCPConnectionsManager.cleanupClosedConnections(now);
dnsdist::IncomingConcurrentTCPConnectionsManager::cleanup(time(nullptr));
timeval now{};
while (true) {
mplexer->run(&now, -1);
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
}
}
}
try {
ComboAddress remote(listeningAddress);
int fileDesc = SAccept(sock.getHandle(), remote);
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
if (!isClientAllowedByACL(remote)) {
vinfolog("Connection to webserver from client %s is not allowed, closing", remote.toStringWithPort());
auto pollfds = getPollFdsForWorker(*xskInfo);
while (!dss->isStopped()) {
poll(pollfds.data(), pollfds.size(), -1);
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
bool needNotify = false;
if ((pollfds[0].revents & POLLIN) != 0) {
needNotify = true;
while (true) {
try {
auto ready = xsk->wait(-1);
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
// descriptor 0 gets incoming AF_XDP packets
if ((fds.at(0).revents & POLLIN) != 0) {
auto packets = xsk->recv(64, &failed);
while (!xskInfo->hasIncomingFrames()) {
xskInfo->waitForXskSocket();
}
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
xskInfo->processIncomingFrames([&](XskPacket packet) {
if (XskProcessQuery(*clientState, packet)) {
packet.updatePacket();
static void handleResponseTC4UDPClient(DNSQuestion& dnsQuestion, uint16_t udpPayloadSize, PacketBuffer& response)
{
- if (udpPayloadSize > 0 && response.size() > udpPayloadSize) {
+ if (udpPayloadSize != 0 && response.size() > udpPayloadSize) {
vinfolog("Got a response of size %d while the initial UDP payload size was %d, truncating", response.size(), udpPayloadSize);
truncateTC(dnsQuestion.getMutableData(), dnsQuestion.getMaximumSize(), dnsQuestion.ids.qname.wirelength(), dnsdist::configuration::getCurrentRuntimeConfiguration().d_addEDNSToSelfGeneratedResponses);
dnsdist::PacketMangling::editDNSHeaderFromPacket(dnsQuestion.getMutableData(), [](dnsheader& header) {
return true;
});
}
- else if (dnsQuestion.getHeader()->tc && dnsdist::configuration::getCurrentRuntimeConfiguration().d_truncateTC) {
+ else if (dnsdist::configuration::getCurrentRuntimeConfiguration().d_truncateTC && dnsQuestion.getHeader()->tc) {
truncateTC(response, dnsQuestion.getMaximumSize(), dnsQuestion.ids.qname.wirelength(), dnsdist::configuration::getCurrentRuntimeConfiguration().d_addEDNSToSelfGeneratedResponses);
}
}
break;
}
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
for (const auto& sockDesc : sockets) {
/* allocate one more byte so we can detect truncation */
// NOLINTNEXTLINE(bugprone-use-after-move): resizing a vector has no preconditions so it is valid to do so after moving it
packet.resize(static_cast<size_t>(got));
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
processUDPQuery(*param.cs, &msgh, remote, dest, packet, nullptr, nullptr, nullptr, nullptr);
};
for (;;) {
std::this_thread::sleep_for(std::chrono::seconds(interval));
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
{
auto lua = g_lua.lock();
try {
{
setThreadName("dnsdist/dynBloc");
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
DynBlockMaintenance::run();
}
#endif
setThreadName("dnsdist/secpoll");
for (;;) {
- const auto& runtimeConfig = dnsdist::configuration::getCurrentRuntimeConfiguration();
+ const auto& runtimeConfig = dnsdist::configuration::refreshLocalRuntimeConfiguration();
try {
dnsdist::secpoll::doSecPoll(runtimeConfig.d_secPollSuffix);
}
std::unique_ptr<FDMultiplexer> mplexer{nullptr};
+ const auto& runtimeConfig = dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
// this points to the actual shared_ptrs!
// coverity[auto_causes_copy]
- const auto servers = dnsdist::configuration::getCurrentRuntimeConfiguration().d_backends;
+ const auto servers = runtimeConfig.d_backends;
for (const auto& dss : servers) {
dss->updateStatisticsInfo();
static void setupPools()
{
bool precompute = false;
- if (dnsdist::configuration::getCurrentRuntimeConfiguration().d_lbPolicy->getName() == "chashed") {
+ const auto& currentConfig = dnsdist::configuration::getCurrentRuntimeConfiguration();
+ if (currentConfig.d_lbPolicy->getName() == "chashed") {
precompute = true;
}
else {
- for (const auto& entry : dnsdist::configuration::getCurrentRuntimeConfiguration().d_pools) {
+ for (const auto& entry : currentConfig.d_pools) {
if (entry.second->policy != nullptr && entry.second->policy->getName() == "chashed") {
precompute = true;
break;
if (precompute) {
vinfolog("Pre-computing hashes for consistent hash load-balancing policy");
// pre compute hashes
- for (const auto& backend : dnsdist::configuration::getCurrentRuntimeConfiguration().d_backends) {
+ for (const auto& backend : currentConfig.d_backends) {
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);
}
if (clientState->dohFrontend != nullptr && clientState->dohFrontend->d_library == "h2o") {
#ifdef HAVE_DNS_OVER_HTTPS
#ifdef HAVE_LIBH2OEVLOOP
- std::thread dotThreadHandle(dohThread, clientState.get());
+ std::thread dohThreadHandle(dohThread, clientState.get());
if (!clientState->cpus.empty()) {
- mapThreadToCPUList(dotThreadHandle.native_handle(), clientState->cpus);
+ mapThreadToCPUList(dohThreadHandle.native_handle(), clientState->cpus);
}
- dotThreadHandle.detach();
+ dohThreadHandle.detach();
#endif /* HAVE_LIBH2OEVLOOP */
#endif /* HAVE_DNS_OVER_HTTPS */
continue;
}
};
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
auto& ids = unit->ids;
uint16_t queryId = 0;
ComboAddress remote;
*/
static int doh_handler(h2o_handler_t *self, h2o_req_t *req)
{
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
try {
if (req->conn->ctx->storage.size == 0) {
return 0; // although we might was well crash on this
readyFDs.clear();
mplexer->getAvailableFDs(readyFDs, 500);
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
try {
if (std::find(readyFDs.begin(), readyFDs.end(), sock.getHandle()) != readyFDs.end()) {
handleSocketReadable(*frontend, *clientState, sock, buffer);
readyFDs.clear();
mplexer->getAvailableFDs(readyFDs, 500);
+ dnsdist::configuration::refreshLocalRuntimeConfiguration();
+
try {
if (std::find(readyFDs.begin(), readyFDs.end(), sock.getHandle()) != readyFDs.end()) {
handleSocketReadable(*frontend, *clientState, sock, buffer);
return *operator->();
}
+ // fast const-only access, see "read-only" above.
+ // if allowedOutdated is true, the current local version is returned
+ // without checking if there has been an update.
+ const T& get(bool allowedOutdated = false)
+ {
+ if (!allowedOutdated || !d_state) {
+ return *operator->();
+ }
+ return *d_state;
+ }
+
void reset()
{
d_generation = 0;