falco_plugin/plugin/async_event/
mod.rs

1use crate::base::Plugin;
2use crate::plugin::async_event::async_handler::AsyncHandler;
3use crate::plugin::async_event::wrappers::AsyncPluginExported;
4
5use falco_event::events::types::PPME_ASYNCEVENT_E as AsyncEvent;
6use falco_event::events::Event;
7
8pub mod async_handler;
9pub mod background_task;
10#[doc(hidden)]
11pub mod wrappers;
12
13/// # Support for asynchronous event plugins
14pub trait AsyncEventPlugin: Plugin + AsyncPluginExported {
15    /// # Event names coming from this plugin
16    ///
17    /// This constant contains a list describing the name list of all asynchronous events
18    /// that this plugin is capable of pushing into a live event stream. The framework rejects
19    /// async events produced by a plugin if their name is not on the name list returned by this
20    /// function.
21    const ASYNC_EVENTS: &'static [&'static str];
22    /// # Event sources to attach asynchronous events to
23    ///
24    /// This constant contains a list describing the event sources for which this plugin
25    /// is capable of injecting async events in the event stream of a capture.
26    ///
27    /// This is optional--if NULL or an empty array, then async events produced by this plugin will
28    /// be injected in the event stream of any data source.
29    ///
30    /// **Note**: one notable event source is called `syscall`
31    const EVENT_SOURCES: &'static [&'static str];
32
33    /// # Start asynchronous event generation
34    ///
35    /// When this method is called, your plugin should start whatever background mechanism
36    /// is necessary (e.g. spawn a separate thread) and use the [`AsyncHandler::emit`] method
37    /// to inject events to the main event loop.
38    ///
39    /// **Note**: you must provide a mechanism to shut down the thread upon a call to [`AsyncEventPlugin::stop_async`].
40    /// This may involve e.g. a [`std::sync::Condvar`] that's checked via [`std::sync::Condvar::wait_timeout`]
41    /// by the thread.
42    ///
43    /// **Note**: one notable event source is called `syscall`
44    fn start_async(&mut self, handler: AsyncHandler) -> Result<(), anyhow::Error>;
45
46    /// # Stop asynchronous event generation
47    ///
48    /// When this method is called, your plugin must stop the background mechanism started by
49    /// [`AsyncEventPlugin::start_async`] and wait for it to finish (no calls to [`AsyncHandler::emit`]
50    /// are permitted after this method returns).
51    ///
52    /// **Note**: [`AsyncEventPlugin::start_async`] can be called again, with a different [`AsyncHandler`].
53    fn stop_async(&mut self) -> Result<(), anyhow::Error>;
54
55    /// # Dump the plugin state as a series of async events
56    ///
57    /// When this method is called, your plugin may save its state via a series of async events
58    /// that will be replayed when a capture file is loaded.
59    ///
60    /// The default implementation does nothing.
61    fn dump_state(&mut self, _handler: AsyncHandler) -> Result<(), anyhow::Error> {
62        Ok(())
63    }
64
65    /// # A helper method to create an asynchronous event
66    fn async_event<'a>(name: &'a std::ffi::CStr, data: &'a [u8]) -> Event<AsyncEvent<'a>> {
67        let event = AsyncEvent {
68            plugin_id: None, // gets populated by the framework, shall be None
69            name: Some(name),
70            data: Some(data),
71        };
72
73        let metadata = falco_event::events::EventMetadata::default();
74
75        Event {
76            metadata,
77            params: event,
78        }
79    }
80}