diff --git a/falco_plugin_runner/src/plugin/async_event.rs b/falco_plugin_runner/src/plugin/async_event.rs index b774b21..5ea5231 100644 --- a/falco_plugin_runner/src/plugin/async_event.rs +++ b/falco_plugin_runner/src/plugin/async_event.rs @@ -1,15 +1,18 @@ +use falco_event::events::types::PPME_ASYNCEVENT_E; +use falco_event::events::RawEvent; use falco_plugin_api::{ plugin_api__bindgen_ty_4, ss_plugin_event, ss_plugin_owner_t, ss_plugin_rc, - ss_plugin_rc_SS_PLUGIN_NOT_SUPPORTED, ss_plugin_rc_SS_PLUGIN_SUCCESS, - ss_plugin_rc_SS_PLUGIN_TIMEOUT, ss_plugin_t, + ss_plugin_rc_SS_PLUGIN_FAILURE, ss_plugin_rc_SS_PLUGIN_NOT_SUPPORTED, + ss_plugin_rc_SS_PLUGIN_SUCCESS, ss_plugin_rc_SS_PLUGIN_TIMEOUT, ss_plugin_t, }; use std::collections::VecDeque; -use std::ffi::c_char; +use std::ffi::{c_char, CStr}; use std::sync::{Arc, Mutex}; pub struct AsyncPlugin { plugin: *mut ss_plugin_t, api: *const plugin_api__bindgen_ty_4, + async_events: Vec, last_event: Option>, event_queue: Arc>>>, @@ -17,9 +20,23 @@ pub struct AsyncPlugin { impl AsyncPlugin { pub fn new(plugin: *mut ss_plugin_t, api: *const plugin_api__bindgen_ty_4) -> Self { + let async_events = match unsafe { (*api).get_async_events } { + Some(async_events_fn) => { + let events = unsafe { async_events_fn() }; + if events.is_null() { + Vec::new() + } else { + let sources = unsafe { CStr::from_ptr(events) }; + serde_json::from_slice(sources.to_bytes()).unwrap_or_default() + } + } + None => Vec::new(), + }; + Self { plugin, api, + async_events, last_event: None, event_queue: Arc::new(Mutex::new(VecDeque::new())), } @@ -81,6 +98,26 @@ unsafe extern "C-unwind" fn async_handler( let event = event as *const u8; let event = unsafe { std::slice::from_raw_parts(event, evt_len) }; + let Ok(raw_event) = RawEvent::from(event) else { + return ss_plugin_rc_SS_PLUGIN_FAILURE; + }; + + let Ok(async_event) = raw_event.load::() else { + return ss_plugin_rc_SS_PLUGIN_FAILURE; + }; + + let Some(async_event_name) = async_event.params.name else { + return ss_plugin_rc_SS_PLUGIN_FAILURE; + }; + + let Ok(async_event_name) = async_event_name.to_str() else { + return ss_plugin_rc_SS_PLUGIN_FAILURE; + }; + + if !owner.async_events.iter().any(|evt| evt == async_event_name) { + return ss_plugin_rc_SS_PLUGIN_FAILURE; + } + owner.event_queue.lock().unwrap().push_back(event.to_vec()); ss_plugin_rc_SS_PLUGIN_SUCCESS diff --git a/falco_plugin_tests/tests/async.rs b/falco_plugin_tests/tests/async.rs index 2cd0e9e..e6eca6b 100644 --- a/falco_plugin_tests/tests/async.rs +++ b/falco_plugin_tests/tests/async.rs @@ -82,7 +82,23 @@ impl AsyncEventPlugin for DummyPlugin { metadata, params: event, }; - handler.emit(event) + handler.emit(event)?; + + let event = AsyncEvent { + plugin_id: Some(0), + name: Some(c"invalid_event_name"), + data: Some(b"hello"), + }; + + let metadata = EventMetadata::default(); + + let event = Event { + metadata, + params: event, + }; + assert!(handler.emit(event).is_err()); + + Ok(()) })?); Ok(())