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}