Changeset - e223cf27bf2e
[Not reviewed]
0 2 0
Christopher Esterhuyse - 5 years ago 2020-07-23 15:30:40
christopher.esterhuyse@gmail.com
fixed botched branch merge
2 files changed with 21 insertions and 57 deletions:
0 comments (0 inline, 0 general)
Cargo.toml
Show inline comments
 
@@ -41,7 +41,7 @@ lazy_static = "1.4.0"
 
crate-type = ["cdylib"]
 

	
 
[features]
 
default = ["ffi", "session_optimization"]
 
default = ["ffi", "session_optimization", "ffi_pseudo_socket_api"]
 
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
src/ffi/pseudo_socket_api.rs
Show inline comments
 
@@ -4,7 +4,7 @@ use libc::{sockaddr, socklen_t};
 
use std::{
 
    collections::HashMap,
 
    ffi::c_void,
 
    net::{Ipv4Addr, SocketAddr, SocketAddrV4},
 
    net::SocketAddr,
 
    os::raw::c_int,
 
    sync::RwLock,
 
};
 
@@ -36,13 +36,9 @@ unsafe fn payload_from_raw(bytes_ptr: *const c_void, bytes_len: usize) -> Payloa
 
    let bytes = &*slice_from_raw_parts(bytes_ptr, bytes_len);
 
    Payload::from(bytes)
 
}
 
unsafe fn addr_from_raw(addr: *const sockaddr, addr_len: socklen_t) -> Option<SocketAddr> {
 
unsafe fn libc_to_std_sockaddr(addr: *const sockaddr, addr_len: socklen_t) -> Option<SocketAddr> {
 
    os_socketaddr::OsSocketAddr::from_raw_parts(addr as _, addr_len as usize).into_addr()
 
}
 
fn dummy_peer_addr() -> SocketAddr {
 
    // SocketAddrV4::new isn't a constant-time func
 
    SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 0), 8000))
 
}
 
impl Default for FdAllocator {
 
