luaCtx.writeFunction("requestDoHStatesDump", [] {
setLuaNoSideEffect();
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
g_dohStatesDumpRequested += g_dohClientThreads->getThreadsCount();
+#endif
});
luaCtx.writeFunction("dumpStats", [] {
tlsCtx = getTLSContext(config.d_tlsParams);
if (getOptionalValue<std::string>(vars, "dohPath", valueStr) > 0) {
-#ifndef HAVE_NGHTTP2
+#if !defined(HAVE_DNS_OVER_HTTPS) || !defined(HAVE_NGHTTP2)
throw std::runtime_error("Outgoing DNS over HTTPS support requested (via 'dohPath' on newServer()) but nghttp2 support is not available");
#endif
setTCPDownstreamMaxIdleConnectionsPerBackend(max);
});
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
luaCtx.writeFunction("setMaxIdleDoHConnectionsPerDownstream", [](uint64_t max) {
setDoHDownstreamMaxIdleConnectionsPerBackend(max);
});
}
g_outgoingDoHWorkerThreads = workers;
});
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
luaCtx.writeFunction("setOutgoingTLSSessionsCacheMaxTicketsPerBackend", [](uint64_t max) {
if (!checkConfigurationTime("setOutgoingTLSSessionsCacheMaxTicketsPerBackend")) {
setTCPDownstreamCleanupInterval(interval);
});
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
luaCtx.writeFunction("setDoHDownstreamCleanupInterval", [](uint64_t interval) {
setLuaSideEffect();
checkParameterBound("setDoHDownstreamCleanupInterval", interval);
setDoHDownstreamCleanupInterval(interval);
});
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
luaCtx.writeFunction("setTCPDownstreamMaxIdleTime", [](uint64_t max) {
setLuaSideEffect();
setTCPDownstreamMaxIdleTime(max);
});
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
luaCtx.writeFunction("setDoHDownstreamMaxIdleTime", [](uint64_t max) {
setLuaSideEffect();
checkParameterBound("setDoHDownstreamMaxIdleTime", max);
setDoHDownstreamMaxIdleTime(max);
});
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
luaCtx.writeFunction("setConsoleConnectionsLogging", [](bool enabled) {
g_logConsoleConnections = enabled;
gettimeofday(&now, nullptr);
if (citmp->cs->dohFrontend) {
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
auto state = std::make_shared<IncomingHTTP2Connection>(std::move(*citmp), *threadData, now);
state->handleIO();
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
}
else {
auto state = std::make_shared<IncomingTCPConnectionState>(std::move(*citmp), *threadData, now);
state->handleTimeout(state, false);
}
}
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
else if (cbData.second.type() == typeid(std::shared_ptr<IncomingHTTP2Connection>)) {
auto state = boost::any_cast<std::shared_ptr<IncomingHTTP2Connection>>(cbData.second);
if (cbData.first == state->d_handler.getDescriptor()) {
state->handleTimeout(parentState, false);
}
}
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
else if (cbData.second.type() == typeid(std::shared_ptr<TCPConnectionToBackend>)) {
auto conn = boost::any_cast<std::shared_ptr<TCPConnectionToBackend>>(cbData.second);
vinfolog("Timeout (read) from remote backend %s", conn->getBackendName());
state->handleTimeout(state, true);
}
}
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
else if (cbData.second.type() == typeid(std::shared_ptr<IncomingHTTP2Connection>)) {
auto state = boost::any_cast<std::shared_ptr<IncomingHTTP2Connection>>(cbData.second);
if (cbData.first == state->d_handler.getDescriptor()) {
state->handleTimeout(parentState, true);
}
}
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
else if (cbData.second.type() == typeid(std::shared_ptr<TCPConnectionToBackend>)) {
auto conn = boost::any_cast<std::shared_ptr<TCPConnectionToBackend>>(cbData.second);
vinfolog("Timeout (write) from remote backend %s", conn->getBackendName());
auto state = boost::any_cast<std::shared_ptr<IncomingTCPConnectionState>>(param);
infolog(" - %s", state->toString());
}
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
else if (param.type() == typeid(std::shared_ptr<IncomingHTTP2Connection>)) {
auto state = boost::any_cast<std::shared_ptr<IncomingHTTP2Connection>>(param);
infolog(" - %s", state->toString());
}
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
else if (param.type() == typeid(std::shared_ptr<TCPConnectionToBackend>)) {
auto conn = boost::any_cast<std::shared_ptr<TCPConnectionToBackend>>(param);
infolog(" - %s", conn->toString());
gettimeofday(&now, nullptr);
if (ci.cs->dohFrontend) {
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
auto state = std::make_shared<IncomingHTTP2Connection>(std::move(ci), *threadData, now);
state->handleIO();
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
}
else {
auto state = std::make_shared<IncomingTCPConnectionState>(std::move(ci), *threadData, now);
g_tcpclientthreads = std::make_unique<TCPClientCollection>(*g_maxTCPClientThreads, std::vector<ClientState*>());
#endif
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
initDoHWorkers();
+#endif
for (auto& todoItem : todo) {
todoItem();
dnsdist-lua.cc dnsdist-lua.hh \
dnsdist-mac-address.cc dnsdist-mac-address.hh \
dnsdist-metrics.cc dnsdist-metrics.hh \
- dnsdist-nghttp2-in.cc dnsdist-nghttp2-in.hh \
- dnsdist-nghttp2.cc dnsdist-nghttp2.hh \
+ dnsdist-nghttp2-in.hh \
+ dnsdist-nghttp2.hh \
dnsdist-prometheus.hh \
dnsdist-protobuf.cc dnsdist-protobuf.hh \
dnsdist-protocols.cc dnsdist-protocols.hh \
dnsdist-lua-vars.cc \
dnsdist-mac-address.cc dnsdist-mac-address.hh \
dnsdist-metrics.cc dnsdist-metrics.hh \
- dnsdist-nghttp2-in.cc dnsdist-nghttp2-in.hh \
- dnsdist-nghttp2.cc dnsdist-nghttp2.hh \
+ dnsdist-nghttp2-in.hh \
+ dnsdist-nghttp2.hh \
dnsdist-protocols.cc dnsdist-protocols.hh \
dnsdist-proxy-protocol.cc dnsdist-proxy-protocol.hh \
dnsdist-random.cc dnsdist-random.hh \
test-dnsdistkvs_cc.cc \
test-dnsdistlbpolicies_cc.cc \
test-dnsdistluanetwork.cc \
- test-dnsdistnghttp2-in_cc.cc \
- test-dnsdistnghttp2_cc.cc \
test-dnsdistnghttp2_common.hh \
test-dnsdistpacketcache_cc.cc \
test-dnsdistrings_cc.cc \
dnsdist_LDADD += $(LIBH2OEVLOOP_LIBS)
endif
+if HAVE_NGHTTP2
+dnsdist_SOURCES += dnsdist-nghttp2-in.cc
+dnsdist_SOURCES += dnsdist-nghttp2.cc
+testrunner_SOURCES += dnsdist-nghttp2-in.cc
+testrunner_SOURCES += dnsdist-nghttp2.cc
+testrunner_SOURCES += test-dnsdistnghttp2-in_cc.cc \
+ test-dnsdistnghttp2_cc.cc
+dnsdist_LDADD += $(NGHTTP2_LDFLAGS) $(NGHTTP2_LIBS)
+testrunner_LDADD += $(NGHTTP2_LDFLAGS) $(NGHTTP2_LIBS)
+endif
+
endif
if HAVE_DNS_OVER_QUIC
endif
endif
-if HAVE_NGHTTP2
-dnsdist_LDADD += $(NGHTTP2_LDFLAGS) $(NGHTTP2_LIBS)
-testrunner_LDADD += $(NGHTTP2_LDFLAGS) $(NGHTTP2_LIBS)
-endif
-
if !HAVE_LUA_HPP
BUILT_SOURCES += lua.hpp
nodist_dnsdist_SOURCES = lua.hpp
])
])
-PDNS_WITH_NGHTTP2
DNSDIST_WITH_CDB
PDNS_CHECK_LMDB
PDNS_ENABLE_IPCIPHER
bool DownstreamState::passCrossProtocolQuery(std::unique_ptr<CrossProtocolQuery>&& cpq)
{
- if (d_config.d_dohPath.empty()) {
- return g_tcpclientthreads && g_tcpclientthreads->passCrossProtocolQueryToThread(std::move(cpq));
- }
- else {
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
+ if (!d_config.d_dohPath.empty()) {
return g_dohClientThreads && g_dohClientThreads->passCrossProtocolQueryToThread(std::move(cpq));
}
+#endif
+ return g_tcpclientthreads && g_tcpclientthreads->passCrossProtocolQueryToThread(std::move(cpq));
}
bool DownstreamState::reconnect(bool initialAttempt)
mplexer->addReadFD(data->d_udpSocket.getHandle(), &healthCheckUDPCallback, data, &data->d_ttd);
}
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
else if (downstream->isDoH()) {
InternalQuery query(std::move(packet), InternalQueryState());
query.d_proxyProtocolPayload = std::move(proxyProtocolPayload);
data->d_ds->submitHealthCheckResult(data->d_initial, false);
}
}
+#endif
else {
data->d_tcpHandler = std::make_unique<TCPIOHandler>(downstream->d_config.d_tlsSubjectName, downstream->d_config.d_tlsSubjectIsAddr, sock.releaseHandle(), timeval{downstream->d_config.checkTimeout, 0}, downstream->d_tlsCtx);
data->d_ioState = std::make_unique<IOStateHandler>(*mplexer, data->d_tcpHandler->getDescriptor());
continue;
}
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
handleH2Timeouts(mplexer, now);
+#endif
auto timeouts = mplexer.getTimeouts(now);
for (const auto& timeout : timeouts) {
#include "dnsdist-proxy-protocol.hh"
#include "dnsparser.hh"
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
#if 0
class IncomingDoHCrossProtocolContext : public CrossProtocolContext
return !d_connectionDied && d_ioState != nullptr;
}
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
#pragma once
#include "config.h"
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
#include <nghttp2/nghttp2.h>
#include "dnsdist-tcp-upstream.hh"
static void addCustomDynamicHeader(std::vector<nghttp2_nv>& headers, const std::string& name, const std::string_view& value);
};
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
#include "config.h"
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
#include <nghttp2/nghttp2.h>
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
#include "dnsdist-nghttp2.hh"
#include "dnsdist-nghttp2-in.hh"
std::unique_ptr<DoHClientCollection> g_dohClientThreads{nullptr};
std::optional<uint16_t> g_outgoingDoHWorkerThreads{std::nullopt};
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
class DoHConnectionToBackend : public ConnectionToBackend
{
public:
return true;
}
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
struct DoHClientCollection::DoHWorkerThread
{
void DoHClientCollection::addThread()
{
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
try {
auto [sender, receiver] = pdns::channel::createObjectQueue<CrossProtocolQuery>(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, g_tcpInternalPipeBufferSize);
errlog("Error creating the DoH channel: %s", e.what());
return;
}
-#else /* HAVE_NGHTTP2 */
+#else /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
throw std::runtime_error("DoHClientCollection::addThread() called but nghttp2 support is not available");
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
}
bool initDoHWorkers()
{
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
if (!g_outgoingDoHWorkerThreads) {
/* Unless the value has been set to 0 explicitly, always start at least one outgoing DoH worker thread, in case a DoH backend
is added at a later time. */
return true;
#else
return false;
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
}
bool setupDoHClientProtocolNegotiation(std::shared_ptr<TLSCtx>& ctx)
if (ctx == nullptr) {
return false;
}
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
/* we want to set the ALPN to h2, if only to mitigate the ALPACA attack */
const std::vector<std::vector<uint8_t>> h2Alpns = {{'h', '2'}};
ctx->setALPNProtos(h2Alpns);
ctx->setNextProtocolSelectCallback(select_next_proto_callback);
return true;
-#else /* HAVE_NGHTTP2 */
+#else /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
return false;
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
}
bool sendH2Query(const std::shared_ptr<DownstreamState>& ds, std::unique_ptr<FDMultiplexer>& mplexer, std::shared_ptr<TCPQuerySender>& sender, InternalQuery&& query, bool healthCheck)
{
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
struct timeval now
{
.tv_sec = 0, .tv_usec = 0
}
return true;
-#else /* HAVE_NGHTTP2 */
+#else /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
return false;
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
}
size_t clearH2Connections()
{
size_t cleared = 0;
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
cleared = t_downstreamDoHConnectionsManager.clear();
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
return cleared;
}
size_t handleH2Timeouts(FDMultiplexer& mplexer, const struct timeval& now)
{
size_t got = 0;
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
auto expiredReadConns = mplexer.getTimeouts(now, false);
for (const auto& cbData : expiredReadConns) {
if (cbData.second.type() == typeid(std::shared_ptr<DoHConnectionToBackend>)) {
++got;
}
}
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
return got;
}
void setDoHDownstreamCleanupInterval(uint16_t max)
{
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
DownstreamDoHConnectionsManager::setCleanupInterval(max);
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
}
void setDoHDownstreamMaxIdleTime(uint16_t max)
{
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
DownstreamDoHConnectionsManager::setMaxIdleTime(max);
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
}
void setDoHDownstreamMaxIdleConnectionsPerBackend(size_t max)
{
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
DownstreamDoHConnectionsManager::setMaxIdleConnectionsPerDownstream(max);
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
}
#include "dnsdist-proxy-protocol.hh"
#include "dnsdist-nghttp2-in.hh"
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
#include <nghttp2/nghttp2.h>
extern std::function<ProcessQueryResult(DNSQuestion& dnsQuestion, std::shared_ptr<DownstreamState>& selectedBackend)> s_processQuery;
}
BOOST_AUTO_TEST_SUITE_END();
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */
#include "dnsdist-nghttp2.hh"
#include "sstuff.hh"
-#ifdef HAVE_NGHTTP2
+#if defined(HAVE_DNS_OVER_HTTPS) && defined(HAVE_NGHTTP2)
#include <nghttp2/nghttp2.h>
BOOST_AUTO_TEST_SUITE(test_dnsdistnghttp2_cc)
}
BOOST_AUTO_TEST_SUITE_END();
-#endif /* HAVE_NGHTTP2 */
+#endif /* HAVE_DNS_OVER_HTTPS && HAVE_NGHTTP2 */