/* * TLS Session Manager * (C) 2011 Jack Lloyd * * Released under the terms of the Botan license */ #ifndef BOTAN_TLS_SESSION_MANAGER_H__ #define BOTAN_TLS_SESSION_MANAGER_H__ #include #include #include #include namespace Botan { namespace TLS { /** * Session_Manager is an interface to systems which can save * session parameters for supporting session resumption. * * Saving sessions is done on a best-effort basis; an implementation is * allowed to drop sessions due to space constraints. * * Implementations should strive to be thread safe */ class BOTAN_DLL Session_Manager { public: /** * Try to load a saved session (server side) * @param session_id the session identifier we are trying to resume * @param session will be set to the saved session data (if found), or not modified if not found * @return true if session was modified */ virtual bool load_from_session_id(const std::vector& session_id, Session& session) = 0; /** * Try to load a saved session (client side) * @param hostname of the host we are connecting to * @param port the port number if we know it, or 0 if unknown * @param session will be set to the saved session data (if found), or not modified if not found * @return true if session was modified */ virtual bool load_from_host_info(const std::string& hostname, u16bit port, Session& session) = 0; /** * Remove this session id from the cache, if it exists */ virtual void remove_entry(const std::vector& session_id) = 0; /** * Save a session on a best effort basis; the manager may not in * fact be able to save the session for whatever reason; this is * not an error. Caller cannot assume that calling save followed * immediately by load_from_* will result in a successful lookup. * * @param session to save * @param port the protocol port (if known) */ virtual void save(const Session& session, u16bit port = 0) = 0; /** * Return the allowed lifetime of a session; beyond this time, * sessions are not resumed. Returns 0 if unknown/no explicit * expiration policy. */ virtual std::chrono::seconds session_lifetime() const = 0; virtual ~Session_Manager() {} }; /** * An implementation of Session_Manager that does not save sessions at * all, preventing session resumption. */ class BOTAN_DLL Session_Manager_Noop : public Session_Manager { public: bool load_from_session_id(const std::vector&, Session&) override { return false; } bool load_from_host_info(const std::string&, u16bit, Session&) override { return false; } void remove_entry(const std::vector&) override {} void save(const Session&, u16bit) override {} std::chrono::seconds session_lifetime() const override { return std::chrono::seconds(0); } }; /** * An implementation of Session_Manager that saves values in memory */ class BOTAN_DLL Session_Manager_In_Memory : public Session_Manager { public: /** * @param max_sessions a hint on the maximum number of sessions * to keep in memory at any one time. (If zero, don't cap) * @param session_lifetime sessions are expired after this many * seconds have elapsed from initial handshake. */ Session_Manager_In_Memory(size_t max_sessions = 1000, std::chrono::seconds session_lifetime = std::chrono::seconds(7200)) : m_max_sessions(max_sessions), m_session_lifetime(session_lifetime) {} bool load_from_session_id(const std::vector& session_id, Session& session) override; bool load_from_host_info(const std::string& hostname, u16bit port, Session& session) override; void remove_entry(const std::vector& session_id) override; void save(const Session& session_data, u16bit port) override; std::chrono::seconds session_lifetime() const override { return m_session_lifetime; } private: bool load_from_session_str(const std::string& session_str, Session& session); std::mutex m_mutex; size_t m_max_sessions; std::chrono::seconds m_session_lifetime; std::map m_sessions; // hex(session_id) -> session std::map m_host_sessions; }; } } #endif