libgvproxy_sys/lib.rs
1//! Low-level FFI bindings to libgvproxy
2//!
3//! This crate provides raw, unsafe bindings to the gvproxy-bridge C library.
4//! For a safe, idiomatic Rust API, use the higher-level wrapper in the boxlite crate.
5
6use std::os::raw::{c_char, c_int, c_longlong, c_void};
7
8/// Logging callback function type
9///
10/// Called by Go's slog handler to forward log messages to Rust.
11///
12/// # Arguments
13/// * `level` - Log level (0=trace, 1=debug, 2=info, 3=warn, 4=error)
14/// * `message` - Log message (null-terminated C string)
15pub type LogCallbackFn = extern "C" fn(level: c_int, message: *const c_char);
16
17extern "C" {
18 /// Create a new gvproxy instance with port mappings
19 ///
20 /// # Arguments
21 /// * `portMappingsJSON` - JSON string describing port mappings
22 ///
23 /// # Returns
24 /// Instance ID (handle) or -1 on error
25 pub fn gvproxy_create(portMappingsJSON: *const c_char) -> c_longlong;
26
27 /// Free a string allocated by libgvproxy
28 ///
29 /// # Arguments
30 /// * `str` - Pointer to string returned by gvproxy functions
31 pub fn gvproxy_free_string(str: *mut c_char);
32
33 /// Destroy a gvproxy instance and free resources
34 ///
35 /// # Arguments
36 /// * `id` - Instance ID to destroy
37 ///
38 /// # Returns
39 /// 0 on success, non-zero on error
40 pub fn gvproxy_destroy(id: c_longlong) -> c_int;
41
42 /// Get network statistics for a gvproxy instance
43 ///
44 /// Returns a JSON string containing network statistics including:
45 /// - bytes_sent, bytes_received: Total bandwidth
46 /// - tcp.forward_max_inflight_drop: Packets dropped due to maxInFlight limit
47 /// - tcp.current_established: Active TCP connections
48 /// - tcp.failed_connection_attempts: Total connection failures
49 /// - tcp.retransmits: TCP segments retransmitted
50 /// - tcp.timeouts: RTO timeout events
51 ///
52 /// # Arguments
53 /// * `id` - Instance ID returned from gvproxy_create
54 ///
55 /// # Returns
56 /// Pointer to JSON string (must be freed with gvproxy_free_string), or NULL if:
57 /// - Instance doesn't exist
58 /// - VirtualNetwork not initialized yet
59 /// - Stats collection or serialization failed
60 ///
61 /// # Safety
62 /// - `id` must be a valid instance ID
63 /// - Returned pointer must be freed with gvproxy_free_string
64 /// - Do not use pointer after calling gvproxy_free_string
65 pub fn gvproxy_get_stats(id: c_longlong) -> *mut c_char;
66
67 /// Get the libgvproxy version string
68 ///
69 /// # Returns
70 /// Pointer to version string (must be freed with gvproxy_free_string)
71 pub fn gvproxy_get_version() -> *mut c_char;
72
73 /// Set the log callback function for routing gvproxy logs to Rust
74 ///
75 /// When set, Go's slog handler will call this callback for all log messages,
76 /// allowing integration with Rust's tracing system.
77 ///
78 /// # Arguments
79 /// * `callback` - Function pointer to Rust logging callback, or NULL to disable
80 ///
81 /// # Safety
82 /// The callback must be thread-safe and must not panic.
83 /// Pass NULL to restore default stderr logging.
84 pub fn gvproxy_set_log_callback(callback: *const c_void);
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn test_version() {
93 unsafe {
94 let version = gvproxy_get_version();
95 assert!(!version.is_null());
96 gvproxy_free_string(version);
97 }
98 }
99}