From c421b93f9e93a9ff0ca05d93f8d6854143e7cfe9 Mon Sep 17 00:00:00 2001 From: Jackson Coxson Date: Sat, 25 Jun 2022 15:59:13 -0600 Subject: [PATCH] Fix clippy warnings for safety docs --- src/ffi.rs | 237 ++++++++++++++++++++++++++++------------------------- 1 file changed, 126 insertions(+), 111 deletions(-) diff --git a/src/ffi.rs b/src/ffi.rs index 71541ab..c21c5e7 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -11,11 +11,19 @@ use crate::{ start_tunnels, }; +/// Starts a new onetun tunnel +/// # Arguments +/// * `config` - The configuration for the tunnel, generated with `onetun_new_config` +/// * `bus` - The bus to publish events on, generated with `onetun_new_bus` +/// # Returns +/// 0 on success, non-zero on failure +/// # Safety +/// All pointers must be valid and not null. #[no_mangle] -pub extern "C" fn onetun_start_tunnels(config: *mut config::Config, bus: *mut Bus) -> i32 { +pub unsafe extern "C" fn onetun_start_tunnels(config: *mut config::Config, bus: *mut Bus) -> i32 { // Unbox the structs - let config = unsafe { *(std::boxed::Box::from_raw(config)) }; - let bus = unsafe { *(std::boxed::Box::from_raw(bus)) }; + let config = *(std::boxed::Box::from_raw(config)); + let bus = *(std::boxed::Box::from_raw(bus)); // Create a runtime for the future let rt = match tokio::runtime::Builder::new_multi_thread() @@ -42,8 +50,27 @@ pub extern "C" fn onetun_start_tunnels(config: *mut config::Config, bus: *mut Bu 0 } +/// Creates a new config struct for starting a tunnel +/// # Arguments +/// * `port_forwards` - A pointer to an array of pointers to port forwards, generated with `onetun_new_port_forward` +/// * `port_forwards_len` - The length of the array of pointers to port forwards +/// * `remote_forwards` - A pointer to an array of pointers to port forwards, generated with `onetun_new_port_forward` +/// * `remote_forwards_len` - The length of the array of pointers to port forwards +/// * `private_key` - A pointer to an array of chars containing the private key +/// * `public_key` - A pointer to an array of chars containing the public key +/// * `endpoint_addr` - A pointer to an array of chars containing the endpoint address +/// * `endpoint_bind_addr` - A pointer to an array of chars containing the endpoint bind address +/// * `source_peer_ip` - A pointer to an array of chars containing the source peer IP address +/// * `keepalive_seconds` - A number representing the keepalive interval, or -1 for None +/// * `max_transmission_unit` - A number representing the maximum transmission unit +/// * `log` - A pointer to an array of chars containing the log level (e.g. "INFO", "DEBUG", "TRACE") +/// * `pcap_file` - A pointer to an array of chars containing the pcap file path, or NULL for none +/// # Returns +/// A pointer to a config struct, or NULL on failure +/// # Safety +/// All pointers must be valid and not null, unless specified and expected to be NULL. #[no_mangle] -pub extern "C" fn onetun_new_config( +pub unsafe extern "C" fn onetun_new_config( port_forwards: *const *mut config::PortForwardConfig, port_forwards_len: c_uint, remote_forwards: *const *mut config::PortForwardConfig, @@ -59,99 +86,78 @@ pub extern "C" fn onetun_new_config( pcap_file: *const c_char, ) -> *mut config::Config { // Convert the port configs to a vector of PortForwardConfigs ending with a null pointer - let port_forwards = unsafe { - std::slice::from_raw_parts(port_forwards, port_forwards_len as usize) - .iter() - .filter(|&&x| (!x.is_null() || x != 0 as *mut _)) - .map(|&x| *(std::boxed::Box::from_raw(x))) - .map(|x| x.clone()) - .collect::>() - }; - let remote_forwards = unsafe { - std::slice::from_raw_parts(remote_forwards, remote_forwards_len as usize) - .iter() - .filter(|&&x| (!x.is_null() || x != 0 as *mut _)) - .map(|&x| *(std::boxed::Box::from_raw(x))) - .map(|x| x.clone()) - .collect::>() - }; + let port_forwards = std::slice::from_raw_parts(port_forwards, port_forwards_len as usize) + .iter() + .filter(|&&x| !x.is_null()) + .map(|&x| *(std::boxed::Box::from_raw(x))) + .collect::>(); + let remote_forwards = std::slice::from_raw_parts(remote_forwards, remote_forwards_len as usize) + .iter() + .filter(|&&x| !x.is_null()) + .map(|&x| *(std::boxed::Box::from_raw(x))) + .collect::>(); // Convert the c_chars to &str's - let private_key = unsafe { - match std::ffi::CStr::from_ptr(private_key).to_str() { - Ok(x) => match config::X25519SecretKey::from_str(x) { - Ok(x) => x, - Err(e) => { - println!("Error parsing private key: {}", e); - return std::ptr::null_mut(); - } - }, - Err(_) => return std::ptr::null_mut(), - } - }; - let public_key = unsafe { - match std::ffi::CStr::from_ptr(public_key).to_str() { - Ok(x) => match config::X25519PublicKey::from_str(x) { - Ok(x) => x, - Err(e) => { - println!("Error parsing public key: {}", e); - return std::ptr::null_mut(); - } - }, - Err(_) => return std::ptr::null_mut(), - } - }; - let endpoint_addr = unsafe { - match std::ffi::CStr::from_ptr(endpoint_addr).to_str() { - Ok(x) => match config::parse_addr(Some(x)) { - Ok(x) => x, - Err(e) => { - println!("Error parsing endpoint address: {}", e); - return std::ptr::null_mut(); - } - }, - Err(_) => return std::ptr::null_mut(), - } - }; - let endpoint_bind_addr = unsafe { - match std::ffi::CStr::from_ptr(endpoint_bind_addr).to_str() { - Ok(x) => match config::parse_addr(Some(x)) { - Ok(x) => x, - Err(e) => { - println!("Error parsing endpoint bind address: {}", e); - return std::ptr::null_mut(); - } - }, - Err(_) => return std::ptr::null_mut(), - } - }; - let source_peer_ip = unsafe { - match std::ffi::CStr::from_ptr(source_peer_ip).to_str() { - Ok(x) => match config::parse_ip(Some(x)) { - Ok(x) => x, - Err(e) => { - println!("Error parsing source peer IP: {}", e); - return std::ptr::null_mut(); - } - }, - Err(_) => return std::ptr::null_mut(), - } - }; - let log = unsafe { - match std::ffi::CStr::from_ptr(log).to_str() { - Ok(x) => x.to_string(), - Err(_) => return std::ptr::null_mut(), - } - }; - let pcap_file = unsafe { - match std::ffi::CStr::from_ptr(pcap_file).to_str() { - Ok(x) => { - if x == "" { - None - } else { - Some(x.to_string()) - } + let private_key = match std::ffi::CStr::from_ptr(private_key).to_str() { + Ok(x) => match config::X25519SecretKey::from_str(x) { + Ok(x) => x, + Err(e) => { + println!("Error parsing private key: {}", e); + return std::ptr::null_mut(); } + }, + Err(_) => return std::ptr::null_mut(), + }; + let public_key = match std::ffi::CStr::from_ptr(public_key).to_str() { + Ok(x) => match config::X25519PublicKey::from_str(x) { + Ok(x) => x, + Err(e) => { + println!("Error parsing public key: {}", e); + return std::ptr::null_mut(); + } + }, + Err(_) => return std::ptr::null_mut(), + }; + let endpoint_addr = match std::ffi::CStr::from_ptr(endpoint_addr).to_str() { + Ok(x) => match config::parse_addr(Some(x)) { + Ok(x) => x, + Err(e) => { + println!("Error parsing endpoint address: {}", e); + return std::ptr::null_mut(); + } + }, + Err(_) => return std::ptr::null_mut(), + }; + let endpoint_bind_addr = match std::ffi::CStr::from_ptr(endpoint_bind_addr).to_str() { + Ok(x) => match config::parse_addr(Some(x)) { + Ok(x) => x, + Err(e) => { + println!("Error parsing endpoint bind address: {}", e); + return std::ptr::null_mut(); + } + }, + Err(_) => return std::ptr::null_mut(), + }; + let source_peer_ip = match std::ffi::CStr::from_ptr(source_peer_ip).to_str() { + Ok(x) => match config::parse_ip(Some(x)) { + Ok(x) => x, + Err(e) => { + println!("Error parsing source peer IP: {}", e); + return std::ptr::null_mut(); + } + }, + Err(_) => return std::ptr::null_mut(), + }; + let log = match std::ffi::CStr::from_ptr(log).to_str() { + Ok(x) => x.to_string(), + Err(_) => return std::ptr::null_mut(), + }; + + let pcap_file = if pcap_file.is_null() { + None + } else { + match std::ffi::CStr::from_ptr(pcap_file).to_str() { + Ok(x) => Some(x.to_string()), Err(_) => return std::ptr::null_mut(), } }; @@ -182,37 +188,46 @@ pub extern "C" fn onetun_new_config( Box::into_raw(Box::new(config)) as *mut config::Config } +/// Creates a new bus struct +/// # Arguments +/// *none* +/// # Returns +/// A pointer to a bus struct #[no_mangle] pub extern "C" fn onetun_new_bus() -> *mut Bus { let bus = Bus::new(); Box::into_raw(Box::new(bus)) as *mut Bus } +/// Creates a new port forward configuration +/// # Arguments +/// * `source` - A list of chars representing a socket address +/// * `destination` - A list of chars representing a socket address +/// * `protocol` - Either `tcp` or `udp` +/// * `port` - Whether this forward is remote: 1 for true, 0 for false +/// # Returns +/// A pointer to a port forward config struct, or NULL on failure +/// # Safety +/// All pointers must be valid. Strings may be freed after this function returns. #[no_mangle] -pub extern "C" fn onetun_new_port_forward( +pub unsafe extern "C" fn onetun_new_port_forward( source: *const c_char, destination: *const c_char, protocol: *const c_char, remote: c_uint, ) -> *mut config::PortForwardConfig { // Create strings from pointers - let source = unsafe { - match std::ffi::CStr::from_ptr(source).to_str() { - Ok(s) => s, - Err(_) => return std::ptr::null_mut(), - } + let source = match std::ffi::CStr::from_ptr(source).to_str() { + Ok(s) => s, + Err(_) => return std::ptr::null_mut(), }; - let destination = unsafe { - match std::ffi::CStr::from_ptr(destination).to_str() { - Ok(s) => s, - Err(_) => return std::ptr::null_mut(), - } + let destination = match std::ffi::CStr::from_ptr(destination).to_str() { + Ok(s) => s, + Err(_) => return std::ptr::null_mut(), }; - let protocol = unsafe { - match std::ffi::CStr::from_ptr(protocol).to_str() { - Ok(s) => s.to_lowercase(), - Err(_) => return std::ptr::null_mut(), - } + let protocol = match std::ffi::CStr::from_ptr(protocol).to_str() { + Ok(s) => s.to_lowercase(), + Err(_) => return std::ptr::null_mut(), }; // Create config @@ -232,7 +247,7 @@ pub extern "C" fn onetun_new_port_forward( "udp" => config::PortProtocol::Udp, _ => return std::ptr::null_mut(), }, - remote: remote == 0, + remote: remote == 1, }; // Create pointer to config