6个版本 (3个重大更新)
0.4.2 | 2023年2月21日 |
---|---|
0.4.1 | 2021年1月12日 |
0.4.0 | 2020年11月16日 |
0.3.0 | 2017年10月13日 |
0.1.0 | 2017年7月19日 |
#808 在 网络编程
每月13,112次下载
36KB
498 行
openvpn-plugin
是一个crate,它使得在Rust中编写OpenVPN插件变得简单。
该crate包含两个主要部分
- 用于生成OpenVPN将与之交互的FFI接口的
openvpn_plugin!
宏 - 与OpenVPN通信所需的FFI和安全的Rust类型。
用法
编辑您的 Cargo.toml
以依赖此crate,并将crate的类型设置为 cdylib
以将其编译为OpenVPN可以理解的共享库。
[lib]
crate-type = ["cdylib"]
[dependencies]
openvpn-plugin = "x.y"
在crate根目录(lib.rs
)中定义您的处理类型、三个回调函数,并调用 openvpn_plugin!
宏以生成相应的FFI绑定。有关处理和回调函数的更多详细信息,请参阅 openvpn_plugin!
宏的文档。
use std::collections::HashMap;
use std::ffi::CString;
use std::io::Error;
use openvpn_plugin::{openvpn_plugin, EventResult, EventType};
pub struct Handle {
// Fields needed for the plugin to keep state between callbacks
}
fn openvpn_open(
args: Vec<CString>,
env: HashMap<CString, CString>,
) -> Result<(Vec<EventType>, Handle), Error> {
// Listen to only the `Up` event, which will be fired when a tunnel has been established.
let events = vec![EventType::Up];
// Create the handle instance.
let handle = Handle { /* ... */ };
Ok((events, handle))
}
fn openvpn_close(handle: Handle) {
println!("Plugin is closing down");
}
fn openvpn_event(
event: EventType,
args: Vec<CString>,
env: HashMap<CString, CString>,
handle: &mut Handle,
) -> Result<EventResult, Error> {
/* Process the event */
// If the processing worked fine and/or the request the callback represents should be
// accepted, return EventResult::Success. See EventResult docs for more info.
Ok(EventResult::Success)
}
openvpn_plugin!(crate::openvpn_open, crate::openvpn_close, crate::openvpn_event, Handle);
恐慌处理
C无法处理Rust恐慌的展开,因此当从C调用时,允许Rust恐慌不是一种好做法。正因为如此,所有从此crate到提供给 openvpn_plugin!
($open_fn
、$close_fn
和 $event_fn
)的回调的调用都被包装在 catch_unwind
中。
如果 catch_unwind
捕获到一个恐慌,它将记录它,然后返回 OPENVPN_PLUGIN_FUNC_ERROR
到OpenVPN。
请注意,这将仅对展开的恐慌起作用,而不是对 panic=abort
。
日志记录
用户定义的回调函数返回的错误或Rust中任何地方发生的panic都会在控制权返回给OpenVPN之前由这个crate记录。默认情况下,日志记录到stderr。要使用error!
宏在log
crate中激活日志记录,需要用log
功能构建这个crate。
依赖项
~1.5MB
~37K SLoC