    fn default() -> Self {
 
        Self {
 
@@ -67,15 +63,15 @@ impl FdAllocator {
 
    }
 
}
 
lazy_static::lazy_static! {
 
    static ref LOCK_POISONED: RwLock<CcMap> = Default::default();
 
    static ref CC_MAP: RwLock<CcMap> = Default::default();
 
}
 
impl ConnectorComplex {
 
    fn try_become_connected(&mut self) {
 
        match self {
 
            ConnectorComplex::Setup { Some(local), Some(peer) } => {
 
            ConnectorComplex::Setup { local: Some(local), peer: Some(peer) } => {
 
                // setup complete
 
                let connector = Connector::new(crate::DummyLogger, TRIVIAL_PD.clone(), Connector::random_id());
 
                let [putter, getter] = connector.new_udp_mediator_component(local, peer).unwrap();
 
                let mut connector = Connector::new(Box::new(crate::DummyLogger), crate::TRIVIAL_PD.clone(), Connector::random_id());
 
                let [putter, getter] = connector.new_udp_mediator_component(*local, *peer).unwrap();
 
                *self = ConnectorComplex::Communication { connector, putter, getter }
 
            }
 
            _ => {} // setup incomplete
 
@@ -87,7 +83,7 @@ impl ConnectorComplex {
 
pub extern "C" fn rw_socket(_domain: c_int, _type: c_int) -> c_int {
 
    // ignoring domain and type
 
    // get writer lock
 
    let mut w = if let Ok(w) = LOCK_POISONED.write() { w } else { return CCMLP };
 
    let mut w = if let Ok(w) = CC_MAP.write() { w } else { return LOCK_POISONED };
 
    let fd = w.fd_allocator.alloc();
 
    let cc = ConnectorComplex::Setup { local: None, peer: None };
 
    w.fd_to_cc.insert(fd, RwLock::new(cc));
 
@@ -97,7 +93,7 @@ pub extern "C" fn rw_socket(_domain: c_int, _type: c_int) -> c_int {
 
pub extern "C" fn rw_close(fd: c_int, _how: c_int) -> c_int {
 
    // ignoring HOW
 
    // get writer lock
 
    let mut w = if let Ok(w) = LOCK_POISONED.write() { w } else { return CCMLP };
 
    let mut w = if let Ok(w) = CC_MAP.write() { w } else { return LOCK_POISONED };
 
    if w.fd_to_cc.remove(&fd).is_some() {
 
        w.fd_allocator.free(fd);
 
        ERR_OK
 
@@ -108,18 +104,17 @@ 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, addr: *const sockaddr, addr_len: socklen_t) -> c_int {
 
    // assuming _domain is AF_INET and _type is SOCK_DGRAM
 
    let addr = match addr_from_raw(addr, addr_len) {
 
    let addr = match libc_to_std_sockaddr(addr, addr_len) {
 
        Some(addr) => addr,
 
        _ => return BAD_SOCKADDR,
 
    };
 
    // get outer reader, inner writer locks
 
    let r = if let Ok(r) = LOCK_POISONED.read() { r } else { return CCMLP };
 
    let r = if let Ok(r) = CC_MAP.read() { r } else { return 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 CCMLP };
 
    let mut cc = if let Ok(cc) = cc.write() { cc } else { return LOCK_POISONED };
 
    let cc: &mut ConnectorComplex = &mut cc;
 
    match cc {
 
        ConnectorComplex::Communication { ..} => WRONG_STATE,
 
        ConnectorComplex::Setup { local, peer } => {
 
        ConnectorComplex::Setup { local, .. } => {
 
            *local = Some(addr);
 
            cc.try_become_connected();
 
@@ -133,15 +128,15 @@ pub unsafe extern "C" fn rw_connect(
 
    addr: *const sockaddr,
 
    addr_len: socklen_t,
 
) -> c_int {
 
    let addr = match addr_from_raw(addr, addr_len) {
 
    let addr = match libc_to_std_sockaddr(addr, addr_len) {
 
        Some(addr) => addr,
 
        _ => return BAD_SOCKADDR,
 
    };
 
    // assuming _domain is AF_INET and _type is SOCK_DGRAM
 
    // get outer reader, inner writer locks
 
    let r = if let Ok(r) = LOCK_POISONED.read() { r } else { return CCMLP };
 
    let r = if let Ok(r) = CC_MAP.read() { r } else { return 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 CCMLP };
 
    let mut cc = if let Ok(cc) = cc.write() { cc } else { return LOCK_POISONED };
 
    let cc: &mut ConnectorComplex = &mut cc;
 
    match cc {
 
        ConnectorComplex::Communication { .. } => WRONG_STATE,
 
@@ -161,9 +156,9 @@ pub unsafe extern "C" fn rw_send(
 
) -> isize {
 
    // ignoring flags
 
    // get outer reader, inner writer locks
 
    let r = if let Ok(r) = LOCK_POISONED.read() { r } else { return CCMLP as isize };
 
    let r = if let Ok(r) = CC_MAP.read() { r } else { return 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 CCMLP as isize };
 
    let mut cc = if let Ok(cc) = cc.write() { cc } else { return LOCK_POISONED as isize };
 
    let cc: &mut ConnectorComplex = &mut cc;
 
    match cc {
 
        ConnectorComplex::Setup { .. } => WRONG_STATE as isize,
 
@@ -171,7 +166,7 @@ pub unsafe extern "C" fn rw_send(
 
            let payload = payload_from_raw(bytes_ptr, bytes_len);
 
            connector.put(*putter, payload).unwrap();
 
            connector.sync(None).unwrap();
 
            bytes_len
 
            bytes_len as isize
 
        }
 
    }
 
}
 
@@ -188,48 +183,17 @@ pub unsafe extern "C" fn rw_recv(
 
    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 LOCK_POISONED as isize };
 
    let cc: &mut ConnectorComplex = &mut cc;
 
    if let Some(ConnectorBound { connector, getter, .. }) = &mut cc.connector_bound {
 
        connector.get(*getter).unwrap();
 
        // this call BLOCKS until it succeeds, and its got no reason to fail
 
        connector.sync(None).unwrap();
 
        // copy from gotten to caller's buffer (truncating if necessary)
 
        let slice = connector.gotten(*getter).unwrap().as_slice();
 
        if !bytes_ptr.is_null() {
 
            let cpy_msg_bytes = slice.len().min(bytes_len);
 
            std::ptr::copy_nonoverlapping(slice.as_ptr(), bytes_ptr as *mut u8, cpy_msg_bytes);
 
        }
 
        // return number of bytes sent   
 
        slice.len() as isize
 
    } else {
 
        // not bound!
 
        WRONG_STATE as isize
 
    }
 
}
 

	
 
#[no_mangle]
 
pub unsafe extern "C" fn rw_recvfrom(
 
    fd: c_int,
 
    bytes_ptr: *mut c_void,
 
    bytes_len: usize,
 
    _flags: c_int,
 
    addr: *mut sockaddr,
 
    addr_len: *mut socklen_t,
 
) -> isize {
 
    // ignoring flags
 
    // get outer reader, inner writer locks
 
    let r = if let Ok(r) = CC_MAP.read() { r } else { return 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 CCMLP as isize };
 
    let cc: &mut ConnectorComplex = &mut cc;
 
    match cc {
 
        ConnectorComplex::Setup { .. } => WRONG_STATE as isize,
 
        ConnectorComplex::Communication { connector, getter, .. } => {
 
            connector.get(*getter).unwrap();
 
            connector.sync(None).unwrap();
 
            let slice = connector.gotten(*getter).unwrap().as_slice();
 
            if !bytes_ptr.is_null() {
 
                let cpy_msg_bytes = slice.len().min(bytes_len);
 
                std::ptr::copy_nonoverlapping(slice.as_ptr(), bytes_ptr as *mut u8, cpy_msg_bytes);
 
            cpy_msg_bytes
 
            }
 
            slice.len() as isize
 
        }
 
    }
 
}
 
\ No newline at end of file
0 comments (0 inline, 0 general)