dnsdist-rings.cc dnsdist-rings.hh \
dnsdist-rules.cc dnsdist-rules.hh \
dnsdist-secpoll.cc dnsdist-secpoll.hh \
+ dnsdist-session-cache.cc dnsdist-session-cache.hh \
dnsdist-snmp.cc dnsdist-snmp.hh \
dnsdist-systemd.cc dnsdist-systemd.hh \
dnsdist-tcp-downstream.cc dnsdist-tcp-downstream.hh \
dnsdist-proxy-protocol.cc dnsdist-proxy-protocol.hh \
dnsdist-rings.cc dnsdist-rings.hh \
dnsdist-rules.cc dnsdist-rules.hh \
+ dnsdist-session-cache.cc dnsdist-session-cache.hh \
dnsdist-tcp-downstream.cc \
dnsdist-tcp.cc dnsdist-tcp.hh \
dnsdist-xpf.cc dnsdist-xpf.hh \
else {
data->d_tcpHandler = std::make_unique<TCPIOHandler>(ds->d_tlsSubjectName, sock.releaseHandle(), timeval{ds->checkTimeout,0}, ds->d_tlsCtx, time(nullptr));
data->d_ioState = std::make_unique<IOStateHandler>(*mplexer, data->d_tcpHandler->getDescriptor());
-
data->d_tcpHandler->tryConnect(ds->tcpFastOpen, ds->remote);
const uint8_t sizeBytes[] = { static_cast<uint8_t>(packetSize / 256), static_cast<uint8_t>(packetSize % 256) };
--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include "dnsdist-session-cache.hh"
+
+TLSSessionCache g_sessionCache;
+
+void TLSSessionCache::cleanup(time_t now)
+{
+ #warning WRITEME
+}
+
+void TLSSessionCache::putSession(const ComboAddress& remote, std::unique_ptr<TLSSession>&& session)
+{
+ std::lock_guard<decltype(d_lock)> lock(d_lock);
+ auto& entry = d_sessions[remote];
+ entry.d_session = std::move(session);
+}
+
+std::unique_ptr<TLSSession> TLSSessionCache::getSession(const ComboAddress& remote, time_t now)
+{
+ std::lock_guard<decltype(d_lock)> lock(d_lock);
+ auto it = d_sessions.find(remote);
+ if (it == d_sessions.end()) {
+ return nullptr;
+ }
+
+ auto& entry = it->second;
+ if (entry.d_session == nullptr) {
+ return nullptr;
+ }
+
+ entry.d_lastUse = now;
+ return std::move(entry.d_session);
+}
--- /dev/null
+/*
+ * This file is part of PowerDNS or dnsdist.
+ * Copyright -- PowerDNS.COM B.V. and its contributors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * In addition, for the avoidance of any doubt, permission is granted to
+ * link this program with OpenSSL and to (re)distribute the binaries
+ * produced as the result of such linking.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#pragma once
+
+#include "tcpiohandler.hh"
+
+class TLSSessionCache
+{
+public:
+ TLSSessionCache()
+ {
+ }
+ void cleanup(time_t now);
+
+ void putSession(const ComboAddress& remote, std::unique_ptr<TLSSession>&& session);
+ std::unique_ptr<TLSSession> getSession(const ComboAddress& remote, time_t now);
+
+private:
+ struct Entry
+ {
+ // might become a FIFO at some point
+ std::unique_ptr<TLSSession> d_session{nullptr};
+ time_t d_lastUse{0};
+ };
+
+ std::map<ComboAddress, Entry> d_sessions;
+ std::mutex d_lock;
+};
+
+extern TLSSessionCache g_sessionCache;
+#include "dnsdist-session-cache.hh"
#include "dnsdist-tcp-downstream.hh"
#include "dnsdist-tcp-upstream.hh"
#include "dnsparser.hh"
+TCPConnectionToBackend::~TCPConnectionToBackend()
+{
+ if (d_ds && d_handler) {
+ --d_ds->tcpCurrentConnections;
+ struct timeval now;
+ gettimeofday(&now, nullptr);
+
+ if (d_handler->isTLS()) {
+ cerr<<"Closing TLS connection, resumption was "<<d_handler->hasTLSSessionBeenResumed()<<endl;
+ auto session = d_handler->getTLSSession();
+ if (session) {
+ g_sessionCache.putSession(d_ds->remote, std::move(session));
+ }
+ }
+ auto diff = now - d_connectionStartTime;
+ d_ds->updateTCPMetrics(d_queries, diff.tv_sec * 1000 + diff.tv_usec / 1000);
+ }
+}
+
void TCPConnectionToBackend::release()
{
d_ds->outstanding -= d_pendingResponses.size();
bool TCPConnectionToBackend::reconnect()
{
+ std::unique_ptr<TLSSession> tlsSession{nullptr};
if (d_handler) {
DEBUGLOG("closing socket "<<d_handler->getDescriptor());
+ if (d_handler->isTLS()) {
+ cerr<<"is TLS, getting a session"<<endl;
+ tlsSession = d_handler->getTLSSession();
+ }
d_handler->close();
d_ioState.reset();
--d_ds->tcpCurrentConnections;
socket->setNonBlocking();
gettimeofday(&d_connectionStartTime, nullptr);
- auto handler = std::make_unique<TCPIOHandler>(d_ds->d_tlsSubjectName, socket->releaseHandle(), timeval{0,0}, d_ds->d_tlsCtx, time(nullptr));
+ auto handler = std::make_unique<TCPIOHandler>(d_ds->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->remote, d_connectionStartTime.tv_sec);
+ if (tlsSession) {
+ cerr<<"reusing session from cache"<<endl;
+ }
+ }
+ else {
+ cerr<<"reusing session from previous connection"<<endl;
+ }
+ if (tlsSession) {
+ handler->setTLSSession(tlsSession);
+ }
handler->tryConnect(d_ds->tcpFastOpen && isFastOpenEnabled(), d_ds->remote);
d_queries = 0;
reconnect();
}
- ~TCPConnectionToBackend()
- {
- if (d_ds && d_handler) {
- --d_ds->tcpCurrentConnections;
- struct timeval now;
- gettimeofday(&now, nullptr);
-
- auto diff = now - d_connectionStartTime;
- d_ds->updateTCPMetrics(d_queries, diff.tv_sec * 1000 + diff.tv_usec / 1000);
- }
- }
+ ~TCPConnectionToBackend();
int getHandle() const
{
std::unique_ptr<TLSSession> getSession() const override
{
- throw std::runtime_error("getSession() not implemented");
+ return nullptr;
}
void setSession(std::unique_ptr<TLSSession>& session) override
{
- throw std::runtime_error("setSession() not implemented");
}
/* unused in that context, don't bother */
/* needed for proper TCP_FASTOPEN_CONNECT detection */
#include <netinet/tcp.h>
+#include "iputils.hh"
#include "libssl.hh"
#include "misc.hh"
#include "noinitvector.hh"