int Flow::set_flow_data(FlowData* fd)
{
- FlowData* old = get_flow_data(fd->get_id());
- assert(old != fd);
-
- if (old)
- free_flow_data(old);
-
- fd->prev = nullptr;
- fd->next = flow_data;
-
- if ( flow_data )
- flow_data->prev = fd;
-
- flow_data = fd;
+ if ( !fd ) return -1;
+
+ current_flow_data = fd;
+ uint32_t id = fd->get_id();
+ // operator[] will create a new entry if it does not exist
+ // or replace the existing one if it does
+ // when replacing, the old entry is deleted
+ flow_data[id] = std::unique_ptr<FlowData>(fd);
return 0;
}
+
FlowData* Flow::get_flow_data(unsigned id) const
{
- FlowData* fd = flow_data;
-
- while (fd)
- {
- if (fd->get_id() == id)
- return fd;
-
- fd = fd->next;
- }
+ auto it = flow_data.find(id);
+ if ( it != flow_data.end() )
+ return it->second.get();
return nullptr;
}
-// FIXIT-L: implement doubly linked list with STL to cut down on code we maintain
void Flow::free_flow_data(FlowData* fd)
{
- if ( fd == flow_data )
- {
- flow_data = fd->next;
- if ( flow_data )
- flow_data->prev = nullptr;
- }
- else if ( !fd->next )
- {
- fd->prev->next = nullptr;
- }
- else
- {
- fd->prev->next = fd->next;
- fd->next->prev = fd->prev;
- }
- delete fd;
+ if ( !fd ) return;
+ flow_data.erase(fd->get_id());
}
void Flow::free_flow_data(uint32_t proto)
{
- FlowData* fd = get_flow_data(proto);
-
- if ( fd )
- free_flow_data(fd);
+ flow_data.erase(proto);
}
void Flow::free_flow_data()
{
- if (!flow_data)
+ if ( flow_data.empty() )
return;
const SnortConfig* sc = SnortConfig::get_conf();
PolicySelector* ps = sc->policy_map->get_policy_selector();
}
}
- while (flow_data)
- {
- FlowData* tmp = flow_data;
- flow_data = flow_data->next;
- delete tmp;
- }
+ flow_data.clear();
if (ps)
{
void Flow::call_handlers(Packet* p, bool eof)
{
- FlowData* fd = flow_data;
-
- while (fd)
+ for (auto& fd_pair : flow_data)
{
+ FlowData* fd = fd_pair.second.get();
if ( eof )
fd->handle_eof(p);
else
fd->handle_retransmit(p);
-
- fd = fd->next;
}
}
// fields are organized by initialization and size to minimize
// void space
+ std::unordered_map<uint32_t, std::unique_ptr<FlowData>> flow_data;
+
DeferredTrust deferred_trust;
const FlowKey* key = nullptr;
Layer mpls_server = {};
IpsContextChain context_chain;
- FlowData* flow_data = nullptr;
+ FlowData* current_flow_data = nullptr;
FlowStats flowstats = {};
StreamFlowIntf* stream_intf = nullptr;
char src_ip[INET6_ADDRSTRLEN];
char dst_ip[INET6_ADDRSTRLEN];
- AppIdInspector* inspector = (AppIdInspector*)ctrlPkt->flow->flow_data->get_handler();
+ AppIdInspector* inspector = (AppIdInspector*)ctrlPkt->flow->current_flow_data->get_handler();
if ((inspector == nullptr) or strcmp(inspector->get_name(), MOD_NAME))
inspector = (AppIdInspector*)InspectorManager::get_inspector(MOD_NAME, true);