From 02fe5e06cad9b84bd02a79df454dfabeccbbc6a5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 26 Nov 2021 12:15:09 +0100 Subject: [PATCH] dnsdist: Reuse and save the TLS session tickets in DoT healthchecks This reduces the cost of the healthchecks themselves while saving the TLS session reduces the cost of opening of a DoT connection for actual queries later on. In the future a refactoring of the TCP/DoT healthcheck code to be more like the "black box" approach used for DoH would be nice to have. --- pdns/dnsdistdist/dnsdist-healthchecks.cc | 28 +++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index ec9ab9902f..c689877d66 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -26,6 +26,7 @@ #include "dolog.hh" #include "dnsdist-tcp.hh" #include "dnsdist-nghttp2.hh" +#include "dnsdist-session-cache.hh" bool g_verboseHealthChecks{false}; @@ -287,6 +288,19 @@ static void healthCheckTCPCallback(int fd, FDMultiplexer::funcparam_t& param) if (ioState == IOState::Done) { /* remove us from the mplexer, we are done */ data->d_ioState->update(ioState, healthCheckTCPCallback, data); + if (data->d_tcpHandler->isTLS()) { + try { + auto sessions = data->d_tcpHandler->getTLSSessions(); + if (!sessions.empty()) { + struct timeval now; + gettimeofday(&now, nullptr); + g_sessionCache.putSessions(data->d_ds->getID(), now.tv_sec, std::move(sessions)); + } + } + catch (const std::exception& e) { + vinfolog("Unable to get a TLS session from the DoT healthcheck: %s", e.what()); + } + } } else { data->d_ioState->update(ioState, healthCheckTCPCallback, data, data->d_ttd); @@ -409,8 +423,20 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared } } else { - data->d_tcpHandler = std::make_unique(ds->d_tlsSubjectName, sock.releaseHandle(), timeval{ds->checkTimeout,0}, ds->d_tlsCtx, time(nullptr)); + 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_ioState = std::make_unique(*mplexer, data->d_tcpHandler->getDescriptor()); + if (ds->d_tlsCtx) { + try { + auto tlsSession = g_sessionCache.getSession(ds->getID(), now); + if (tlsSession) { + data->d_tcpHandler->setTLSSession(tlsSession); + } + } + catch (const std::exception& e) { + vinfolog("Unable to restore a TLS session for the DoT healthcheck: %s", e.what()); + } + } data->d_tcpHandler->tryConnect(ds->tcpFastOpen, ds->remote); const uint8_t sizeBytes[] = { static_cast(packetSize / 256), static_cast(packetSize % 256) }; -- 2.47.2