1 //--------------------------------------------------------------------------
2 // Copyright (C) 2015-2021 Cisco and/or its affiliates. All rights reserved.
3 //
4 // This program is free software; you can redistribute it and/or modify it
5 // under the terms of the GNU General Public License Version 2 as published
6 // by the Free Software Foundation. You may not use, modify or distribute
7 // this program under any other version of the GNU General Public License.
8 //
9 // This program is distributed in the hope that it will be useful, but
10 // WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License along
15 // with this program; if not, write to the Free Software Foundation, Inc.,
16 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 //--------------------------------------------------------------------------
18 // connector_manager.cc author Ed Borgoyn <eborgoyn@cisco.com>
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "connector_manager.h"
25
26 #include <cassert>
27 #include <list>
28 #include <map>
29 #include <unordered_map>
30
31 #include "framework/connector.h"
32 #include "log/messages.h"
33 #include "utils/util.h"
34
35 using namespace snort;
36
37 // ConnectorManager Private Data
38
39 // One ConnectorElem for each Connector within the ConnectorCommon configuration
40 struct ConnectorElem
41 {
42 ConnectorConfig* config;
43 std::unordered_map<pid_t, Connector*> thread_connectors;
44 };
45
46 // One ConnectorCommonElem created for each ConnectorCommon configured
47 struct ConnectorCommonElem
48 {
49 const ConnectorApi* api;
50 ConnectorCommon* connector_common;
51 std::map<std::string, ConnectorElem*> connectors;
52
ConnectorCommonElemConnectorCommonElem53 ConnectorCommonElem(const ConnectorApi* p)
54 {
55 api = p;
56 connector_common = nullptr;
57 }
58 };
59
60 typedef std::list<ConnectorCommonElem> CList;
61 static CList s_connector_commons;
62
63 //-------------------------------------------------------------------------
64
add_plugin(const ConnectorApi * api)65 void ConnectorManager::add_plugin(const ConnectorApi* api)
66 {
67 if ( api->pinit )
68 api->pinit();
69 }
70
dump_plugins()71 void ConnectorManager::dump_plugins()
72 {
73 Dumper d("Connectors");
74
75 for ( auto& sc : s_connector_commons )
76 d.dump(sc.api->base.name, sc.api->base.version);
77 }
78
release_plugins()79 void ConnectorManager::release_plugins()
80 {
81 for ( auto& sc : s_connector_commons )
82 {
83 if ( sc.api->dtor )
84 sc.api->dtor(sc.connector_common);
85
86 for ( auto& conn : sc.connectors )
87 delete conn.second;
88
89 sc.connectors.clear();
90
91 if ( sc.api->pterm )
92 sc.api->pterm();
93 }
94
95 s_connector_commons.clear();
96 }
97
get_connector(const std::string & connector_name)98 Connector* ConnectorManager::get_connector(const std::string& connector_name)
99 {
100 for ( auto& sc : s_connector_commons )
101 {
102 pid_t tid = gettid();
103 if ( sc.connectors.count(connector_name) > 0 )
104 {
105 ConnectorElem* map = sc.connectors[connector_name];
106 if ( map->thread_connectors.count(tid) == 1 )
107 return ( map->thread_connectors[tid] );
108 }
109 }
110 return ( nullptr );
111 }
112
thread_init()113 void ConnectorManager::thread_init()
114 {
115 pid_t tid = gettid();
116
117 for ( auto& sc : s_connector_commons )
118 {
119 if ( sc.api->tinit )
120 {
121 for ( auto& conn : sc.connectors )
122 {
123 /* There must NOT be a connector for this thread present. */
124 assert(conn.second->thread_connectors.count(tid) == 0);
125
126 Connector* connector = sc.api->tinit(conn.second->config);
127 conn.second->thread_connectors.emplace(tid, std::move(connector));
128 }
129 }
130 }
131 }
132
thread_term()133 void ConnectorManager::thread_term()
134 {
135 pid_t tid = gettid();
136
137 for ( auto& sc : s_connector_commons )
138 {
139 if ( sc.api->tterm )
140 {
141 for ( auto& conn : sc.connectors )
142 {
143 /* There must be a connector for this thread present. */
144 assert(conn.second->thread_connectors.count(tid) != 0);
145
146 sc.api->tterm(conn.second->thread_connectors[tid]);
147
148 conn.second->thread_connectors.clear();
149 }
150 }
151 }
152 }
153
instantiate(const ConnectorApi * api,Module * mod,SnortConfig *)154 void ConnectorManager::instantiate(const ConnectorApi* api, Module* mod, SnortConfig*)
155 {
156 assert(mod);
157 ConnectorCommonElem c(api);
158
159 ConnectorCommon* connector_common = api->ctor(mod);
160 assert(connector_common);
161
162 c.connector_common = connector_common;
163 ConnectorConfig::ConfigSet* config_set = connector_common->config_set;
164
165 // iterate through the config_set and create the connector entries
166 for ( auto cfg : *config_set )
167 {
168 ConnectorElem* connector_elem = new ConnectorElem;
169 connector_elem->config = &*cfg;
170 c.connectors.emplace(cfg->connector_name, std::move(connector_elem));
171 }
172
173 s_connector_commons.emplace_back(c);
174 }
175
176