diff --git a/Cargo.toml b/Cargo.toml index 15902eef642a795c2e76ddc22d54e0a16765765a..5f1e68510393469cb1371289729c829c99d8052f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,11 @@ socket2 = { version = "0.3.12", optional = true } backtrace = "0.3" lazy_static = "1.4.0" +# ffi + # socket ffi -atomic_refcell = { version = "0.1.6", optional = true } +libc = { version = "^0.2", optional = true } +os_socketaddr = { verion = "0.1.0", optional = true } [dev-dependencies] # test-generator = "0.3.0" @@ -38,8 +41,8 @@ lazy_static = "1.4.0" crate-type = ["cdylib"] [features] -default = ["ffi", "ffi_socket_api"] # // "session_optimization", -ffi = [] # see src/ffi.rs -ffi_socket_api = ["ffi", "atomic_refcell", "socket2"] +default = ["ffi", "session_optimization"] +ffi = [] # see src/ffi/mod.rs +ffi_pseudo_socket_api = ["ffi", "libc", "os_socketaddr"]# see src/ffi/pseudo_socket_api.rs endpoint_logging = [] # see src/macros.rs session_optimization = [] # see src/runtime/setup.rs \ No newline at end of file diff --git a/reowolf.h b/reowolf.h index 5646ed438f5a698d1bb43ae9e8f9588e2105795e..5f92cd04f9b15e7f4a2b06ac05d8d53be22ba8a9 100644 --- a/reowolf.h +++ b/reowolf.h @@ -173,4 +173,30 @@ Arc_ProtocolDescription *protocol_description_parse(const uint8_t *pdl, uintptr_ */ const uint8_t *reowolf_error_peek(uintptr_t *len); +int rw_bind(int fd, const SocketAddr *local_addr, uintptr_t _addr_len); + +int rw_close(int fd, int _how); + +int rw_connect(int fd, const SocketAddr *peer_addr, uintptr_t _address_len); + +intptr_t rw_recv(int fd, void *bytes_ptr, uintptr_t bytes_len, int _flags); + +intptr_t rw_recvfrom(int fd, + void *bytes_ptr, + uintptr_t bytes_len, + int _flags, + const SocketAddr *peer_addr, + uintptr_t _addr_len); + +intptr_t rw_send(int fd, const void *bytes_ptr, uintptr_t bytes_len, int _flags); + +intptr_t rw_sendto(int fd, + void *bytes_ptr, + uintptr_t bytes_len, + int _flags, + const SocketAddr *peer_addr, + uintptr_t _addr_len); + +int rw_socket(int _domain, int _type); + #endif /* REOWOLF_HEADER_DEFINED */ diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 4e73ff40eed1c71c33681377f3708b34eb2067c2..653b6e4a0a28adb7def9dae7cac31834ba841ead 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -3,8 +3,8 @@ use core::{cell::RefCell, convert::TryFrom}; use std::os::raw::c_int; use std::slice::from_raw_parts as slice_from_raw_parts; -// #[cfg(feature = "ffi_pseudo_socket_api")] -// pub mod pseudo_socket_api; +#[cfg(all(target_os = "linux", feature = "ffi_pseudo_socket_api"))] +pub mod pseudo_socket_api; // Temporary simplfication: ignore ipv6. To revert, just refactor this structure and its usages #[repr(C)] @@ -99,6 +99,7 @@ pub const CLOSE_FAIL: c_int = -4; pub const BAD_FD: c_int = -5; pub const CONNECT_FAILED: c_int = -6; pub const WOULD_BLOCK: c_int = -7; +pub const BAD_SOCKADDR: c_int = -8; ///////////////////// REOWOLF ////////////////////////// diff --git a/src/ffi/pseudo_socket_api.rs b/src/ffi/pseudo_socket_api.rs index 1f0c2420325a69e3589d0480e4727376bb17857b..3a1e794848d59b518b93df3560831cc92bea545a 100644 --- a/src/ffi/pseudo_socket_api.rs +++ b/src/ffi/pseudo_socket_api.rs @@ -3,6 +3,7 @@ use super::*; use std::{ collections::HashMap, ffi::c_void, + libc::{sockaddr, socklen_t}, net::{Ipv4Addr, SocketAddr, SocketAddrV4}, os::raw::c_int, sync::RwLock, @@ -32,12 +33,14 @@ struct CcMap { fd_to_cc: HashMap>, fd_allocator: FdAllocator, } +/////////////////////////////////////////////////////////////////// +fn addr_from_raw(addr: *const sockaddr, addr_len: socklen_t) -> Option { + os_socketaddr::OsSocketAddr::from_raw_parts(addr, addr_len as usize).into_addr() +} fn trivial_peer_addr() -> SocketAddr { // SocketAddrV4::new isn't a constant-time func SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0)) } -/////////////////////////////////////////////////////////////////// - impl Default for FdAllocator { fn default() -> Self { Self { @@ -132,11 +135,11 @@ pub extern "C" fn rw_close(fd: c_int, _how: c_int) -> c_int { } #[no_mangle] -pub unsafe extern "C" fn rw_bind( - fd: c_int, - local_addr: *const SocketAddr, - _addr_len: usize, -) -> c_int { +pub unsafe extern "C" fn rw_bind(fd: c_int, addr: *const sockaddr, addr_len: socklen_t) -> c_int { + let addr = match addr_from_raw(addr, addr_len) { + Some(addr) => addr, + _ => return BAD_SOCKADDR, + }; // assuming _domain is AF_INET and _type is SOCK_DGRAM let r = if let Ok(r) = CC_MAP.read() { r } else { return CC_MAP_LOCK_POISONED }; let cc = if let Some(cc) = r.fd_to_cc.get(&fd) { cc } else { return BAD_FD }; @@ -151,8 +154,7 @@ pub unsafe extern "C" fn rw_bind( crate::TRIVIAL_PD.clone(), Connector::random_id(), ); - let [putter, getter] = - connector.new_udp_mediator_component(local_addr.read(), cc.peer_addr).unwrap(); + let [putter, getter] = connector.new_udp_mediator_component(addr, cc.peer_addr).unwrap(); Some(ConnectorBound { connector, putter, getter, is_nonblocking: false }) }; ERR_OK @@ -161,15 +163,19 @@ pub unsafe extern "C" fn rw_bind( #[no_mangle] pub unsafe extern "C" fn rw_connect( fd: c_int, - peer_addr: *const SocketAddr, - _address_len: usize, + addr: *const sockaddr, + addr_len: socklen_t, ) -> c_int { + let addr = match addr_from_raw(addr, addr_len) { + Some(addr) => addr, + _ => return BAD_SOCKADDR, + }; // assuming _domain is AF_INET and _type is SOCK_DGRAM let r = if let Ok(r) = CC_MAP.read() { r } else { return CC_MAP_LOCK_POISONED }; let cc = if let Some(cc) = r.fd_to_cc.get(&fd) { cc } else { return BAD_FD }; let mut cc = if let Ok(cc) = cc.write() { cc } else { return CC_MAP_LOCK_POISONED }; let cc: &mut ConnectorComplex = &mut cc; - cc.connect(peer_addr.read()) + cc.connect(addr) } #[no_mangle] @@ -208,46 +214,53 @@ pub unsafe extern "C" fn rw_sendto( bytes_ptr: *mut c_void, bytes_len: usize, _flags: c_int, - peer_addr: *const SocketAddr, - _addr_len: usize, + addr: *const sockaddr, + addr_len: socklen_t, ) -> isize { + let addr = match addr_from_raw(addr, addr_len) { + Some(addr) => addr, + _ => return BAD_SOCKADDR, + }; let r = if let Ok(r) = CC_MAP.read() { r } else { return CC_MAP_LOCK_POISONED as isize }; let cc = if let Some(cc) = r.fd_to_cc.get(&fd) { cc } else { return BAD_FD as isize }; let mut cc = if let Ok(cc) = cc.write() { cc } else { return CC_MAP_LOCK_POISONED as isize }; let cc: &mut ConnectorComplex = &mut cc; - // copy currently connected peer addr - let connected = cc.peer_addr; + // copy currently old_addr + let old_addr = cc.peer_addr; // connect to given peer_addr - match cc.connect(peer_addr.read()) { + match cc.connect(addr) { e if e != ERR_OK => return e as isize, _ => {} } // send let ret = cc.send(bytes_ptr, bytes_len); - // restore connected peer addr - match cc.connect(connected) { + // restore old_addr + match cc.connect(old_addr) { e if e != ERR_OK => return e as isize, _ => {} } ret } -#[no_mangle] #[no_mangle] pub unsafe extern "C" fn rw_recvfrom( fd: c_int, bytes_ptr: *mut c_void, bytes_len: usize, _flags: c_int, - peer_addr: *const SocketAddr, - _addr_len: usize, + addr: *const sockaddr, + addr_len: socklen_t, ) -> isize { + let addr = match addr_from_raw(addr, addr_len) { + Some(addr) => addr, + _ => return BAD_SOCKADDR, + }; let r = if let Ok(r) = CC_MAP.read() { r } else { return CC_MAP_LOCK_POISONED as isize }; let cc = if let Some(cc) = r.fd_to_cc.get(&fd) { cc } else { return BAD_FD as isize }; let mut cc = if let Ok(cc) = cc.write() { cc } else { return CC_MAP_LOCK_POISONED as isize }; let cc: &mut ConnectorComplex = &mut cc; - // copy currently connected peer addr - let connected = cc.peer_addr; + // copy currently old_addr + let old_addr = cc.peer_addr; // connect to given peer_addr match cc.connect(peer_addr.read()) { e if e != ERR_OK => return e as isize, @@ -255,8 +268,8 @@ pub unsafe extern "C" fn rw_recvfrom( } // send let ret = cc.send(bytes_ptr, bytes_len); - // restore connected peer addr - match cc.connect(connected) { + // restore old_addr + match cc.connect(old_addr) { e if e != ERR_OK => return e as isize, _ => {} }