blob: 512b17c2a2c74a076273af3b7c212e57f6c3f29e [file] [log] [blame]
Tom Joseph3e61aa02016-08-08 08:42:39 -05001#pragma once
2
Vernon Mauery2085ae02021-06-10 11:51:00 -07003#include "main.hpp"
Vernon Mauery9e801a22018-10-12 13:20:49 -07004#include "session.hpp"
5
Vernon Maueryecc8efa2021-06-12 12:52:23 -07006#include <boost/asio/steady_timer.hpp>
Suryakanth Sekarf8a34fc2019-06-12 20:59:18 +05307#include <ipmid/api.hpp>
8#include <ipmid/sessiondef.hpp>
George Liubc8958f2022-07-04 09:29:49 +08009
10#include <chrono>
Tom Joseph3e61aa02016-08-08 08:42:39 -050011#include <map>
12#include <memory>
13#include <mutex>
Andrew Geissler7408e762020-05-17 08:56:05 -050014#include <string>
Tom Joseph3e61aa02016-08-08 08:42:39 -050015
Tom Joseph3e61aa02016-08-08 08:42:39 -050016namespace session
17{
18
19enum class RetrieveOption
20{
21 BMC_SESSION_ID,
22 RC_SESSION_ID,
23};
24
Vernon Maueryecc8efa2021-06-12 12:52:23 -070025static constexpr size_t maxSessionHandles = multiIntfaceSessionHandleMask;
26
Tom Joseph3563f8f2017-05-08 15:42:54 +053027/**
Tom Joseph3e61aa02016-08-08 08:42:39 -050028 * @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
35class Manager
36{
Vernon Mauery2085ae02021-06-10 11:51:00 -070037 private:
38 struct Private
George Liubc8958f2022-07-04 09:29:49 +080039 {};
Vernon Mauery2085ae02021-06-10 11:51:00 -070040
Vernon Mauery9e801a22018-10-12 13:20:49 -070041 public:
42 // BMC Session ID is the key for the map
43 using SessionMap = std::map<SessionID, std::shared_ptr<Session>>;
Tom Joseph3e61aa02016-08-08 08:42:39 -050044
Vernon Maueryecc8efa2021-06-12 12:52:23 -070045 Manager() = delete;
Vernon Mauery2085ae02021-06-10 11:51:00 -070046 Manager(std::shared_ptr<boost::asio::io_context>& io, const Private&) :
Vernon Maueryecc8efa2021-06-12 12:52:23 -070047 io(io), timer(*io){};
Vernon Mauery9e801a22018-10-12 13:20:49 -070048 ~Manager() = default;
49 Manager(const Manager&) = delete;
50 Manager& operator=(const Manager&) = delete;
51 Manager(Manager&&) = default;
52 Manager& operator=(Manager&&) = default;
Tom Joseph3e61aa02016-08-08 08:42:39 -050053
Vernon Mauery9e801a22018-10-12 13:20:49 -070054 /**
Vernon Mauery2085ae02021-06-10 11:51:00 -070055 * @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 /**
Vernon Mauery9e801a22018-10-12 13:20:49 -070075 * @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 */
Vernon Maueryae1fda42018-10-15 12:55:34 -070087 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);
Tom Joseph3e61aa02016-08-08 08:42:39 -050092
Vernon Mauery9e801a22018-10-12 13:20:49 -070093 /**
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);
Tom Joseph3e61aa02016-08-08 08:42:39 -0500102
Vernon Mauery9e801a22018-10-12 13:20:49 -0700103 /**
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 */
Vernon Maueryae1fda42018-10-15 12:55:34 -0700113 std::shared_ptr<Session>
Vernon Mauery9e801a22018-10-12 13:20:49 -0700114 getSession(SessionID sessionID,
115 RetrieveOption option = RetrieveOption::BMC_SESSION_ID);
Suryakanth Sekarf8a34fc2019-06-12 20:59:18 +0530116 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);
Tom Joseph3e61aa02016-08-08 08:42:39 -0500124
Vernon Maueryecc8efa2021-06-12 12:52:23 -0700125 /**
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
Vernon Mauery9e801a22018-10-12 13:20:49 -0700132 private:
Vernon Maueryecc8efa2021-06-12 12:52:23 -0700133 /**
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};
Suryakanth Sekarf8a34fc2019-06-12 20:59:18 +0530155
Vernon Mauery9e801a22018-10-12 13:20:49 -0700156 /**
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;
Patrick Williams0a590622022-07-22 19:26:53 -0500161 std::unique_ptr<sdbusplus::server::manager_t> objManager = nullptr;
Suryakanth Sekarf8a34fc2019-06-12 20:59:18 +0530162 std::string chName{}; // Channel Name
Willy Tuc1c2e0a2021-11-09 23:14:03 -0800163 uint8_t ipmiNetworkInstance = 0;
Suryakanth Sekarf8a34fc2019-06-12 20:59:18 +0530164 void setNetworkInstance(void);
Tom Joseph3e61aa02016-08-08 08:42:39 -0500165};
166
167} // namespace session