diff --git a/src/ffi/pseudo_socket_api.rs b/src/ffi/pseudo_socket_api.rs index ed2d9d2f72356424490e6922a8f7c2097e9fb57a..0f7f3cb10658060168d32f02e82c9acfcb440d37 100644 --- a/src/ffi/pseudo_socket_api.rs +++ b/src/ffi/pseudo_socket_api.rs @@ -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 { +unsafe fn libc_to_std_sockaddr(addr: *const sockaddr, addr_len: socklen_t) -> Option { 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 = Default::default(); + static ref CC_MAP: RwLock = 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,19 +104,18 @@ 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, .. } => { + ConnectorComplex::Setup { local, .. } => { *local = Some(addr); cc.try_become_connected(); ERR_OK @@ -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(); - 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 + 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); + } + slice.len() as isize } } -} +} \ No newline at end of file