From c01298f83912707021d6c1a88289465be48e12a4 Mon Sep 17 00:00:00 2001 From: Mariappan Ramasamy <142216110+kp-mariappan-ramasamy@users.noreply.github.com> Date: Mon, 27 May 2024 14:23:38 +0800 Subject: [PATCH] CVPN-793: add plugin documentation with example plugin --- docs/README.md | 1 + docs/plugins.md | 79 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 docs/plugins.md diff --git a/docs/README.md b/docs/README.md index 2bcb16e..384dc6e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,6 +3,7 @@ * [Connection State Machine](connection_state_machine.md) * [UDP Session ID Rotation](udp_session_id.md) * [PMTU Discovery](pmtu_discovery.md) +* [Plugin architecture](plugins.md) # Miscellaneous diff --git a/docs/plugins.md b/docs/plugins.md new file mode 100644 index 0000000..1b82969 --- /dev/null +++ b/docs/plugins.md @@ -0,0 +1,79 @@ +# Plugins + +Plugins provides a way to control traffic flowing throught Lightway protocol. +Applications can create a custom plugin and attach it to client or server. + +Plugins can be constructed by implementing the following trait (Ref: `lightway_core::Plugin`) + +```rust +pub trait Plugin { + /// Hook to run during packet ingress + fn ingress(&self, data: &mut BytesMut) -> PluginResult; + + /// Hook to run during packet egress + fn egress(&self, data: &mut BytesMut) -> PluginResult; +} +``` + + +The following is an example plugin to drop packets destined to a particular IP address. + +```rust +use pnet::packet::ipv4::Ipv4Packet; +use pnet::packet::tcp::TcpPacket; + +#[derive(Clone, Debug)] +struct IpFilter(Ipv4Address); + +impl IpFilter { + pub fn new(ip: Ipv4Address) -> Self { + Self(ip) + } +} + +impl Plugin for IpFilter { + fn ingress(&self, data: &mut BytesMut) -> PluginResult { + let mut packet = Ipv4Packet::new(pkt)?; + if packet.get_source() == self.0 { + PluginResult::Drop + } else { + PluginResult::Accept + } + } + + fn egress(&self, data: &mut BytesMut) -> PluginResult { + let mut packet = Ipv4Packet::new(pkt)?; + if packet.get_source() == self.0 { + PluginResult::Drop + } else { + PluginResult::Accept + } + } +} + +pub struct IpFilterPluginFactory { + filter: IpFilter, +}; + +impl IpFilterPluginFactory { + pub fn new(ip: Ipv4Address) -> Self { + let filter = IpFilter::new(ip); + Self { filter } + } +} + +impl PluginFactory for IpFilterPluginFactory { + fn build(&self) -> Result { + let filter = self.filter.clone(); + Ok(Box::new(filter)) + } +} + +``` + +Plugin factory's instance can be created and attached to a factory list `lightway_client::PluginFactoryList` + +And this plugin factory list can be applied to a client or server by sending it as an argument: +`lightway_client::ClientConfig::inside_plugins` or `lightway_server:ServerConfig::inside_plugins` + +to `lightway_client::client` or `lightway_server::server` api to filter traffic.