#openvpn #vpn #cdylib #ffi #plugin #api-bindings

openvpn-plugin

一个允许在Rust中轻松创建OpenVPN插件的crate

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网络编程

Download history 4163/week @ 2024-03-14 6392/week @ 2024-03-21 3060/week @ 2024-03-28 3711/week @ 2024-04-04 4404/week @ 2024-04-11 2951/week @ 2024-04-18 3344/week @ 2024-04-25 3438/week @ 2024-05-02 3482/week @ 2024-05-09 5242/week @ 2024-05-16 4039/week @ 2024-05-23 3308/week @ 2024-05-30 3025/week @ 2024-06-06 3716/week @ 2024-06-13 3812/week @ 2024-06-20 1909/week @ 2024-06-27

每月13,112次下载

MIT/Apache

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