diff options
Diffstat (limited to 'ext/net/ops_unix.rs')
-rw-r--r-- | ext/net/ops_unix.rs | 157 |
1 files changed, 111 insertions, 46 deletions
diff --git a/ext/net/ops_unix.rs b/ext/net/ops_unix.rs index 181dcacec..b45b02343 100644 --- a/ext/net/ops_unix.rs +++ b/ext/net/ops_unix.rs @@ -1,20 +1,18 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. use crate::io::UnixStreamResource; -use crate::ops::AcceptArgs; -use crate::ops::OpAddr; -use crate::ops::OpConn; -use crate::ops::OpPacket; -use crate::ops::ReceiveArgs; +use crate::NetPermissions; use deno_core::error::bad_resource; use deno_core::error::custom_error; use deno_core::error::AnyError; +use deno_core::op; use deno_core::AsyncRefCell; use deno_core::CancelHandle; use deno_core::CancelTryFuture; use deno_core::OpState; use deno_core::RcRef; use deno_core::Resource; +use deno_core::ResourceId; use deno_core::ZeroCopyBuf; use serde::Deserialize; use serde::Serialize; @@ -74,13 +72,11 @@ pub struct UnixListenArgs { pub path: String, } -pub(crate) async fn accept_unix( +#[op] +pub async fn op_net_accept_unix( state: Rc<RefCell<OpState>>, - args: AcceptArgs, - _: (), -) -> Result<OpConn, AnyError> { - let rid = args.rid; - + rid: ResourceId, +) -> Result<(ResourceId, Option<String>, Option<String>), AnyError> { let resource = state .borrow() .resource_table @@ -98,27 +94,52 @@ pub(crate) async fn accept_unix( let local_addr = unix_stream.local_addr()?; let remote_addr = unix_stream.peer_addr()?; + let local_addr_path = local_addr.as_pathname().map(pathstring).transpose()?; + let remote_addr_path = + remote_addr.as_pathname().map(pathstring).transpose()?; let resource = UnixStreamResource::new(unix_stream.into_split()); let mut state = state.borrow_mut(); let rid = state.resource_table.add(resource); - Ok(OpConn { - rid, - local_addr: Some(OpAddr::Unix(UnixAddr { - path: local_addr.as_pathname().and_then(pathstring), - })), - remote_addr: Some(OpAddr::Unix(UnixAddr { - path: remote_addr.as_pathname().and_then(pathstring), - })), - }) + Ok((rid, local_addr_path, remote_addr_path)) } -pub(crate) async fn receive_unix_packet( +#[op] +pub async fn op_net_connect_unix<NP>( state: Rc<RefCell<OpState>>, - args: ReceiveArgs, - mut buf: ZeroCopyBuf, -) -> Result<OpPacket, AnyError> { - let rid = args.rid; + path: String, +) -> Result<(ResourceId, Option<String>, Option<String>), AnyError> +where + NP: NetPermissions + 'static, +{ + let address_path = Path::new(&path); + super::check_unstable2(&state, "Deno.connect"); + { + let mut state_ = state.borrow_mut(); + state_ + .borrow_mut::<NP>() + .check_read(address_path, "Deno.connect()")?; + state_ + .borrow_mut::<NP>() + .check_write(address_path, "Deno.connect()")?; + } + let unix_stream = UnixStream::connect(Path::new(&path)).await?; + let local_addr = unix_stream.local_addr()?; + let remote_addr = unix_stream.peer_addr()?; + let local_addr_path = local_addr.as_pathname().map(pathstring).transpose()?; + let remote_addr_path = + remote_addr.as_pathname().map(pathstring).transpose()?; + let mut state_ = state.borrow_mut(); + let resource = UnixStreamResource::new(unix_stream.into_split()); + let rid = state_.resource_table.add(resource); + Ok((rid, local_addr_path, remote_addr_path)) +} +#[op] +pub async fn op_net_recv_unixpacket( + state: Rc<RefCell<OpState>>, + rid: ResourceId, + mut buf: ZeroCopyBuf, +) -> Result<(usize, Option<String>), AnyError> { let resource = state .borrow() .resource_table @@ -128,46 +149,90 @@ pub(crate) async fn receive_unix_packet( .try_borrow_mut() .ok_or_else(|| custom_error("Busy", "Socket already in use"))?; let cancel = RcRef::map(resource, |r| &r.cancel); - let (size, remote_addr) = + let (nread, remote_addr) = socket.recv_from(&mut buf).try_or_cancel(cancel).await?; - Ok(OpPacket { - size, - remote_addr: OpAddr::UnixPacket(UnixAddr { - path: remote_addr.as_pathname().and_then(pathstring), - }), - }) + let path = remote_addr.as_pathname().map(pathstring).transpose()?; + Ok((nread, path)) +} + +#[op] +async fn op_net_send_unixpacket<NP>( + state: Rc<RefCell<OpState>>, + rid: ResourceId, + path: String, + zero_copy: ZeroCopyBuf, +) -> Result<usize, AnyError> +where + NP: NetPermissions + 'static, +{ + let address_path = Path::new(&path); + { + let mut s = state.borrow_mut(); + s.borrow_mut::<NP>() + .check_write(address_path, "Deno.DatagramConn.send()")?; + } + + let resource = state + .borrow() + .resource_table + .get::<UnixDatagramResource>(rid) + .map_err(|_| custom_error("NotConnected", "Socket has been closed"))?; + let socket = RcRef::map(&resource, |r| &r.socket) + .try_borrow_mut() + .ok_or_else(|| custom_error("Busy", "Socket already in use"))?; + let nwritten = socket.send_to(&zero_copy, address_path).await?; + + Ok(nwritten) } -pub fn listen_unix( +#[op] +pub fn op_net_listen_unix<NP>( state: &mut OpState, - addr: &Path, -) -> Result<(u32, tokio::net::unix::SocketAddr), AnyError> { - let listener = UnixListener::bind(&addr)?; + path: String, +) -> Result<(ResourceId, Option<String>), AnyError> +where + NP: NetPermissions + 'static, +{ + let address_path = Path::new(&path); + super::check_unstable(state, "Deno.listen"); + let permissions = state.borrow_mut::<NP>(); + permissions.check_read(address_path, "Deno.listen()")?; + permissions.check_write(address_path, "Deno.listen()")?; + let listener = UnixListener::bind(&address_path)?; let local_addr = listener.local_addr()?; + let pathname = local_addr.as_pathname().map(pathstring).transpose()?; let listener_resource = UnixListenerResource { listener: AsyncRefCell::new(listener), cancel: Default::default(), }; let rid = state.resource_table.add(listener_resource); - - Ok((rid, local_addr)) + Ok((rid, pathname)) } -pub fn listen_unix_packet( +#[op] +pub fn op_net_listen_unixpacket<NP>( state: &mut OpState, - addr: &Path, -) -> Result<(u32, tokio::net::unix::SocketAddr), AnyError> { - let socket = UnixDatagram::bind(&addr)?; + path: String, +) -> Result<(ResourceId, Option<String>), AnyError> +where + NP: NetPermissions + 'static, +{ + let address_path = Path::new(&path); + super::check_unstable(state, "Deno.listenDatagram"); + let permissions = state.borrow_mut::<NP>(); + permissions.check_read(address_path, "Deno.listenDatagram()")?; + permissions.check_write(address_path, "Deno.listenDatagram()")?; + let socket = UnixDatagram::bind(&address_path)?; let local_addr = socket.local_addr()?; + let pathname = local_addr.as_pathname().map(pathstring).transpose()?; let datagram_resource = UnixDatagramResource { socket: AsyncRefCell::new(socket), cancel: Default::default(), }; let rid = state.resource_table.add(datagram_resource); - - Ok((rid, local_addr)) + Ok((rid, pathname)) } -pub fn pathstring(pathname: &Path) -> Option<String> { - into_string(pathname.into()).ok() +pub fn pathstring(pathname: &Path) -> Result<String, AnyError> { + into_string(pathname.into()) } |