a RCU-like mechanism */
struct RuntimeConfiguration
{
+ NetmaskGroup d_ACL;
NetmaskGroup d_proxyProtocolACL;
NetmaskGroup d_consoleACL;
dnsdist::QueryCount::Configuration d_queryCountConfig;
luaCtx.writeFunction("getVerbose", []() { return dnsdist::configuration::getCurrentRuntimeConfiguration().d_verbose; });
- luaCtx.writeFunction("addACL", [](const std::string& domain) {
+ luaCtx.writeFunction("addACL", [](const std::string& mask) {
setLuaSideEffect();
- g_ACL.modify([domain](NetmaskGroup& nmg) { nmg.addMask(domain); });
+ dnsdist::configuration::updateRuntimeConfiguration([&mask](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_ACL.addMask(mask);
+ });
});
luaCtx.writeFunction("rmACL", [](const std::string& netmask) {
setLuaSideEffect();
- g_ACL.modify([netmask](NetmaskGroup& nmg) { nmg.deleteMask(netmask); });
+ dnsdist::configuration::updateRuntimeConfiguration([&netmask](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_ACL.deleteMask(netmask);
+ });
});
luaCtx.writeFunction("setLocal", [client](const std::string& addr, boost::optional<localbind_t> vars) {
nmg.addMask(entry.second);
}
}
- g_ACL.setState(nmg);
+ dnsdist::configuration::updateRuntimeConfiguration([&nmg](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_ACL = std::move(nmg);
+ });
});
luaCtx.writeFunction("setACLFromFile", [](const std::string& file) {
nmg.addMask(line);
}
- g_ACL.setState(nmg);
+ dnsdist::configuration::updateRuntimeConfiguration([&nmg](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_ACL = std::move(nmg);
+ });
});
luaCtx.writeFunction("showACL", []() {
setLuaNoSideEffect();
- auto aclEntries = g_ACL.getLocal()->toStringVector();
+ auto aclEntries = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.toStringVector();
for (const auto& entry : aclEntries) {
g_outputBuffer += entry + "\n";
processForwardedForHeader(query.d_headers, d_proxiedRemote);
/* second ACL lookup based on the updated address */
- auto& holders = d_threadData.holders;
- if (!holders.acl->match(d_proxiedRemote)) {
+ if (!dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.match(d_proxiedRemote)) {
++dnsdist::metrics::g_stats.aclDrops;
vinfolog("Query from %s (%s) (DoH) dropped because of ACL", d_ci.remote.toStringWithPort(), d_proxiedRemote.toStringWithPort());
handleImmediateResponse(403, "DoH query not allowed because of ACL");
else {
/* proxy header received */
std::vector<ProxyProtocolValue> proxyProtocolValues;
- if (!handleProxyProtocol(d_ci.remote, true, *d_threadData.holders.acl, d_buffer, d_proxiedRemote, d_proxiedDestination, proxyProtocolValues)) {
+ if (!handleProxyProtocol(d_ci.remote, true, dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL, d_buffer, d_proxiedRemote, d_proxiedDestination, proxyProtocolValues)) {
vinfolog("Error handling the Proxy Protocol received from TCP client %s", d_ci.remote.toStringWithPort());
return ProxyProtocolResult::Error;
}
// NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members)
ClientState& clientState;
ComboAddress local;
- // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members)
- LocalStateHolder<NetmaskGroup>& acl;
int socket{-1};
};
data.mplexer->addReadFD(data.crossProtocolResponseReceiver.getDescriptor(), handleCrossProtocolResponse, &data);
/* only used in single acceptor mode for now */
- auto acl = g_ACL.getLocal();
std::vector<TCPAcceptorParam> acceptParams;
acceptParams.reserve(tcpAcceptStates.size());
for (auto& state : tcpAcceptStates) {
- acceptParams.emplace_back(TCPAcceptorParam{*state, state->local, acl, state->tcpFD});
+ acceptParams.emplace_back(TCPAcceptorParam{*state, state->local, state->tcpFD});
for (const auto& [addr, socket] : state->d_additionalAddresses) {
- acceptParams.emplace_back(TCPAcceptorParam{*state, addr, acl, socket});
+ acceptParams.emplace_back(TCPAcceptorParam{*state, addr, socket});
}
}
static void acceptNewConnection(const TCPAcceptorParam& param, TCPClientThreadData* threadData)
{
auto& clientState = param.clientState;
- auto& acl = param.acl;
const bool checkACL = clientState.dohFrontend == nullptr || (!clientState.dohFrontend->d_trustForwardedForHeader && clientState.dohFrontend->d_earlyACLDrop);
const int socket = param.socket;
bool tcpClientCountIncremented = false;
throw std::runtime_error((boost::format("accepting new connection on socket: %s") % stringerror()).str());
}
- if (checkACL && !acl->match(remote)) {
+ if (checkACL && !dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.match(remote)) {
++dnsdist::metrics::g_stats.aclDrops;
vinfolog("Dropped TCP connection from %s because of ACL", remote.toStringWithPort());
return;
{
setThreadName("dnsdist/tcpAcce");
- auto acl = g_ACL.getLocal();
std::vector<TCPAcceptorParam> params;
params.reserve(states.size());
for (const auto& state : states) {
- params.emplace_back(TCPAcceptorParam{*state, state->local, acl, state->tcpFD});
+ params.emplace_back(TCPAcceptorParam{*state, state->local, state->tcpFD});
for (const auto& [addr, socket] : state->d_additionalAddresses) {
- params.emplace_back(TCPAcceptorParam{*state, addr, acl, socket});
+ params.emplace_back(TCPAcceptorParam{*state, addr, socket});
}
}
string acl;
{
- auto aclEntries = g_ACL.getLocal()->toStringVector();
+ auto aclEntries = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.toStringVector();
for (const auto& entry : aclEntries) {
if (!acl.empty()) {
const auto immutableConfig = dnsdist::configuration::getImmutableConfiguration();
using configentry_t = boost::variant<bool, double, std::string>;
std::vector<std::pair<std::string, configentry_t>> configEntries{
- {"acl", g_ACL.getLocal()->toString()},
+ {"acl", runtimeConfiguration.d_ACL.toString()},
{"allow-empty-response", runtimeConfiguration.d_allowEmptyResponse},
{"control-socket", immutableConfig.d_consoleServerAddress.toStringWithPort()},
{"ecs-override", runtimeConfiguration.d_ecsOverride},
if (resp.status == 200) {
infolog("Updating the ACL via the API to %s", nmg.toString());
- g_ACL.setState(nmg);
+ dnsdist::configuration::updateRuntimeConfiguration([&nmg](dnsdist::configuration::RuntimeConfiguration& config) {
+ config.d_ACL = nmg;
+ });
apiSaveACL(nmg);
}
}
}
}
if (resp.status == 200) {
- auto aclEntries = g_ACL.getLocal()->toStringVector();
+ auto aclEntries = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.toStringVector();
Json::object obj{
{"type", "ConfigSetting"},
{
const auto& from = packet.getFromAddr();
expectProxyProtocol = expectProxyProtocolFrom(from);
- if (!holders.acl->match(from) && !expectProxyProtocol) {
+ if (!dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.match(from) && !expectProxyProtocol) {
vinfolog("Query from %s dropped because of ACL", from.toStringWithPort());
++dnsdist::metrics::g_stats.aclDrops;
return false;
using std::thread;
-GlobalStateHolder<NetmaskGroup> g_ACL;
string g_outputBuffer;
std::vector<std::shared_ptr<TLSFrontend>> g_tlslocals;
}
expectProxyProtocol = clientState.d_enableProxyProtocol && expectProxyProtocolFrom(remote);
- if (!holders.acl->match(remote) && !expectProxyProtocol) {
+ if (!dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.match(remote) && !expectProxyProtocol) {
vinfolog("Query from %s dropped because of ACL", remote.toStringWithPort());
++dnsdist::metrics::g_stats.aclDrops;
return false;
}
std::vector<ProxyProtocolValue> proxyProtocolValues;
- if (expectProxyProtocol && !handleProxyProtocol(remote, false, *holders.acl, query, ids.origRemote, ids.origDest, proxyProtocolValues)) {
+ if (expectProxyProtocol && !handleProxyProtocol(remote, false, dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL, query, ids.origRemote, ids.origDest, proxyProtocolValues)) {
return;
}
auto query = packet.clonePacketBuffer();
std::vector<ProxyProtocolValue> proxyProtocolValues;
- if (expectProxyProtocol && !handleProxyProtocol(remote, false, *holders.acl, query, ids.origRemote, ids.origDest, proxyProtocolValues)) {
+ if (expectProxyProtocol && !handleProxyProtocol(remote, false, dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL, query, ids.origRemote, ids.origDest, proxyProtocolValues)) {
return false;
}
break;
case 'a':
optstring = optarg;
- g_ACL.modify([optstring](NetmaskGroup& nmg) { nmg.addMask(optstring); });
+ newConfig.d_ACL.addMask(optstring);
break;
case 'k':
#if defined HAVE_LIBSODIUM || defined(HAVE_LIBCRYPTO)
#endif
}
- auto acl = g_ACL.getCopy();
- if (acl.empty()) {
- for (const auto& addr : {"127.0.0.0/8", "10.0.0.0/8", "100.64.0.0/10", "169.254.0.0/16", "192.168.0.0/16", "172.16.0.0/12", "::1/128", "fc00::/7", "fe80::/10"}) {
- acl.addMask(addr);
+ dnsdist::configuration::updateRuntimeConfiguration([](dnsdist::configuration::RuntimeConfiguration& config) {
+ auto& acl = config.d_ACL;
+ if (acl.empty()) {
+ for (const auto& addr : {"127.0.0.0/8", "10.0.0.0/8", "100.64.0.0/10", "169.254.0.0/16", "192.168.0.0/16", "172.16.0.0/12", "::1/128", "fc00::/7", "fe80::/10"}) {
+ acl.addMask(addr);
+ }
}
- g_ACL.setState(acl);
- }
+ });
dnsdist::configuration::updateRuntimeConfiguration([](dnsdist::configuration::RuntimeConfiguration& config) {
for (const auto& mask : {"127.0.0.1/8", "::1/128"}) {
{
std::string acls;
- auto aclEntries = g_ACL.getLocal()->toStringVector();
+ auto aclEntries = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.toStringVector();
for (const auto& aclEntry : aclEntries) {
if (!acls.empty()) {
acls += ", ";
extern GlobalStateHolder<ServerPolicy> g_policy;
extern GlobalStateHolder<servers_t> g_dstates;
extern GlobalStateHolder<pools_t> g_pools;
-extern GlobalStateHolder<NetmaskGroup> g_ACL;
extern std::vector<shared_ptr<TLSFrontend>> g_tlslocals;
extern std::vector<shared_ptr<DOHFrontend>> g_dohlocals;
struct LocalHolders
{
LocalHolders() :
- acl(g_ACL.getLocal()), policy(g_policy.getLocal()), ruleactions(dnsdist::rules::getRuleChainHolder(dnsdist::rules::RuleChain::Rules).getLocal()), cacheMissRuleActions(dnsdist::rules::getRuleChainHolder(dnsdist::rules::RuleChain::CacheMissRules).getLocal()), cacheHitRespRuleactions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheHitResponseRules).getLocal()), cacheInsertedRespRuleActions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal()), selfAnsweredRespRuleactions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::SelfAnsweredResponseRules).getLocal()), servers(g_dstates.getLocal()), dynNMGBlock(g_dynblockNMG.getLocal()), dynSMTBlock(g_dynblockSMT.getLocal()), pools(g_pools.getLocal())
+ policy(g_policy.getLocal()), ruleactions(dnsdist::rules::getRuleChainHolder(dnsdist::rules::RuleChain::Rules).getLocal()), cacheMissRuleActions(dnsdist::rules::getRuleChainHolder(dnsdist::rules::RuleChain::CacheMissRules).getLocal()), cacheHitRespRuleactions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheHitResponseRules).getLocal()), cacheInsertedRespRuleActions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::CacheInsertedResponseRules).getLocal()), selfAnsweredRespRuleactions(dnsdist::rules::getResponseRuleChainHolder(dnsdist::rules::ResponseRuleChain::SelfAnsweredResponseRules).getLocal()), servers(g_dstates.getLocal()), dynNMGBlock(g_dynblockNMG.getLocal()), dynSMTBlock(g_dynblockSMT.getLocal()), pools(g_pools.getLocal())
{
}
- LocalStateHolder<NetmaskGroup> acl;
LocalStateHolder<ServerPolicy> policy;
LocalStateHolder<vector<dnsdist::rules::RuleAction>> ruleactions;
LocalStateHolder<vector<dnsdist::rules::RuleAction>> cacheMissRuleActions;
}
}
- auto& holders = dsc->holders;
- if (!holders.acl->match(remote)) {
+ if (!dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.match(remote)) {
++dnsdist::metrics::g_stats.aclDrops;
vinfolog("Query from %s (DoH) dropped because of ACL", remote.toStringWithPort());
h2o_send_error_403(req, "Forbidden", "DoH query not allowed because of ACL", 0);
return;
}
- if (dsc->dohFrontend->d_earlyACLDrop && !dsc->dohFrontend->d_trustForwardedForHeader && !dsc->holders.acl->match(remote)) {
+ if (dsc->dohFrontend->d_earlyACLDrop && !dsc->dohFrontend->d_trustForwardedForHeader && !dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.match(remote)) {
++dnsdist::metrics::g_stats.aclDrops;
vinfolog("Dropping DoH connection from %s because of ACL", remote.toStringWithPort());
h2o_socket_close(sock);
auto& holders = dsc->holders;
ClientState& clientState = *dsc->clientState;
- if (!holders.acl->match(remote)) {
+ if (!dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.match(remote)) {
vinfolog("Query from %s (DoH3) dropped because of ACL", remote.toStringWithPort());
++dnsdist::metrics::g_stats.aclDrops;
unit->response.clear();
auto& holders = dsc->holders;
ClientState& clientState = *dsc->clientState;
- if (!holders.acl->match(remote)) {
+ if (!dnsdist::configuration::getCurrentRuntimeConfiguration().d_ACL.match(remote)) {
vinfolog("Query from %s (DoQ) dropped because of ACL", remote.toStringWithPort());
++dnsdist::metrics::g_stats.aclDrops;
unit->response.clear();