1 #pragma once 2 3 #include "main.hpp" 4 #include "session.hpp" 5 6 #include <boost/asio/steady_timer.hpp> 7 #include <ipmid/api.hpp> 8 #include <ipmid/sessiondef.hpp> 9 10 #include <chrono> 11 #include <map> 12 #include <memory> 13 #include <mutex> 14 #include <string> 15 16 namespace session 17 { 18 19 enum class RetrieveOption 20 { 21 BMC_SESSION_ID, 22 RC_SESSION_ID, 23 }; 24 25 static constexpr size_t maxSessionHandles = multiIntfaceSessionHandleMask; 26 27 /** 28 * @class Manager 29 * 30 * Manager class acts a manager for the IPMI sessions and provides interfaces 31 * to start a session, stop a session and get reference to the session objects. 32 * 33 */ 34 35 class Manager 36 { 37 private: 38 struct Private 39 {}; 40 41 public: 42 // BMC Session ID is the key for the map 43 using SessionMap = std::map<SessionID, std::shared_ptr<Session>>; 44 45 Manager() = delete; 46 Manager(std::shared_ptr<boost::asio::io_context>& io, const Private&) : 47 io(io), timer(*io){}; 48 ~Manager() = default; 49 Manager(const Manager&) = delete; 50 Manager& operator=(const Manager&) = delete; 51 Manager(Manager&&) = default; 52 Manager& operator=(Manager&&) = default; 53 54 /** 55 * @brief Get a reference to the singleton Manager 56 * 57 * @return Manager reference 58 */ 59 static Manager& get() 60 { 61 static std::shared_ptr<Manager> ptr = nullptr; 62 if (!ptr) 63 { 64 std::shared_ptr<boost::asio::io_context> io = getIo(); 65 ptr = std::make_shared<Manager>(io, Private()); 66 if (!ptr) 67 { 68 throw std::runtime_error("failed to create session manager"); 69 } 70 } 71 return *ptr; 72 } 73 74 /** 75 * @brief Start an IPMI session 76 * 77 * @param[in] remoteConsoleSessID - Remote Console Session ID mentioned 78 * in the Open SessionRequest Command 79 * @param[in] priv - Privilege level requested 80 * @param[in] authAlgo - Authentication Algorithm 81 * @param[in] intAlgo - Integrity Algorithm 82 * @param[in] cryptAlgo - Confidentiality Algorithm 83 * 84 * @return session handle on success and nullptr on failure 85 * 86 */ 87 std::shared_ptr<Session> 88 startSession(SessionID remoteConsoleSessID, Privilege priv, 89 cipher::rakp_auth::Algorithms authAlgo, 90 cipher::integrity::Algorithms intAlgo, 91 cipher::crypt::Algorithms cryptAlgo); 92 93 /** 94 * @brief Stop IPMI Session 95 * 96 * @param[in] bmcSessionID - BMC Session ID 97 * 98 * @return true on success and failure if session ID is invalid 99 * 100 */ 101 bool stopSession(SessionID bmcSessionID); 102 103 /** 104 * @brief Get Session Handle 105 * 106 * @param[in] sessionID - Session ID 107 * @param[in] option - Select between BMC Session ID and Remote Console 108 * Session ID, Default option is BMC Session ID 109 * 110 * @return session handle on success and nullptr on failure 111 * 112 */ 113 std::shared_ptr<Session> 114 getSession(SessionID sessionID, 115 RetrieveOption option = RetrieveOption::BMC_SESSION_ID); 116 uint8_t getActiveSessionCount() const; 117 uint8_t getSessionHandle(SessionID bmcSessionID) const; 118 uint8_t storeSessionHandle(SessionID bmcSessionID); 119 uint32_t getSessionIDbyHandle(uint8_t sessionHandle) const; 120 121 void managerInit(const std::string& channel); 122 123 uint8_t getNetworkInstance(void); 124 125 /** 126 * @brief Clean Session Stale Entries 127 * 128 * Schedules cleaning the inactive sessions entries from the Session Map 129 */ 130 void scheduleSessionCleaner(const std::chrono::microseconds& grace); 131 132 private: 133 /** 134 * @brief reclaim system resources by limiting idle sessions 135 * 136 * Limits on active, authenticated sessions are calculated independently 137 * from in-setup sessions, which are not required to be authenticated. This 138 * will prevent would-be DoS attacks by calling a bunch of Open Session 139 * requests to fill up all available sessions. Too many active sessions will 140 * trigger a shorter timeout, but is unaffected by setup session counts. 141 * 142 * For active sessions, grace time is inversely proportional to (the number 143 * of active sessions beyond max sessions per channel)^3 144 * 145 * For sessions in setup, grace time is inversely proportional to (the 146 * number of total sessions beyond max sessions per channel)^3, with a max 147 * of 3 seconds 148 */ 149 void cleanStaleEntries(); 150 151 std::shared_ptr<boost::asio::io_context> io; 152 boost::asio::steady_timer timer; 153 154 std::array<uint32_t, session::maxSessionHandles> sessionHandleMap = {0}; 155 156 /** 157 * @brief Session Manager keeps the session objects as a sorted 158 * associative container with Session ID as the unique key 159 */ 160 SessionMap sessionsMap; 161 std::unique_ptr<sdbusplus::server::manager_t> objManager = nullptr; 162 std::string chName{}; // Channel Name 163 uint8_t ipmiNetworkInstance = 0; 164 void setNetworkInstance(void); 165 }; 166 167 } // namespace session 168