1+ #pragma once
2+
3+ #include " fieldHandler.hpp"
4+ #include " flowRecord.hpp"
5+ #include " icmp.hpp"
6+ #include " packet.hpp"
7+ #include " processPluginEntry.hpp"
8+
9+ #include < array>
10+ #include < cstdint>
11+ #include < memory>
12+ #include < string>
13+ #include < type_traits>
14+
15+ #include < boost/container/static_vector.hpp>
16+
17+ namespace ipxp {
18+
19+ class FlowRecordBuilder ;
20+
21+ class ProcessPlugins {
22+ public:
23+ ProcessPlugins (FieldManager& manager)
24+ : m_fieldManager(manager)
25+ {
26+ }
27+
28+ template <typename ... Args>
29+ void addProcessPlugin (const std::string& pluginName, Args&&... args)
30+ {
31+ std::lock_guard<std::mutex> lock (m_mutex);
32+
33+ auto processPlugin
34+ = std::make_shared<IcmpPlugin>(std::forward<Args>(args)..., m_fieldManager);
35+ auto [pluginDataSize, pluginDataAlignment] = processPlugin->getDataMemoryLayout ();
36+ ProcessPluginEntry pluginEntry = {
37+ .name = pluginName,
38+ .contextSize = pluginDataSize,
39+ .contextAlignment = pluginDataAlignment,
40+ .enabled = true ,
41+ .plugin = std::move (processPlugin),
42+ };
43+
44+ printPluginEntry (pluginEntry);
45+
46+ m_processPlugins.emplace_back (pluginEntry);
47+ }
48+
49+ void enableProcessPlugin (const std::string& pluginName)
50+ {
51+ std::lock_guard<std::mutex> lock (m_mutex);
52+ for (auto & plugin : m_processPlugins) {
53+ if (plugin.name == pluginName) {
54+ // plugin.enabled = true;
55+ std::cout << " Plugin '" << pluginName << " ' has been enabled\n " ;
56+ return ;
57+ }
58+ }
59+ std::cout << " Plugin '" << pluginName << " ' not found\n " ;
60+ }
61+
62+ void disableProcessPlugin (const std::string& pluginName)
63+ {
64+ std::lock_guard<std::mutex> lock (m_mutex);
65+ for (auto & plugin : m_processPlugins) {
66+ if (plugin.name == pluginName) {
67+ // plugin.enabled = false;
68+ std::cout << " Plugin '" << pluginName << " ' has been disabled\n " ;
69+ return ;
70+ }
71+ }
72+ std::cout << " Plugin '" << pluginName << " ' not found\n " ;
73+ }
74+
75+ /*
76+ void processFlowRecord(FlowContext& flowContext)
77+ {
78+ // updateBasic
79+
80+ FlowRecord& flowRecord = flowContext.flowRecord;
81+
82+ if (flowRecord.pluginsUpdate.none()) {
83+ return;
84+ }
85+
86+ for (std::size_t pluginID = 0; pluginID < m_processPlugins.size(); pluginID++) {
87+ const auto& pluginEntry = m_processPlugins[pluginID];
88+ if (!flowRecord.pluginsAvailable.test(pluginID)) {
89+ continue;
90+ }
91+
92+ if (!flowRecord.pluginsUpdate.test(pluginID)) {
93+ continue;
94+ }
95+
96+ if (!flowRecord.pluginsConstructed.test(pluginID)) {
97+ auto pluginInitResult
98+ = pluginEntry.plugin->onInit(flowContext, flowRecord.getPluginData(pluginID));
99+
100+ if (pluginInitResult.updateRequirement == UpdateRequirement::NoUpdateNeeded) {
101+ flowRecord.pluginsUpdate.reset(pluginID);
102+ }
103+
104+ if (pluginInitResult.flowAction == FlowAction::RemovePlugin) {
105+ flowRecord.pluginsAvailable.reset(pluginID);
106+ }
107+
108+ if (pluginInitResult.constructionState == ConstructionState::Constructed) {
109+ flowRecord.pluginsConstructed.set(pluginID);
110+ }
111+
112+ continue;
113+ }
114+ }
115+ */
116+
117+ /*
118+ void processFlowRecord(
119+ FlowRecord* flowRecord,
120+ const Packet& packet,
121+ const PacketFeatures& packetFeatures)
122+ {
123+ // Check if any plugin needs to process the flow record
124+ if (flowRecord->pluginsUpdate.none()) {
125+ return;
126+ }
127+
128+ for (std::size_t pluginID = 0; pluginID < m_processPlugins.size(); ++pluginID) {
129+ const auto& entry = m_processPlugins[pluginID];
130+ if (!flowRecord->pluginsAvailable.test(pluginID)) {
131+ continue;
132+ }
133+
134+ // Plugin does not want to process packets
135+ if (!flowRecord->pluginsUpdate.test(pluginID)) {
136+ continue;
137+ }
138+
139+ // Plugin not yet constructed, call onFlowCreate
140+ if (!flowRecord->pluginsConstructed.test(pluginID)) {
141+ const auto [isConstructed, needsUpdate, status] =
142+ entry.plugin->onFlowCreate( *flowRecord, flowRecord->getPluginData(pluginID), packet,
143+ packetFeatures);
144+ {
145+ // TODO: na zaklade return value
146+ flowRecord->pluginsConstructed.set(pluginID);
147+ flowRecord->pluginsUpdate.set(pluginID);
148+ }
149+ continue;
150+ }
151+
152+ // Plugin already constructed, call update
153+ if (flowRecord->pluginsConstructed.test(pluginID)) {
154+ const auto [needsUpdate, status] = entry.plugin->onFlowUpdate(
155+ *flowRecord,
156+ flowRecord->getPluginData(pluginID),
157+ packet,
158+ packetFeatures);
159+ continue;
160+ }
161+ }
162+ }
163+ */
164+
165+ template <typename Func>
166+ void forEachPlugin (FlowRecord* flowRecord, Func&& func)
167+ {
168+ std::size_t index = 0 ;
169+ for (const auto & entry : m_processPlugins) {
170+ if (flowRecord->pluginsAvailable .test (index)) {
171+ func (flowRecord, entry.plugin .get (), flowRecord->getPluginContext (index));
172+ }
173+ index++;
174+ }
175+ }
176+
177+ std::shared_ptr<FlowRecordBuilder> rebuild ();
178+
179+ const std::vector<ProcessPluginEntry>& getEntries () { return m_processPlugins; }
180+
181+ private:
182+ void printPluginEntry (const ProcessPluginEntry& entry)
183+ {
184+ std::cout << " Plugin: " << entry.name << " \n " ;
185+ std::cout << " Context Size: " << entry.contextSize << " bytes\n " ;
186+ std::cout << " Context Alignment: " << entry.contextAlignment << " bytes\n " ;
187+ // std::cout << " Enabled: " << std::boolalpha << entry.isEnabled << "\n";
188+ }
189+
190+ std::mutex m_mutex;
191+ std::atomic<std::size_t > m_pluginID = 0 ;
192+ FieldManager& m_fieldManager;
193+ std::vector<ProcessPluginEntry> m_processPlugins;
194+ };
195+
196+ } // namespace ipxp
0 commit comments