Reformat Zeek in Spicy style

This largely copies over Spicy's `.clang-format` configuration file. The
one place where we deviate is header include order since Zeek depends on
headers being included in a certain order.
This commit is contained in:
Benjamin Bannier 2023-10-10 21:13:34 +02:00
parent 7b8e7ed72c
commit f5a76c1aed
786 changed files with 131714 additions and 153609 deletions

View file

@ -26,489 +26,417 @@
extern int signal_val;
namespace zeek::iosource
{
namespace zeek::iosource {
Manager::WakeupHandler::WakeupHandler()
{
if ( ! iosource_mgr->RegisterFd(flare.FD(), this) )
reporter->FatalError("Failed to register WakeupHandler's fd with iosource_mgr");
}
Manager::WakeupHandler::WakeupHandler() {
if ( ! iosource_mgr->RegisterFd(flare.FD(), this) )
reporter->FatalError("Failed to register WakeupHandler's fd with iosource_mgr");
}
Manager::WakeupHandler::~WakeupHandler()
{
iosource_mgr->UnregisterFd(flare.FD(), this);
}
Manager::WakeupHandler::~WakeupHandler() { iosource_mgr->UnregisterFd(flare.FD(), this); }
void Manager::WakeupHandler::Process()
{
flare.Extinguish();
}
void Manager::WakeupHandler::Process() { flare.Extinguish(); }
void Manager::WakeupHandler::Ping(std::string_view where)
{
// Calling DBG_LOG calls fprintf, which isn't safe to call in a signal
// handler.
if ( signal_val != 0 )
DBG_LOG(DBG_MAINLOOP, "Pinging WakeupHandler from %s", where.data());
void Manager::WakeupHandler::Ping(std::string_view where) {
// Calling DBG_LOG calls fprintf, which isn't safe to call in a signal
// handler.
if ( signal_val != 0 )
DBG_LOG(DBG_MAINLOOP, "Pinging WakeupHandler from %s", where.data());
flare.Fire(true);
}
flare.Fire(true);
}
Manager::Manager()
{
event_queue = kqueue();
if ( event_queue == -1 )
reporter->FatalError("Failed to initialize kqueue: %s", strerror(errno));
}
Manager::Manager() {
event_queue = kqueue();
if ( event_queue == -1 )
reporter->FatalError("Failed to initialize kqueue: %s", strerror(errno));
}
Manager::~Manager()
{
delete wakeup;
wakeup = nullptr;
Manager::~Manager() {
delete wakeup;
wakeup = nullptr;
// Make sure all of the sources are done before we try to delete any of them.
for ( auto& src : sources )
src->src->Done();
// Make sure all of the sources are done before we try to delete any of them.
for ( auto& src : sources )
src->src->Done();
for ( auto& src : sources )
{
if ( src->manage_lifetime )
delete src->src;
for ( auto& src : sources ) {
if ( src->manage_lifetime )
delete src->src;
delete src;
}
delete src;
}
sources.clear();
sources.clear();
for ( PktDumperList::iterator i = pkt_dumpers.begin(); i != pkt_dumpers.end(); ++i )
{
(*i)->Done();
delete *i;
}
for ( PktDumperList::iterator i = pkt_dumpers.begin(); i != pkt_dumpers.end(); ++i ) {
(*i)->Done();
delete *i;
}
pkt_dumpers.clear();
pkt_dumpers.clear();
#ifndef _MSC_VER
// There's a bug here with builds on Windows that causes an assertion with debug builds
// related to libkqueue returning a zero for the file descriptor. The assert happens
// because something else has already closed FD zero by the time we get here, and Windows
// doesn't like that very much. We only do this close when shutting down, so it should
// be fine to just skip it.
//
// See https://github.com/mheily/libkqueue/issues/151 for more details.
if ( event_queue != -1 )
close(event_queue);
// There's a bug here with builds on Windows that causes an assertion with debug builds
// related to libkqueue returning a zero for the file descriptor. The assert happens
// because something else has already closed FD zero by the time we get here, and Windows
// doesn't like that very much. We only do this close when shutting down, so it should
// be fine to just skip it.
//
// See https://github.com/mheily/libkqueue/issues/151 for more details.
if ( event_queue != -1 )
close(event_queue);
#endif
}
}
void Manager::InitPostScript()
{
wakeup = new WakeupHandler();
poll_interval = BifConst::io_poll_interval_default;
}
void Manager::InitPostScript() {
wakeup = new WakeupHandler();
poll_interval = BifConst::io_poll_interval_default;
}
void Manager::RemoveAll()
{
// We're cheating a bit here ...
dont_counts = sources.size();
}
void Manager::RemoveAll() {
// We're cheating a bit here ...
dont_counts = sources.size();
}
void Manager::Wakeup(std::string_view where)
{
if ( wakeup )
wakeup->Ping(where);
}
void Manager::Wakeup(std::string_view where) {
if ( wakeup )
wakeup->Ping(where);
}
void Manager::FindReadySources(ReadySources* ready)
{
ready->clear();
void Manager::FindReadySources(ReadySources* ready) {
ready->clear();
// Remove sources which have gone dry. For simplicity, we only
// remove at most one each time.
for ( SourceList::iterator i = sources.begin(); i != sources.end(); ++i )
if ( ! (*i)->src->IsOpen() )
{
(*i)->src->Done();
delete *i;
sources.erase(i);
break;
}
// Remove sources which have gone dry. For simplicity, we only
// remove at most one each time.
for ( SourceList::iterator i = sources.begin(); i != sources.end(); ++i )
if ( ! (*i)->src->IsOpen() ) {
(*i)->src->Done();
delete *i;
sources.erase(i);
break;
}
// If there aren't any sources and exit_only_after_terminate is false, just
// return an empty set of sources. We want the main loop to end.
if ( Size() == 0 && (! BifConst::exit_only_after_terminate || run_state::terminating) )
return;
// If there aren't any sources and exit_only_after_terminate is false, just
// return an empty set of sources. We want the main loop to end.
if ( Size() == 0 && (! BifConst::exit_only_after_terminate || run_state::terminating) )
return;
double timeout = -1;
IOSource* timeout_src = nullptr;
bool time_to_poll = false;
double timeout = -1;
IOSource* timeout_src = nullptr;
bool time_to_poll = false;
++poll_counter;
if ( poll_counter % poll_interval == 0 )
{
poll_counter = 0;
time_to_poll = true;
}
++poll_counter;
if ( poll_counter % poll_interval == 0 ) {
poll_counter = 0;
time_to_poll = true;
}
// Find the source with the next timeout value.
for ( auto src : sources )
{
auto iosource = src->src;
if ( iosource->IsOpen() )
{
double next = iosource->GetNextTimeout();
// Find the source with the next timeout value.
for ( auto src : sources ) {
auto iosource = src->src;
if ( iosource->IsOpen() ) {
double next = iosource->GetNextTimeout();
if ( timeout == -1 || (next >= 0.0 && next < timeout) )
{
timeout = next;
timeout_src = iosource;
}
if ( timeout == -1 || (next >= 0.0 && next < timeout) ) {
timeout = next;
timeout_src = iosource;
}
// If a source has a zero timeout then it's ready. Just add it to the
// list already. Only do this if it's not time to poll though, since
// we don't want things in the vector passed into Poll() or it'll end
// up inserting duplicates. A source with a zero timeout that was not
// selected as the timeout_src can be safely added, whether it's time
// to poll or not though.
if ( next == 0 && (! time_to_poll || iosource != timeout_src) )
{
ready->push_back({iosource, -1, 0});
}
else if ( iosource == pkt_src )
{
if ( pkt_src->IsLive() )
{
if ( ! time_to_poll )
// Avoid calling Poll() if we can help it since on very
// high-traffic networks, we spend too much time in
// Poll() and end up dropping packets.
ready->push_back({pkt_src, -1, 0});
}
}
}
}
// If a source has a zero timeout then it's ready. Just add it to the
// list already. Only do this if it's not time to poll though, since
// we don't want things in the vector passed into Poll() or it'll end
// up inserting duplicates. A source with a zero timeout that was not
// selected as the timeout_src can be safely added, whether it's time
// to poll or not though.
if ( next == 0 && (! time_to_poll || iosource != timeout_src) ) {
ready->push_back({iosource, -1, 0});
}
else if ( iosource == pkt_src ) {
if ( pkt_src->IsLive() ) {
if ( ! time_to_poll )
// Avoid calling Poll() if we can help it since on very
// high-traffic networks, we spend too much time in
// Poll() and end up dropping packets.
ready->push_back({pkt_src, -1, 0});
}
}
}
}
DBG_LOG(DBG_MAINLOOP, "timeout: %f ready size: %zu time_to_poll: %d\n", timeout,
ready->size(), time_to_poll);
DBG_LOG(DBG_MAINLOOP, "timeout: %f ready size: %zu time_to_poll: %d\n", timeout, ready->size(), time_to_poll);
// If we didn't find any IOSources with zero timeouts or it's time to
// force a poll, do that and return. Otherwise return the set of ready
// sources that we have.
if ( ready->empty() || time_to_poll )
Poll(ready, timeout, timeout_src);
}
// If we didn't find any IOSources with zero timeouts or it's time to
// force a poll, do that and return. Otherwise return the set of ready
// sources that we have.
if ( ready->empty() || time_to_poll )
Poll(ready, timeout, timeout_src);
}
void Manager::Poll(ReadySources* ready, double timeout, IOSource* timeout_src)
{
struct timespec kqueue_timeout;
ConvertTimeout(timeout, kqueue_timeout);
void Manager::Poll(ReadySources* ready, double timeout, IOSource* timeout_src) {
struct timespec kqueue_timeout;
ConvertTimeout(timeout, kqueue_timeout);
int ret = kevent(event_queue, NULL, 0, events.data(), events.size(), &kqueue_timeout);
if ( ret == -1 )
{
// Ignore interrupts since we may catch one during shutdown and we don't want the
// error to get printed.
if ( errno != EINTR )
reporter->InternalWarning("Error calling kevent: %s", strerror(errno));
}
else if ( ret == 0 )
{
// If a timeout_src was provided and nothing else was ready, we timed out
// according to the given source's timeout and can add it as ready.
if ( timeout_src )
ready->push_back({timeout_src, -1, 0});
}
else
{
// kevent returns the number of events that are ready, so we only need to loop
// over that many of them.
bool timeout_src_added = false;
for ( int i = 0; i < ret; i++ )
{
if ( events[i].filter == EVFILT_READ )
{
std::map<int, IOSource*>::const_iterator it = fd_map.find(events[i].ident);
if ( it != fd_map.end() )
ready->push_back({it->second, static_cast<int>(events[i].ident),
IOSource::ProcessFlags::READ});
}
else if ( events[i].filter == EVFILT_WRITE )
{
std::map<int, IOSource*>::const_iterator it = write_fd_map.find(events[i].ident);
if ( it != write_fd_map.end() )
ready->push_back({it->second, static_cast<int>(events[i].ident),
IOSource::ProcessFlags::WRITE});
}
int ret = kevent(event_queue, NULL, 0, events.data(), events.size(), &kqueue_timeout);
if ( ret == -1 ) {
// Ignore interrupts since we may catch one during shutdown and we don't want the
// error to get printed.
if ( errno != EINTR )
reporter->InternalWarning("Error calling kevent: %s", strerror(errno));
}
else if ( ret == 0 ) {
// If a timeout_src was provided and nothing else was ready, we timed out
// according to the given source's timeout and can add it as ready.
if ( timeout_src )
ready->push_back({timeout_src, -1, 0});
}
else {
// kevent returns the number of events that are ready, so we only need to loop
// over that many of them.
bool timeout_src_added = false;
for ( int i = 0; i < ret; i++ ) {
if ( events[i].filter == EVFILT_READ ) {
std::map<int, IOSource*>::const_iterator it = fd_map.find(events[i].ident);
if ( it != fd_map.end() )
ready->push_back({it->second, static_cast<int>(events[i].ident), IOSource::ProcessFlags::READ});
}
else if ( events[i].filter == EVFILT_WRITE ) {
std::map<int, IOSource*>::const_iterator it = write_fd_map.find(events[i].ident);
if ( it != write_fd_map.end() )
ready->push_back({it->second, static_cast<int>(events[i].ident), IOSource::ProcessFlags::WRITE});
}
// If we added a source that is the same as the passed timeout_src, take
// note as to avoid adding it twice.
timeout_src_added |= ready->size() > 0 ? ready->back().src == timeout_src : false;
}
// If we added a source that is the same as the passed timeout_src, take
// note as to avoid adding it twice.
timeout_src_added |= ready->size() > 0 ? ready->back().src == timeout_src : false;
}
// A timeout_src with a zero timeout can be considered ready.
if ( timeout_src && timeout == 0.0 && ! timeout_src_added )
ready->push_back({timeout_src, -1, 0});
}
}
// A timeout_src with a zero timeout can be considered ready.
if ( timeout_src && timeout == 0.0 && ! timeout_src_added )
ready->push_back({timeout_src, -1, 0});
}
}
void Manager::ConvertTimeout(double timeout, struct timespec& spec)
{
// If timeout ended up -1, set it to some nominal value just to keep the loop
// from blocking forever. This is the case of exit_only_after_terminate when
// there isn't anything else going on.
if ( timeout < 0 )
{
spec.tv_sec = 0;
spec.tv_nsec = 1e8;
}
else
{
spec.tv_sec = static_cast<time_t>(timeout);
spec.tv_nsec = static_cast<long>((timeout - spec.tv_sec) * 1e9);
}
}
void Manager::ConvertTimeout(double timeout, struct timespec& spec) {
// If timeout ended up -1, set it to some nominal value just to keep the loop
// from blocking forever. This is the case of exit_only_after_terminate when
// there isn't anything else going on.
if ( timeout < 0 ) {
spec.tv_sec = 0;
spec.tv_nsec = 1e8;
}
else {
spec.tv_sec = static_cast<time_t>(timeout);
spec.tv_nsec = static_cast<long>((timeout - spec.tv_sec) * 1e9);
}
}
bool Manager::RegisterFd(int fd, IOSource* src, int flags)
{
std::vector<struct kevent> new_events;
bool Manager::RegisterFd(int fd, IOSource* src, int flags) {
std::vector<struct kevent> new_events;
if ( (flags & IOSource::READ) != 0 )
{
if ( fd_map.count(fd) == 0 )
{
new_events.push_back({});
EV_SET(&(new_events.back()), fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
}
}
if ( (flags & IOSource::WRITE) != 0 )
{
if ( write_fd_map.count(fd) == 0 )
{
new_events.push_back({});
EV_SET(&(new_events.back()), fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
}
}
if ( (flags & IOSource::READ) != 0 ) {
if ( fd_map.count(fd) == 0 ) {
new_events.push_back({});
EV_SET(&(new_events.back()), fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
}
}
if ( (flags & IOSource::WRITE) != 0 ) {
if ( write_fd_map.count(fd) == 0 ) {
new_events.push_back({});
EV_SET(&(new_events.back()), fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
}
}
if ( ! new_events.empty() )
{
int ret = kevent(event_queue, new_events.data(), new_events.size(), NULL, 0, NULL);
if ( ret != -1 )
{
DBG_LOG(DBG_MAINLOOP, "Registered fd %d from %s", fd, src->Tag());
for ( const auto& a : new_events )
events.push_back({});
if ( ! new_events.empty() ) {
int ret = kevent(event_queue, new_events.data(), new_events.size(), NULL, 0, NULL);
if ( ret != -1 ) {
DBG_LOG(DBG_MAINLOOP, "Registered fd %d from %s", fd, src->Tag());
for ( const auto& a : new_events )
events.push_back({});
if ( (flags & IOSource::READ) != 0 )
fd_map[fd] = src;
if ( (flags & IOSource::WRITE) != 0 )
write_fd_map[fd] = src;
if ( (flags & IOSource::READ) != 0 )
fd_map[fd] = src;
if ( (flags & IOSource::WRITE) != 0 )
write_fd_map[fd] = src;
Wakeup("RegisterFd");
return true;
}
else
{
reporter->Error("Failed to register fd %d from %s: %s (flags %d)", fd, src->Tag(),
strerror(errno), flags);
return false;
}
}
Wakeup("RegisterFd");
return true;
}
else {
reporter->Error("Failed to register fd %d from %s: %s (flags %d)", fd, src->Tag(), strerror(errno), flags);
return false;
}
}
return true;
}
return true;
}
bool Manager::UnregisterFd(int fd, IOSource* src, int flags)
{
std::vector<struct kevent> new_events;
bool Manager::UnregisterFd(int fd, IOSource* src, int flags) {
std::vector<struct kevent> new_events;
if ( (flags & IOSource::READ) != 0 )
{
if ( fd_map.count(fd) != 0 )
{
new_events.push_back({});
EV_SET(&(new_events.back()), fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
}
}
if ( (flags & IOSource::WRITE) != 0 )
{
if ( write_fd_map.count(fd) != 0 )
{
new_events.push_back({});
EV_SET(&(new_events.back()), fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
}
}
if ( (flags & IOSource::READ) != 0 ) {
if ( fd_map.count(fd) != 0 ) {
new_events.push_back({});
EV_SET(&(new_events.back()), fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
}
}
if ( (flags & IOSource::WRITE) != 0 ) {
if ( write_fd_map.count(fd) != 0 ) {
new_events.push_back({});
EV_SET(&(new_events.back()), fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
}
}
if ( ! new_events.empty() )
{
int ret = kevent(event_queue, new_events.data(), new_events.size(), NULL, 0, NULL);
if ( ret != -1 )
{
DBG_LOG(DBG_MAINLOOP, "Unregistered fd %d from %s", fd, src->Tag());
for ( const auto& a : new_events )
events.pop_back();
if ( ! new_events.empty() ) {
int ret = kevent(event_queue, new_events.data(), new_events.size(), NULL, 0, NULL);
if ( ret != -1 ) {
DBG_LOG(DBG_MAINLOOP, "Unregistered fd %d from %s", fd, src->Tag());
for ( const auto& a : new_events )
events.pop_back();
if ( (flags & IOSource::READ) != 0 )
fd_map.erase(fd);
if ( (flags & IOSource::WRITE) != 0 )
write_fd_map.erase(fd);
if ( (flags & IOSource::READ) != 0 )
fd_map.erase(fd);
if ( (flags & IOSource::WRITE) != 0 )
write_fd_map.erase(fd);
Wakeup("UnregisterFd");
return true;
}
Wakeup("UnregisterFd");
return true;
}
// We don't care about failure here. If it failed to unregister, it's likely because
// the file descriptor was already closed, and kqueue already automatically removed
// it.
}
else
{
reporter->Error("Attempted to unregister an unknown file descriptor %d from %s", fd,
src->Tag());
return false;
}
// We don't care about failure here. If it failed to unregister, it's likely because
// the file descriptor was already closed, and kqueue already automatically removed
// it.
}
else {
reporter->Error("Attempted to unregister an unknown file descriptor %d from %s", fd, src->Tag());
return false;
}
return true;
}
return true;
}
void Manager::Register(IOSource* src, bool dont_count, bool manage_lifetime)
{
// First see if we already have registered that source. If so, just
// adjust dont_count.
for ( const auto& iosrc : sources )
{
if ( iosrc->src == src )
{
if ( iosrc->dont_count != dont_count )
// Adjust the global counter.
dont_counts += (dont_count ? 1 : -1);
void Manager::Register(IOSource* src, bool dont_count, bool manage_lifetime) {
// First see if we already have registered that source. If so, just
// adjust dont_count.
for ( const auto& iosrc : sources ) {
if ( iosrc->src == src ) {
if ( iosrc->dont_count != dont_count )
// Adjust the global counter.
dont_counts += (dont_count ? 1 : -1);
return;
}
}
return;
}
}
src->InitSource();
Source* s = new Source;
s->src = src;
s->dont_count = dont_count;
s->manage_lifetime = manage_lifetime;
if ( dont_count )
++dont_counts;
src->InitSource();
Source* s = new Source;
s->src = src;
s->dont_count = dont_count;
s->manage_lifetime = manage_lifetime;
if ( dont_count )
++dont_counts;
sources.push_back(s);
}
sources.push_back(s);
}
void Manager::Register(PktSrc* src)
{
pkt_src = src;
void Manager::Register(PktSrc* src) {
pkt_src = src;
Register(src, false);
Register(src, false);
// Once we know if the source is live or not, adapt the
// poll_interval accordingly.
//
// Note that src->IsLive() is only valid after calling Register().
if ( src->IsLive() )
poll_interval = BifConst::io_poll_interval_live;
else if ( run_state::pseudo_realtime )
poll_interval = 1;
}
// Once we know if the source is live or not, adapt the
// poll_interval accordingly.
//
// Note that src->IsLive() is only valid after calling Register().
if ( src->IsLive() )
poll_interval = BifConst::io_poll_interval_live;
else if ( run_state::pseudo_realtime )
poll_interval = 1;
}
static std::pair<std::string, std::string> split_prefix(std::string path)
{
// See if the path comes with a prefix telling us which type of
// PktSrc to use. If not, choose default.
std::string prefix;
static std::pair<std::string, std::string> split_prefix(std::string path) {
// See if the path comes with a prefix telling us which type of
// PktSrc to use. If not, choose default.
std::string prefix;
std::string::size_type i = path.find("::");
if ( i != std::string::npos )
{
prefix = path.substr(0, i);
path = path.substr(i + 2, std::string::npos);
}
std::string::size_type i = path.find("::");
if ( i != std::string::npos ) {
prefix = path.substr(0, i);
path = path.substr(i + 2, std::string::npos);
}
else
prefix = DEFAULT_PREFIX;
else
prefix = DEFAULT_PREFIX;
return std::make_pair(prefix, path);
}
return std::make_pair(prefix, path);
}
PktSrc* Manager::OpenPktSrc(const std::string& path, bool is_live)
{
std::pair<std::string, std::string> t = split_prefix(path);
const auto& prefix = t.first;
const auto& npath = t.second;
PktSrc* Manager::OpenPktSrc(const std::string& path, bool is_live) {
std::pair<std::string, std::string> t = split_prefix(path);
const auto& prefix = t.first;
const auto& npath = t.second;
// Find the component providing packet sources of the requested prefix.
// Find the component providing packet sources of the requested prefix.
PktSrcComponent* component = nullptr;
PktSrcComponent* component = nullptr;
std::list<PktSrcComponent*> all_components = plugin_mgr->Components<PktSrcComponent>();
for ( const auto& c : all_components )
{
if ( c->HandlesPrefix(prefix) &&
((is_live && c->DoesLive()) || (! is_live && c->DoesTrace())) )
{
component = c;
break;
}
}
std::list<PktSrcComponent*> all_components = plugin_mgr->Components<PktSrcComponent>();
for ( const auto& c : all_components ) {
if ( c->HandlesPrefix(prefix) && ((is_live && c->DoesLive()) || (! is_live && c->DoesTrace())) ) {
component = c;
break;
}
}
if ( ! component )
reporter->FatalError("type of packet source '%s' not recognized, or mode not supported",
prefix.c_str());
if ( ! component )
reporter->FatalError("type of packet source '%s' not recognized, or mode not supported", prefix.c_str());
// Instantiate packet source.
// Instantiate packet source.
PktSrc* ps = (*component->Factory())(npath, is_live);
assert(ps);
PktSrc* ps = (*component->Factory())(npath, is_live);
assert(ps);
DBG_LOG(DBG_PKTIO, "Created packet source of type %s for %s", component->Name().c_str(),
npath.c_str());
DBG_LOG(DBG_PKTIO, "Created packet source of type %s for %s", component->Name().c_str(), npath.c_str());
Register(ps);
return ps;
}
Register(ps);
return ps;
}
PktDumper* Manager::OpenPktDumper(const std::string& path, bool append)
{
std::pair<std::string, std::string> t = split_prefix(path);
std::string prefix = t.first;
std::string npath = t.second;
PktDumper* Manager::OpenPktDumper(const std::string& path, bool append) {
std::pair<std::string, std::string> t = split_prefix(path);
std::string prefix = t.first;
std::string npath = t.second;
// Find the component providing packet dumpers of the requested prefix.
// Find the component providing packet dumpers of the requested prefix.
PktDumperComponent* component = nullptr;
PktDumperComponent* component = nullptr;
std::list<PktDumperComponent*> all_components = plugin_mgr->Components<PktDumperComponent>();
for ( const auto& c : all_components )
{
if ( c->HandlesPrefix(prefix) )
{
component = c;
break;
}
}
std::list<PktDumperComponent*> all_components = plugin_mgr->Components<PktDumperComponent>();
for ( const auto& c : all_components ) {
if ( c->HandlesPrefix(prefix) ) {
component = c;
break;
}
}
if ( ! component )
reporter->FatalError("type of packet dumper '%s' not recognized", prefix.c_str());
if ( ! component )
reporter->FatalError("type of packet dumper '%s' not recognized", prefix.c_str());
// Instantiate packet dumper.
// Instantiate packet dumper.
PktDumper* pd = (*component->Factory())(npath, append);
assert(pd);
PktDumper* pd = (*component->Factory())(npath, append);
assert(pd);
if ( ! pd->IsOpen() && pd->IsError() )
// Set an error message if it didn't open successfully.
pd->Error("could not open");
if ( ! pd->IsOpen() && pd->IsError() )
// Set an error message if it didn't open successfully.
pd->Error("could not open");
DBG_LOG(DBG_PKTIO, "Created packer dumper of type %s for %s", component->Name().c_str(),
npath.c_str());
DBG_LOG(DBG_PKTIO, "Created packer dumper of type %s for %s", component->Name().c_str(), npath.c_str());
pd->Init();
pkt_dumpers.push_back(pd);
pd->Init();
pkt_dumpers.push_back(pd);
return pd;
}
return pd;
}
} // namespace zeek::iosource
} // namespace zeek::iosource