Changeset - fdc328afed95
[Not reviewed]
0 4 0
Christopher Esterhuyse - 5 years ago 2020-07-22 16:27:23
christopher.esterhuyse@gmail.com
adapted examples to platform independent ffi. toward linux-specific pseudo-socket API
4 files changed with 75 insertions and 32 deletions:
0 comments (0 inline, 0 general)
Cargo.toml
Show inline comments
 
@@ -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
reowolf.h
Show inline comments
 
@@ -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 */
src/ffi/mod.rs
Show inline comments
 
@@ -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 //////////////////////////
 

	
src/ffi/pseudo_socket_api.rs
Show inline comments
 
@@ -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<c_int, RwLock<ConnectorComplex>>,
 
    fd_allocator: FdAllocator,
 
}
 
///////////////////////////////////////////////////////////////////
 
fn addr_from_raw(addr: *const sockaddr, addr_len: socklen_t) -> Option<SocketAddr> {
 
    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,
 
        _ => {}
 
    }
0 comments (0 inline, 0 general)