d_nextCleanup = now + s_cleanupDelay;
}
-void TLSSessionCache::putSession(const boost::uuids::uuid& backendID, time_t now, std::unique_ptr<TLSSession>&& session)
+void TLSSessionCache::putSessions(const boost::uuids::uuid& backendID, time_t now, std::vector<std::unique_ptr<TLSSession>>&& sessions)
{
std::lock_guard<decltype(d_lock)> lock(d_lock);
if (d_nextCleanup == 0 || now > d_nextCleanup) {
cleanup(now, lock);
}
- auto& entry = d_sessions[backendID];
- if (entry.d_sessions.size() >= s_maxSessionsPerBackend) {
- entry.d_sessions.pop_back();
+ for (auto& session : sessions) {
+ auto& entry = d_sessions[backendID];
+ if (entry.d_sessions.size() >= s_maxSessionsPerBackend) {
+ entry.d_sessions.pop_back();
+ }
+ entry.d_sessions.push_front(std::move(session));
}
- entry.d_sessions.push_front(std::move(session));
}
std::unique_ptr<TLSSession> TLSSessionCache::getSession(const boost::uuids::uuid& backendID, time_t now)
}
void cleanup(time_t now, const std::lock_guard<std::mutex>& lock);
- void putSession(const boost::uuids::uuid& backendID, time_t now, std::unique_ptr<TLSSession>&& session);
+ void putSessions(const boost::uuids::uuid& backendID, time_t now, std::vector<std::unique_ptr<TLSSession>>&& sessions);
std::unique_ptr<TLSSession> getSession(const boost::uuids::uuid& backendID, time_t now);
static void setCleanupDelay(time_t delay)
++d_ds->tlsResumptions;
}
try {
- auto session = d_handler->getTLSSession();
- if (session) {
- g_sessionCache.putSession(d_ds->getID(), now.tv_sec, std::move(session));
+ auto sessions = d_handler->getTLSSessions();
+ if (!sessions.empty()) {
+ g_sessionCache.putSessions(d_ds->getID(), now.tv_sec, std::move(sessions));
}
}
catch (const std::exception& e) {
++d_ds->tlsResumptions;
}
try {
- tlsSession = d_handler->getTLSSession();
+ auto sessions = d_handler->getTLSSessions();
+ if (!sessions.empty()) {
+ tlsSession = std::move(sessions.back());
+ sessions.pop_back();
+ if (!sessions.empty()) {
+ g_sessionCache.putSessions(d_ds->getID(), time(nullptr), std::move(sessions));
+ }
+ }
}
catch (const std::exception& e) {
vinfolog("Unable to get a TLS session to resume: %s", e.what());
}
PacketBuffer d_responseBuffer;
-#warning we do not need this and could append to the outgoing buffer right away but is it better?
std::deque<TCPQuery> d_pendingQueries;
std::unordered_map<uint16_t, TCPQuery> d_pendingResponses;
std::unique_ptr<FDMultiplexer>& d_mplexer;
return false;
}
- std::unique_ptr<TLSSession> getSession() override
+ std::vector<std::unique_ptr<TLSSession>> getSessions() override
{
- return nullptr;
+ return {};
}
void setSession(std::unique_ptr<TLSSession>& session) override
return false;
}
- std::unique_ptr<TLSSession> getSession() override
+ std::vector<std::unique_ptr<TLSSession>> getSessions() override
{
- if (d_tlsSession) {
- return std::move(d_tlsSession);
- }
-
- throw std::runtime_error("Unable to get an OpenSSL session");
+ return std::move(d_tlsSessions);
}
void setSession(std::unique_ptr<TLSSession>& session) override
native.release();
}
- void setNewTicket(SSL_SESSION* session)
+ void addNewTicket(SSL_SESSION* session)
{
- d_tlsSession = std::unique_ptr<TLSSession>(new OpenSSLSession(std::unique_ptr<SSL_SESSION, void(*)(SSL_SESSION*)>(session, SSL_SESSION_free)));
+ d_tlsSessions.push_back(std::unique_ptr<TLSSession>(new OpenSSLSession(std::unique_ptr<SSL_SESSION, void(*)(SSL_SESSION*)>(session, SSL_SESSION_free))));
}
static int s_tlsConnIndex;
private:
static std::atomic_flag s_initTLSConnIndex;
+ std::vector<std::unique_ptr<TLSSession>> d_tlsSessions;
std::shared_ptr<OpenSSLFrontendContext> d_feContext;
std::unique_ptr<SSL, void(*)(SSL*)> d_conn;
- std::unique_ptr<TLSSession> d_tlsSession{nullptr};
std::string d_hostname;
struct timeval d_timeout;
};
return 0;
}
- conn->setNewTicket(session);
+ conn->addNewTicket(session);
return 1;
}
if (ret != GNUTLS_E_SUCCESS || sess.size <= 4) {
throw std::runtime_error("Error getting GnuTLSSession: " + std::string(gnutls_strerror(ret)));
}
- conn->d_tlsSession = std::unique_ptr<TLSSession>(new GnuTLSSession(sess));
+ conn->d_tlsSessions.push_back(std::unique_ptr<TLSSession>(new GnuTLSSession(sess)));
return 0;
}
return false;
}
- std::unique_ptr<TLSSession> getSession() override
+ std::vector<std::unique_ptr<TLSSession>> getSessions() override
{
- if (d_tlsSession) {
- return std::move(d_tlsSession);
- }
-
- throw std::runtime_error("No GnuTLSSession available yet");
+ return std::move(d_tlsSessions);
}
void setSession(std::unique_ptr<TLSSession>& session) override
}
private:
+ std::vector<std::unique_ptr<TLSSession>> d_tlsSessions;
std::shared_ptr<GnuTLSTicketsKey> d_ticketsKey;
std::unique_ptr<gnutls_session_int, void(*)(gnutls_session_t)> d_conn;
- std::unique_ptr<TLSSession> d_tlsSession{nullptr};
std::string d_host;
bool d_client{false};
bool d_handshakeDone{false};
virtual std::vector<uint8_t> getNextProtocol() const = 0;
virtual LibsslTLSVersion getTLSVersion() const = 0;
virtual bool hasSessionBeenResumed() const = 0;
- virtual std::unique_ptr<TLSSession> getSession() = 0;
+ virtual std::vector<std::unique_ptr<TLSSession>> getSessions() = 0;
virtual void setSession(std::unique_ptr<TLSSession>& session) = 0;
virtual void close() = 0;
}
}
- std::unique_ptr<TLSSession> getTLSSession()
+ std::vector<std::unique_ptr<TLSSession>> getTLSSessions()
{
if (!d_conn) {
- throw std::runtime_error("Trying to get a TLS session from a non-TLS handler");
+ throw std::runtime_error("Trying to get TLS sessions from a non-TLS handler");
}
- return d_conn->getSession();
+ return d_conn->getSessions();
}
private: