mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
refactor(ext/net): use concrete error type (#26227)
This commit is contained in:
parent
3b62e05062
commit
ed13efc4ac
10 changed files with 317 additions and 191 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -1423,9 +1423,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_core"
|
name = "deno_core"
|
||||||
version = "0.313.0"
|
version = "0.314.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "29f36be738d78e39b6603a6b07f1cf91e28baf3681f87205f07482999e0d0bc2"
|
checksum = "1fcd11ab87426c611b7170138a768dad7170c8fb66d8095b773d25e58fd254ea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bincode",
|
"bincode",
|
||||||
|
@ -1797,6 +1797,7 @@ dependencies = [
|
||||||
"rustls-tokio-stream",
|
"rustls-tokio-stream",
|
||||||
"serde",
|
"serde",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"trust-dns-proto",
|
"trust-dns-proto",
|
||||||
"trust-dns-resolver",
|
"trust-dns-resolver",
|
||||||
|
@ -1913,9 +1914,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deno_ops"
|
name = "deno_ops"
|
||||||
version = "0.189.0"
|
version = "0.190.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e8f998ad1d5b36064109367ffe67b1088385eb3d8025efc95e445bc013a147a2"
|
checksum = "a48a3e06cace18a2c49e148da067678c6af80e70757a8c3991301397cf6b9919"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-rules",
|
"proc-macro-rules",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -6211,9 +6212,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_v8"
|
name = "serde_v8"
|
||||||
version = "0.222.0"
|
version = "0.223.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "27130b5cd87f6f06228940a1f3a7ecc988ea13d1bede1398a48d74cb59dabc9a"
|
checksum = "c127bb9f2024433d06789b242477c808fd7f7dc4c3278576dd5bc99c4e5c75ff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -46,7 +46,7 @@ repository = "https://github.com/denoland/deno"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
deno_ast = { version = "=0.42.2", features = ["transpiling"] }
|
deno_ast = { version = "=0.42.2", features = ["transpiling"] }
|
||||||
deno_core = { version = "0.313.0" }
|
deno_core = { version = "0.314.1" }
|
||||||
|
|
||||||
deno_bench_util = { version = "0.166.0", path = "./bench_util" }
|
deno_bench_util = { version = "0.166.0", path = "./bench_util" }
|
||||||
deno_lockfile = "=0.23.1"
|
deno_lockfile = "=0.23.1"
|
||||||
|
|
2
ext/cache/lib.rs
vendored
2
ext/cache/lib.rs
vendored
|
@ -28,7 +28,7 @@ pub enum CacheError {
|
||||||
Resource(deno_core::error::AnyError),
|
Resource(deno_core::error::AnyError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
Other(deno_core::error::AnyError),
|
Other(deno_core::error::AnyError),
|
||||||
#[error(transparent)]
|
#[error("{0}")]
|
||||||
Io(#[from] std::io::Error),
|
Io(#[from] std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ pin-project.workspace = true
|
||||||
rustls-tokio-stream.workspace = true
|
rustls-tokio-stream.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
socket2.workspace = true
|
socket2.workspace = true
|
||||||
|
thiserror.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
trust-dns-proto = "0.23"
|
trust-dns-proto = "0.23"
|
||||||
trust-dns-resolver = { version = "0.23", features = ["tokio-runtime", "serde-config"] }
|
trust-dns-resolver = { version = "0.23", features = ["tokio-runtime", "serde-config"] }
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use deno_core::error::generic_error;
|
use deno_core::futures::TryFutureExt;
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::AsyncMutFuture;
|
use deno_core::AsyncMutFuture;
|
||||||
use deno_core::AsyncRefCell;
|
use deno_core::AsyncRefCell;
|
||||||
use deno_core::AsyncResult;
|
use deno_core::AsyncResult;
|
||||||
|
@ -69,25 +68,36 @@ where
|
||||||
pub async fn read(
|
pub async fn read(
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
data: &mut [u8],
|
data: &mut [u8],
|
||||||
) -> Result<usize, AnyError> {
|
) -> Result<usize, std::io::Error> {
|
||||||
let mut rd = self.rd_borrow_mut().await;
|
let mut rd = self.rd_borrow_mut().await;
|
||||||
let nread = rd.read(data).try_or_cancel(self.cancel_handle()).await?;
|
let nread = rd.read(data).try_or_cancel(self.cancel_handle()).await?;
|
||||||
Ok(nread)
|
Ok(nread)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn write(self: Rc<Self>, data: &[u8]) -> Result<usize, AnyError> {
|
pub async fn write(
|
||||||
|
self: Rc<Self>,
|
||||||
|
data: &[u8],
|
||||||
|
) -> Result<usize, std::io::Error> {
|
||||||
let mut wr = self.wr_borrow_mut().await;
|
let mut wr = self.wr_borrow_mut().await;
|
||||||
let nwritten = wr.write(data).await?;
|
let nwritten = wr.write(data).await?;
|
||||||
Ok(nwritten)
|
Ok(nwritten)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn shutdown(self: Rc<Self>) -> Result<(), AnyError> {
|
pub async fn shutdown(self: Rc<Self>) -> Result<(), std::io::Error> {
|
||||||
let mut wr = self.wr_borrow_mut().await;
|
let mut wr = self.wr_borrow_mut().await;
|
||||||
wr.shutdown().await?;
|
wr.shutdown().await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum MapError {
|
||||||
|
#[error("{0}")]
|
||||||
|
Io(std::io::Error),
|
||||||
|
#[error("Unable to get resources")]
|
||||||
|
NoResources,
|
||||||
|
}
|
||||||
|
|
||||||
pub type TcpStreamResource =
|
pub type TcpStreamResource =
|
||||||
FullDuplexResource<tcp::OwnedReadHalf, tcp::OwnedWriteHalf>;
|
FullDuplexResource<tcp::OwnedReadHalf, tcp::OwnedWriteHalf>;
|
||||||
|
|
||||||
|
@ -100,7 +110,7 @@ impl Resource for TcpStreamResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shutdown(self: Rc<Self>) -> AsyncResult<()> {
|
fn shutdown(self: Rc<Self>) -> AsyncResult<()> {
|
||||||
Box::pin(self.shutdown())
|
Box::pin(self.shutdown().map_err(Into::into))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(self: Rc<Self>) {
|
fn close(self: Rc<Self>) {
|
||||||
|
@ -109,31 +119,30 @@ impl Resource for TcpStreamResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TcpStreamResource {
|
impl TcpStreamResource {
|
||||||
pub fn set_nodelay(self: Rc<Self>, nodelay: bool) -> Result<(), AnyError> {
|
pub fn set_nodelay(self: Rc<Self>, nodelay: bool) -> Result<(), MapError> {
|
||||||
self.map_socket(Box::new(move |socket| Ok(socket.set_nodelay(nodelay)?)))
|
self.map_socket(Box::new(move |socket| socket.set_nodelay(nodelay)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_keepalive(
|
pub fn set_keepalive(
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
keepalive: bool,
|
keepalive: bool,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), MapError> {
|
||||||
self
|
self.map_socket(Box::new(move |socket| socket.set_keepalive(keepalive)))
|
||||||
.map_socket(Box::new(move |socket| Ok(socket.set_keepalive(keepalive)?)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
fn map_socket(
|
fn map_socket(
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
map: Box<dyn FnOnce(SockRef) -> Result<(), AnyError>>,
|
map: Box<dyn FnOnce(SockRef) -> Result<(), std::io::Error>>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), MapError> {
|
||||||
if let Some(wr) = RcRef::map(self, |r| &r.wr).try_borrow() {
|
if let Some(wr) = RcRef::map(self, |r| &r.wr).try_borrow() {
|
||||||
let stream = wr.as_ref().as_ref();
|
let stream = wr.as_ref().as_ref();
|
||||||
let socket = socket2::SockRef::from(stream);
|
let socket = socket2::SockRef::from(stream);
|
||||||
|
|
||||||
return map(socket);
|
return map(socket).map_err(MapError::Io);
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(generic_error("Unable to get resources"))
|
Err(MapError::NoResources)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +162,9 @@ impl UnixStreamResource {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
#[allow(clippy::unused_async)]
|
#[allow(clippy::unused_async)]
|
||||||
pub async fn shutdown(self: Rc<Self>) -> Result<(), AnyError> {
|
pub async fn shutdown(
|
||||||
|
self: Rc<Self>,
|
||||||
|
) -> Result<(), deno_core::error::AnyError> {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
pub fn cancel_read_ops(&self) {
|
pub fn cancel_read_ops(&self) {
|
||||||
|
@ -170,7 +181,7 @@ impl Resource for UnixStreamResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shutdown(self: Rc<Self>) -> AsyncResult<()> {
|
fn shutdown(self: Rc<Self>) -> AsyncResult<()> {
|
||||||
Box::pin(self.shutdown())
|
Box::pin(self.shutdown().map_err(Into::into))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(self: Rc<Self>) {
|
fn close(self: Rc<Self>) {
|
||||||
|
|
218
ext/net/ops.rs
218
ext/net/ops.rs
|
@ -6,10 +6,6 @@ use crate::resolve_addr::resolve_addr;
|
||||||
use crate::resolve_addr::resolve_addr_sync;
|
use crate::resolve_addr::resolve_addr_sync;
|
||||||
use crate::tcp::TcpListener;
|
use crate::tcp::TcpListener;
|
||||||
use crate::NetPermissions;
|
use crate::NetPermissions;
|
||||||
use deno_core::error::bad_resource;
|
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::CancelFuture;
|
use deno_core::CancelFuture;
|
||||||
|
|
||||||
|
@ -43,6 +39,7 @@ use trust_dns_proto::rr::record_type::RecordType;
|
||||||
use trust_dns_resolver::config::NameServerConfigGroup;
|
use trust_dns_resolver::config::NameServerConfigGroup;
|
||||||
use trust_dns_resolver::config::ResolverConfig;
|
use trust_dns_resolver::config::ResolverConfig;
|
||||||
use trust_dns_resolver::config::ResolverOpts;
|
use trust_dns_resolver::config::ResolverOpts;
|
||||||
|
use trust_dns_resolver::error::ResolveError;
|
||||||
use trust_dns_resolver::error::ResolveErrorKind;
|
use trust_dns_resolver::error::ResolveErrorKind;
|
||||||
use trust_dns_resolver::system_conf;
|
use trust_dns_resolver::system_conf;
|
||||||
use trust_dns_resolver::AsyncResolver;
|
use trust_dns_resolver::AsyncResolver;
|
||||||
|
@ -68,11 +65,69 @@ impl From<SocketAddr> for IpAddr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn accept_err(e: std::io::Error) -> AnyError {
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum NetError {
|
||||||
|
#[error("Listener has been closed")]
|
||||||
|
ListenerClosed,
|
||||||
|
#[error("Listener already in use")]
|
||||||
|
ListenerBusy,
|
||||||
|
#[error("Socket has been closed")]
|
||||||
|
SocketClosed,
|
||||||
|
#[error("Socket has been closed")]
|
||||||
|
SocketClosedNotConnected,
|
||||||
|
#[error("Socket already in use")]
|
||||||
|
SocketBusy,
|
||||||
|
#[error("{0}")]
|
||||||
|
Io(#[from] std::io::Error),
|
||||||
|
#[error("Another accept task is ongoing")]
|
||||||
|
AcceptTaskOngoing,
|
||||||
|
#[error("{0}")]
|
||||||
|
Permission(deno_core::error::AnyError),
|
||||||
|
#[error("{0}")]
|
||||||
|
Resource(deno_core::error::AnyError),
|
||||||
|
#[error("No resolved address found")]
|
||||||
|
NoResolvedAddress,
|
||||||
|
#[error("{0}")]
|
||||||
|
AddrParse(#[from] std::net::AddrParseError),
|
||||||
|
#[error("{0}")]
|
||||||
|
Map(crate::io::MapError),
|
||||||
|
#[error("{0}")]
|
||||||
|
Canceled(#[from] deno_core::Canceled),
|
||||||
|
#[error("{0}")]
|
||||||
|
DnsNotFound(ResolveError),
|
||||||
|
#[error("{0}")]
|
||||||
|
DnsNotConnected(ResolveError),
|
||||||
|
#[error("{0}")]
|
||||||
|
DnsTimedOut(ResolveError),
|
||||||
|
#[error("{0}")]
|
||||||
|
Dns(#[from] ResolveError),
|
||||||
|
#[error("Provided record type is not supported")]
|
||||||
|
UnsupportedRecordType,
|
||||||
|
#[error("File name or path {0:?} is not valid UTF-8")]
|
||||||
|
InvalidUtf8(std::ffi::OsString),
|
||||||
|
#[error("unexpected key type")]
|
||||||
|
UnexpectedKeyType,
|
||||||
|
#[error("Invalid hostname: '{0}'")]
|
||||||
|
InvalidHostname(String), // TypeError
|
||||||
|
#[error("TCP stream is currently in use")]
|
||||||
|
TcpStreamBusy,
|
||||||
|
#[error("{0}")]
|
||||||
|
Rustls(#[from] deno_tls::rustls::Error),
|
||||||
|
#[error("{0}")]
|
||||||
|
Tls(#[from] deno_tls::TlsError),
|
||||||
|
#[error("Error creating TLS certificate: Deno.listenTls requires a key")]
|
||||||
|
ListenTlsRequiresKey, // InvalidData
|
||||||
|
#[error("{0}")]
|
||||||
|
RootCertStore(deno_core::anyhow::Error),
|
||||||
|
#[error("{0}")]
|
||||||
|
Reunite(tokio::net::tcp::ReuniteError),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn accept_err(e: std::io::Error) -> NetError {
|
||||||
if let std::io::ErrorKind::Interrupted = e.kind() {
|
if let std::io::ErrorKind::Interrupted = e.kind() {
|
||||||
bad_resource("Listener has been closed")
|
NetError::ListenerClosed
|
||||||
} else {
|
} else {
|
||||||
e.into()
|
NetError::Io(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,15 +136,15 @@ pub(crate) fn accept_err(e: std::io::Error) -> AnyError {
|
||||||
pub async fn op_net_accept_tcp(
|
pub async fn op_net_accept_tcp(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
) -> Result<(ResourceId, IpAddr, IpAddr), AnyError> {
|
) -> Result<(ResourceId, IpAddr, IpAddr), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<NetworkListenerResource<TcpListener>>(rid)
|
.get::<NetworkListenerResource<TcpListener>>(rid)
|
||||||
.map_err(|_| bad_resource("Listener has been closed"))?;
|
.map_err(|_| NetError::ListenerClosed)?;
|
||||||
let listener = RcRef::map(&resource, |r| &r.listener)
|
let listener = RcRef::map(&resource, |r| &r.listener)
|
||||||
.try_borrow_mut()
|
.try_borrow_mut()
|
||||||
.ok_or_else(|| custom_error("Busy", "Another accept task is ongoing"))?;
|
.ok_or_else(|| NetError::AcceptTaskOngoing)?;
|
||||||
let cancel = RcRef::map(resource, |r| &r.cancel);
|
let cancel = RcRef::map(resource, |r| &r.cancel);
|
||||||
let (tcp_stream, _socket_addr) = listener
|
let (tcp_stream, _socket_addr) = listener
|
||||||
.accept()
|
.accept()
|
||||||
|
@ -112,12 +167,12 @@ pub async fn op_net_recv_udp(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
#[buffer] mut buf: JsBuffer,
|
#[buffer] mut buf: JsBuffer,
|
||||||
) -> Result<(usize, IpAddr), AnyError> {
|
) -> Result<(usize, IpAddr), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<UdpSocketResource>(rid)
|
.get::<UdpSocketResource>(rid)
|
||||||
.map_err(|_| bad_resource("Socket has been closed"))?;
|
.map_err(|_| NetError::SocketClosed)?;
|
||||||
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
||||||
let cancel_handle = RcRef::map(&resource, |r| &r.cancel);
|
let cancel_handle = RcRef::map(&resource, |r| &r.cancel);
|
||||||
let (nread, remote_addr) = socket
|
let (nread, remote_addr) = socket
|
||||||
|
@ -134,27 +189,29 @@ pub async fn op_net_send_udp<NP>(
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
#[serde] addr: IpAddr,
|
#[serde] addr: IpAddr,
|
||||||
#[buffer] zero_copy: JsBuffer,
|
#[buffer] zero_copy: JsBuffer,
|
||||||
) -> Result<usize, AnyError>
|
) -> Result<usize, NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
let mut s = state.borrow_mut();
|
let mut s = state.borrow_mut();
|
||||||
s.borrow_mut::<NP>().check_net(
|
s.borrow_mut::<NP>()
|
||||||
&(&addr.hostname, Some(addr.port)),
|
.check_net(
|
||||||
"Deno.DatagramConn.send()",
|
&(&addr.hostname, Some(addr.port)),
|
||||||
)?;
|
"Deno.DatagramConn.send()",
|
||||||
|
)
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
}
|
}
|
||||||
let addr = resolve_addr(&addr.hostname, addr.port)
|
let addr = resolve_addr(&addr.hostname, addr.port)
|
||||||
.await?
|
.await?
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| generic_error("No resolved address found"))?;
|
.ok_or(NetError::NoResolvedAddress)?;
|
||||||
|
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<UdpSocketResource>(rid)
|
.get::<UdpSocketResource>(rid)
|
||||||
.map_err(|_| bad_resource("Socket has been closed"))?;
|
.map_err(|_| NetError::SocketClosed)?;
|
||||||
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
||||||
let nwritten = socket.send_to(&zero_copy, &addr).await?;
|
let nwritten = socket.send_to(&zero_copy, &addr).await?;
|
||||||
|
|
||||||
|
@ -167,12 +224,12 @@ pub async fn op_net_join_multi_v4_udp(
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
#[string] address: String,
|
#[string] address: String,
|
||||||
#[string] multi_interface: String,
|
#[string] multi_interface: String,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<UdpSocketResource>(rid)
|
.get::<UdpSocketResource>(rid)
|
||||||
.map_err(|_| bad_resource("Socket has been closed"))?;
|
.map_err(|_| NetError::SocketClosed)?;
|
||||||
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
||||||
|
|
||||||
let addr = Ipv4Addr::from_str(address.as_str())?;
|
let addr = Ipv4Addr::from_str(address.as_str())?;
|
||||||
|
@ -189,12 +246,12 @@ pub async fn op_net_join_multi_v6_udp(
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
#[string] address: String,
|
#[string] address: String,
|
||||||
#[smi] multi_interface: u32,
|
#[smi] multi_interface: u32,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<UdpSocketResource>(rid)
|
.get::<UdpSocketResource>(rid)
|
||||||
.map_err(|_| bad_resource("Socket has been closed"))?;
|
.map_err(|_| NetError::SocketClosed)?;
|
||||||
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
||||||
|
|
||||||
let addr = Ipv6Addr::from_str(address.as_str())?;
|
let addr = Ipv6Addr::from_str(address.as_str())?;
|
||||||
|
@ -210,12 +267,12 @@ pub async fn op_net_leave_multi_v4_udp(
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
#[string] address: String,
|
#[string] address: String,
|
||||||
#[string] multi_interface: String,
|
#[string] multi_interface: String,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<UdpSocketResource>(rid)
|
.get::<UdpSocketResource>(rid)
|
||||||
.map_err(|_| bad_resource("Socket has been closed"))?;
|
.map_err(|_| NetError::SocketClosed)?;
|
||||||
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
||||||
|
|
||||||
let addr = Ipv4Addr::from_str(address.as_str())?;
|
let addr = Ipv4Addr::from_str(address.as_str())?;
|
||||||
|
@ -232,12 +289,12 @@ pub async fn op_net_leave_multi_v6_udp(
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
#[string] address: String,
|
#[string] address: String,
|
||||||
#[smi] multi_interface: u32,
|
#[smi] multi_interface: u32,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<UdpSocketResource>(rid)
|
.get::<UdpSocketResource>(rid)
|
||||||
.map_err(|_| bad_resource("Socket has been closed"))?;
|
.map_err(|_| NetError::SocketClosed)?;
|
||||||
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
||||||
|
|
||||||
let addr = Ipv6Addr::from_str(address.as_str())?;
|
let addr = Ipv6Addr::from_str(address.as_str())?;
|
||||||
|
@ -253,16 +310,16 @@ pub async fn op_net_set_multi_loopback_udp(
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
is_v4_membership: bool,
|
is_v4_membership: bool,
|
||||||
loopback: bool,
|
loopback: bool,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<UdpSocketResource>(rid)
|
.get::<UdpSocketResource>(rid)
|
||||||
.map_err(|_| bad_resource("Socket has been closed"))?;
|
.map_err(|_| NetError::SocketClosed)?;
|
||||||
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
||||||
|
|
||||||
if is_v4_membership {
|
if is_v4_membership {
|
||||||
socket.set_multicast_loop_v4(loopback)?
|
socket.set_multicast_loop_v4(loopback)?;
|
||||||
} else {
|
} else {
|
||||||
socket.set_multicast_loop_v6(loopback)?;
|
socket.set_multicast_loop_v6(loopback)?;
|
||||||
}
|
}
|
||||||
|
@ -275,12 +332,12 @@ pub async fn op_net_set_multi_ttl_udp(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
#[smi] ttl: u32,
|
#[smi] ttl: u32,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<UdpSocketResource>(rid)
|
.get::<UdpSocketResource>(rid)
|
||||||
.map_err(|_| bad_resource("Socket has been closed"))?;
|
.map_err(|_| NetError::SocketClosed)?;
|
||||||
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
let socket = RcRef::map(&resource, |r| &r.socket).borrow().await;
|
||||||
|
|
||||||
socket.set_multicast_ttl_v4(ttl)?;
|
socket.set_multicast_ttl_v4(ttl)?;
|
||||||
|
@ -293,7 +350,7 @@ pub async fn op_net_set_multi_ttl_udp(
|
||||||
pub async fn op_net_connect_tcp<NP>(
|
pub async fn op_net_connect_tcp<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[serde] addr: IpAddr,
|
#[serde] addr: IpAddr,
|
||||||
) -> Result<(ResourceId, IpAddr, IpAddr), AnyError>
|
) -> Result<(ResourceId, IpAddr, IpAddr), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -304,7 +361,7 @@ where
|
||||||
pub async fn op_net_connect_tcp_inner<NP>(
|
pub async fn op_net_connect_tcp_inner<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
addr: IpAddr,
|
addr: IpAddr,
|
||||||
) -> Result<(ResourceId, IpAddr, IpAddr), AnyError>
|
) -> Result<(ResourceId, IpAddr, IpAddr), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -312,13 +369,14 @@ where
|
||||||
let mut state_ = state.borrow_mut();
|
let mut state_ = state.borrow_mut();
|
||||||
state_
|
state_
|
||||||
.borrow_mut::<NP>()
|
.borrow_mut::<NP>()
|
||||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.connect()")?;
|
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.connect()")
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let addr = resolve_addr(&addr.hostname, addr.port)
|
let addr = resolve_addr(&addr.hostname, addr.port)
|
||||||
.await?
|
.await?
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| generic_error("No resolved address found"))?;
|
.ok_or_else(|| NetError::NoResolvedAddress)?;
|
||||||
let tcp_stream = TcpStream::connect(&addr).await?;
|
let tcp_stream = TcpStream::connect(&addr).await?;
|
||||||
let local_addr = tcp_stream.local_addr()?;
|
let local_addr = tcp_stream.local_addr()?;
|
||||||
let remote_addr = tcp_stream.peer_addr()?;
|
let remote_addr = tcp_stream.peer_addr()?;
|
||||||
|
@ -353,7 +411,7 @@ pub fn op_net_listen_tcp<NP>(
|
||||||
#[serde] addr: IpAddr,
|
#[serde] addr: IpAddr,
|
||||||
reuse_port: bool,
|
reuse_port: bool,
|
||||||
load_balanced: bool,
|
load_balanced: bool,
|
||||||
) -> Result<(ResourceId, IpAddr), AnyError>
|
) -> Result<(ResourceId, IpAddr), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -362,10 +420,11 @@ where
|
||||||
}
|
}
|
||||||
state
|
state
|
||||||
.borrow_mut::<NP>()
|
.borrow_mut::<NP>()
|
||||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listen()")?;
|
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listen()")
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
let addr = resolve_addr_sync(&addr.hostname, addr.port)?
|
let addr = resolve_addr_sync(&addr.hostname, addr.port)?
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| generic_error("No resolved address found"))?;
|
.ok_or_else(|| NetError::NoResolvedAddress)?;
|
||||||
|
|
||||||
let listener = if load_balanced {
|
let listener = if load_balanced {
|
||||||
TcpListener::bind_load_balanced(addr)
|
TcpListener::bind_load_balanced(addr)
|
||||||
|
@ -384,16 +443,17 @@ fn net_listen_udp<NP>(
|
||||||
addr: IpAddr,
|
addr: IpAddr,
|
||||||
reuse_address: bool,
|
reuse_address: bool,
|
||||||
loopback: bool,
|
loopback: bool,
|
||||||
) -> Result<(ResourceId, IpAddr), AnyError>
|
) -> Result<(ResourceId, IpAddr), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
state
|
state
|
||||||
.borrow_mut::<NP>()
|
.borrow_mut::<NP>()
|
||||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenDatagram()")?;
|
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenDatagram()")
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
let addr = resolve_addr_sync(&addr.hostname, addr.port)?
|
let addr = resolve_addr_sync(&addr.hostname, addr.port)?
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| generic_error("No resolved address found"))?;
|
.ok_or_else(|| NetError::NoResolvedAddress)?;
|
||||||
|
|
||||||
let domain = if addr.is_ipv4() {
|
let domain = if addr.is_ipv4() {
|
||||||
Domain::IPV4
|
Domain::IPV4
|
||||||
|
@ -453,7 +513,7 @@ pub fn op_net_listen_udp<NP>(
|
||||||
#[serde] addr: IpAddr,
|
#[serde] addr: IpAddr,
|
||||||
reuse_address: bool,
|
reuse_address: bool,
|
||||||
loopback: bool,
|
loopback: bool,
|
||||||
) -> Result<(ResourceId, IpAddr), AnyError>
|
) -> Result<(ResourceId, IpAddr), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -468,7 +528,7 @@ pub fn op_node_unstable_net_listen_udp<NP>(
|
||||||
#[serde] addr: IpAddr,
|
#[serde] addr: IpAddr,
|
||||||
reuse_address: bool,
|
reuse_address: bool,
|
||||||
loopback: bool,
|
loopback: bool,
|
||||||
) -> Result<(ResourceId, IpAddr), AnyError>
|
) -> Result<(ResourceId, IpAddr), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -551,7 +611,7 @@ pub struct NameServer {
|
||||||
pub async fn op_dns_resolve<NP>(
|
pub async fn op_dns_resolve<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[serde] args: ResolveAddrArgs,
|
#[serde] args: ResolveAddrArgs,
|
||||||
) -> Result<Vec<DnsReturnRecord>, AnyError>
|
) -> Result<Vec<DnsReturnRecord>, NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -587,7 +647,9 @@ where
|
||||||
let socker_addr = &ns.socket_addr;
|
let socker_addr = &ns.socket_addr;
|
||||||
let ip = socker_addr.ip().to_string();
|
let ip = socker_addr.ip().to_string();
|
||||||
let port = socker_addr.port();
|
let port = socker_addr.port();
|
||||||
perm.check_net(&(ip, Some(port)), "Deno.resolveDns()")?;
|
perm
|
||||||
|
.check_net(&(ip, Some(port)), "Deno.resolveDns()")
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,22 +680,17 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
lookup
|
lookup
|
||||||
.map_err(|e| {
|
.map_err(|e| match e.kind() {
|
||||||
let message = format!("{e}");
|
ResolveErrorKind::NoRecordsFound { .. } => NetError::DnsNotFound(e),
|
||||||
match e.kind() {
|
ResolveErrorKind::Message("No connections available") => {
|
||||||
ResolveErrorKind::NoRecordsFound { .. } => {
|
NetError::DnsNotConnected(e)
|
||||||
custom_error("NotFound", message)
|
|
||||||
}
|
|
||||||
ResolveErrorKind::Message("No connections available") => {
|
|
||||||
custom_error("NotConnected", message)
|
|
||||||
}
|
|
||||||
ResolveErrorKind::Timeout => custom_error("TimedOut", message),
|
|
||||||
_ => generic_error(message),
|
|
||||||
}
|
}
|
||||||
|
ResolveErrorKind::Timeout => NetError::DnsTimedOut(e),
|
||||||
|
_ => NetError::Dns(e),
|
||||||
})?
|
})?
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|rdata| rdata_to_return_record(record_type)(rdata).transpose())
|
.filter_map(|rdata| rdata_to_return_record(record_type)(rdata).transpose())
|
||||||
.collect::<Result<Vec<DnsReturnRecord>, AnyError>>()
|
.collect::<Result<Vec<DnsReturnRecord>, NetError>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast)]
|
||||||
|
@ -641,7 +698,7 @@ pub fn op_set_nodelay(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
nodelay: bool,
|
nodelay: bool,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
op_set_nodelay_inner(state, rid, nodelay)
|
op_set_nodelay_inner(state, rid, nodelay)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -650,10 +707,12 @@ pub fn op_set_nodelay_inner(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
rid: ResourceId,
|
rid: ResourceId,
|
||||||
nodelay: bool,
|
nodelay: bool,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
let resource: Rc<TcpStreamResource> =
|
let resource: Rc<TcpStreamResource> = state
|
||||||
state.resource_table.get::<TcpStreamResource>(rid)?;
|
.resource_table
|
||||||
resource.set_nodelay(nodelay)
|
.get::<TcpStreamResource>(rid)
|
||||||
|
.map_err(NetError::Resource)?;
|
||||||
|
resource.set_nodelay(nodelay).map_err(NetError::Map)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op2(fast)]
|
#[op2(fast)]
|
||||||
|
@ -661,7 +720,7 @@ pub fn op_set_keepalive(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
keepalive: bool,
|
keepalive: bool,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
op_set_keepalive_inner(state, rid, keepalive)
|
op_set_keepalive_inner(state, rid, keepalive)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,17 +729,19 @@ pub fn op_set_keepalive_inner(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
rid: ResourceId,
|
rid: ResourceId,
|
||||||
keepalive: bool,
|
keepalive: bool,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
let resource: Rc<TcpStreamResource> =
|
let resource: Rc<TcpStreamResource> = state
|
||||||
state.resource_table.get::<TcpStreamResource>(rid)?;
|
.resource_table
|
||||||
resource.set_keepalive(keepalive)
|
.get::<TcpStreamResource>(rid)
|
||||||
|
.map_err(NetError::Resource)?;
|
||||||
|
resource.set_keepalive(keepalive).map_err(NetError::Map)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rdata_to_return_record(
|
fn rdata_to_return_record(
|
||||||
ty: RecordType,
|
ty: RecordType,
|
||||||
) -> impl Fn(&RData) -> Result<Option<DnsReturnRecord>, AnyError> {
|
) -> impl Fn(&RData) -> Result<Option<DnsReturnRecord>, NetError> {
|
||||||
use RecordType::*;
|
use RecordType::*;
|
||||||
move |r: &RData| -> Result<Option<DnsReturnRecord>, AnyError> {
|
move |r: &RData| -> Result<Option<DnsReturnRecord>, NetError> {
|
||||||
let record = match ty {
|
let record = match ty {
|
||||||
A => r.as_a().map(ToString::to_string).map(DnsReturnRecord::A),
|
A => r.as_a().map(ToString::to_string).map(DnsReturnRecord::A),
|
||||||
AAAA => r
|
AAAA => r
|
||||||
|
@ -761,12 +822,7 @@ fn rdata_to_return_record(
|
||||||
.collect();
|
.collect();
|
||||||
DnsReturnRecord::Txt(texts)
|
DnsReturnRecord::Txt(texts)
|
||||||
}),
|
}),
|
||||||
_ => {
|
_ => return Err(NetError::UnsupportedRecordType),
|
||||||
return Err(custom_error(
|
|
||||||
"NotSupported",
|
|
||||||
"Provided record type is not supported",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
Ok(record)
|
Ok(record)
|
||||||
}
|
}
|
||||||
|
@ -985,7 +1041,7 @@ mod tests {
|
||||||
&mut self,
|
&mut self,
|
||||||
_host: &(T, Option<u16>),
|
_host: &(T, Option<u16>),
|
||||||
_api_name: &str,
|
_api_name: &str,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), deno_core::error::AnyError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -993,7 +1049,7 @@ mod tests {
|
||||||
&mut self,
|
&mut self,
|
||||||
p: &str,
|
p: &str,
|
||||||
_api_name: &str,
|
_api_name: &str,
|
||||||
) -> Result<PathBuf, AnyError> {
|
) -> Result<PathBuf, deno_core::error::AnyError> {
|
||||||
Ok(PathBuf::from(p))
|
Ok(PathBuf::from(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,7 +1057,7 @@ mod tests {
|
||||||
&mut self,
|
&mut self,
|
||||||
p: &str,
|
p: &str,
|
||||||
_api_name: &str,
|
_api_name: &str,
|
||||||
) -> Result<PathBuf, AnyError> {
|
) -> Result<PathBuf, deno_core::error::AnyError> {
|
||||||
Ok(PathBuf::from(p))
|
Ok(PathBuf::from(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,7 +1065,7 @@ mod tests {
|
||||||
&mut self,
|
&mut self,
|
||||||
p: &'a Path,
|
p: &'a Path,
|
||||||
_api_name: &str,
|
_api_name: &str,
|
||||||
) -> Result<Cow<'a, Path>, AnyError> {
|
) -> Result<Cow<'a, Path>, deno_core::error::AnyError> {
|
||||||
Ok(Cow::Borrowed(p))
|
Ok(Cow::Borrowed(p))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1091,7 +1147,7 @@ mod tests {
|
||||||
let vals = result.unwrap();
|
let vals = result.unwrap();
|
||||||
rid = rid.or(Some(vals.0));
|
rid = rid.or(Some(vals.0));
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
let rid = rid.unwrap();
|
let rid = rid.unwrap();
|
||||||
|
|
||||||
let state = runtime.op_state();
|
let state = runtime.op_state();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use crate::io::TcpStreamResource;
|
use crate::io::TcpStreamResource;
|
||||||
use crate::ops::IpAddr;
|
use crate::ops::IpAddr;
|
||||||
|
use crate::ops::NetError;
|
||||||
use crate::ops::TlsHandshakeInfo;
|
use crate::ops::TlsHandshakeInfo;
|
||||||
use crate::raw::NetworkListenerResource;
|
use crate::raw::NetworkListenerResource;
|
||||||
use crate::resolve_addr::resolve_addr;
|
use crate::resolve_addr::resolve_addr;
|
||||||
|
@ -10,13 +11,7 @@ use crate::tcp::TcpListener;
|
||||||
use crate::DefaultTlsOptions;
|
use crate::DefaultTlsOptions;
|
||||||
use crate::NetPermissions;
|
use crate::NetPermissions;
|
||||||
use crate::UnsafelyIgnoreCertificateErrors;
|
use crate::UnsafelyIgnoreCertificateErrors;
|
||||||
use deno_core::anyhow::anyhow;
|
use deno_core::futures::TryFutureExt;
|
||||||
use deno_core::anyhow::bail;
|
|
||||||
use deno_core::error::bad_resource;
|
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::generic_error;
|
|
||||||
use deno_core::error::invalid_hostname;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::v8;
|
use deno_core::v8;
|
||||||
use deno_core::AsyncRefCell;
|
use deno_core::AsyncRefCell;
|
||||||
|
@ -118,20 +113,23 @@ impl TlsStreamResource {
|
||||||
pub async fn read(
|
pub async fn read(
|
||||||
self: Rc<Self>,
|
self: Rc<Self>,
|
||||||
data: &mut [u8],
|
data: &mut [u8],
|
||||||
) -> Result<usize, AnyError> {
|
) -> Result<usize, std::io::Error> {
|
||||||
let mut rd = RcRef::map(&self, |r| &r.rd).borrow_mut().await;
|
let mut rd = RcRef::map(&self, |r| &r.rd).borrow_mut().await;
|
||||||
let cancel_handle = RcRef::map(&self, |r| &r.cancel_handle);
|
let cancel_handle = RcRef::map(&self, |r| &r.cancel_handle);
|
||||||
Ok(rd.read(data).try_or_cancel(cancel_handle).await?)
|
rd.read(data).try_or_cancel(cancel_handle).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn write(self: Rc<Self>, data: &[u8]) -> Result<usize, AnyError> {
|
pub async fn write(
|
||||||
|
self: Rc<Self>,
|
||||||
|
data: &[u8],
|
||||||
|
) -> Result<usize, std::io::Error> {
|
||||||
let mut wr = RcRef::map(self, |r| &r.wr).borrow_mut().await;
|
let mut wr = RcRef::map(self, |r| &r.wr).borrow_mut().await;
|
||||||
let nwritten = wr.write(data).await?;
|
let nwritten = wr.write(data).await?;
|
||||||
wr.flush().await?;
|
wr.flush().await?;
|
||||||
Ok(nwritten)
|
Ok(nwritten)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn shutdown(self: Rc<Self>) -> Result<(), AnyError> {
|
pub async fn shutdown(self: Rc<Self>) -> Result<(), std::io::Error> {
|
||||||
let mut wr = RcRef::map(self, |r| &r.wr).borrow_mut().await;
|
let mut wr = RcRef::map(self, |r| &r.wr).borrow_mut().await;
|
||||||
wr.shutdown().await?;
|
wr.shutdown().await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -139,7 +137,7 @@ impl TlsStreamResource {
|
||||||
|
|
||||||
pub async fn handshake(
|
pub async fn handshake(
|
||||||
self: &Rc<Self>,
|
self: &Rc<Self>,
|
||||||
) -> Result<TlsHandshakeInfo, AnyError> {
|
) -> Result<TlsHandshakeInfo, std::io::Error> {
|
||||||
if let Some(tls_info) = &*self.handshake_info.borrow() {
|
if let Some(tls_info) = &*self.handshake_info.borrow() {
|
||||||
return Ok(tls_info.clone());
|
return Ok(tls_info.clone());
|
||||||
}
|
}
|
||||||
|
@ -164,7 +162,7 @@ impl Resource for TlsStreamResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shutdown(self: Rc<Self>) -> AsyncResult<()> {
|
fn shutdown(self: Rc<Self>) -> AsyncResult<()> {
|
||||||
Box::pin(self.shutdown())
|
Box::pin(self.shutdown().map_err(Into::into))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(self: Rc<Self>) {
|
fn close(self: Rc<Self>) {
|
||||||
|
@ -201,7 +199,7 @@ pub fn op_tls_key_null() -> TlsKeysHolder {
|
||||||
pub fn op_tls_key_static(
|
pub fn op_tls_key_static(
|
||||||
#[string] cert: &str,
|
#[string] cert: &str,
|
||||||
#[string] key: &str,
|
#[string] key: &str,
|
||||||
) -> Result<TlsKeysHolder, AnyError> {
|
) -> Result<TlsKeysHolder, deno_tls::TlsError> {
|
||||||
let cert = load_certs(&mut BufReader::new(cert.as_bytes()))?;
|
let cert = load_certs(&mut BufReader::new(cert.as_bytes()))?;
|
||||||
let key = load_private_keys(key.as_bytes())?
|
let key = load_private_keys(key.as_bytes())?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -236,9 +234,9 @@ pub fn op_tls_cert_resolver_resolve(
|
||||||
#[cppgc] lookup: &TlsKeyLookup,
|
#[cppgc] lookup: &TlsKeyLookup,
|
||||||
#[string] sni: String,
|
#[string] sni: String,
|
||||||
#[cppgc] key: &TlsKeysHolder,
|
#[cppgc] key: &TlsKeysHolder,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), NetError> {
|
||||||
let TlsKeys::Static(key) = key.take() else {
|
let TlsKeys::Static(key) = key.take() else {
|
||||||
bail!("unexpected key type");
|
return Err(NetError::UnexpectedKeyType);
|
||||||
};
|
};
|
||||||
lookup.resolve(sni, Ok(key));
|
lookup.resolve(sni, Ok(key));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -258,7 +256,7 @@ pub fn op_tls_cert_resolver_resolve_error(
|
||||||
pub fn op_tls_start<NP>(
|
pub fn op_tls_start<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[serde] args: StartTlsArgs,
|
#[serde] args: StartTlsArgs,
|
||||||
) -> Result<(ResourceId, IpAddr, IpAddr), AnyError>
|
) -> Result<(ResourceId, IpAddr, IpAddr), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -271,7 +269,9 @@ where
|
||||||
{
|
{
|
||||||
let mut s = state.borrow_mut();
|
let mut s = state.borrow_mut();
|
||||||
let permissions = s.borrow_mut::<NP>();
|
let permissions = s.borrow_mut::<NP>();
|
||||||
permissions.check_net(&(&hostname, Some(0)), "Deno.startTls()")?;
|
permissions
|
||||||
|
.check_net(&(&hostname, Some(0)), "Deno.startTls()")
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let ca_certs = args
|
let ca_certs = args
|
||||||
|
@ -281,7 +281,7 @@ where
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let hostname_dns = ServerName::try_from(hostname.to_string())
|
let hostname_dns = ServerName::try_from(hostname.to_string())
|
||||||
.map_err(|_| invalid_hostname(&hostname))?;
|
.map_err(|_| NetError::InvalidHostname(hostname))?;
|
||||||
|
|
||||||
let unsafely_ignore_certificate_errors = state
|
let unsafely_ignore_certificate_errors = state
|
||||||
.borrow()
|
.borrow()
|
||||||
|
@ -291,19 +291,21 @@ where
|
||||||
let root_cert_store = state
|
let root_cert_store = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.borrow::<DefaultTlsOptions>()
|
.borrow::<DefaultTlsOptions>()
|
||||||
.root_cert_store()?;
|
.root_cert_store()
|
||||||
|
.map_err(NetError::RootCertStore)?;
|
||||||
|
|
||||||
let resource_rc = state
|
let resource_rc = state
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.resource_table
|
.resource_table
|
||||||
.take::<TcpStreamResource>(rid)?;
|
.take::<TcpStreamResource>(rid)
|
||||||
|
.map_err(NetError::Resource)?;
|
||||||
// This TCP connection might be used somewhere else. If it's the case, we cannot proceed with the
|
// This TCP connection might be used somewhere else. If it's the case, we cannot proceed with the
|
||||||
// process of starting a TLS connection on top of this TCP connection, so we just return a Busy error.
|
// process of starting a TLS connection on top of this TCP connection, so we just return a Busy error.
|
||||||
// See also: https://github.com/denoland/deno/pull/16242
|
// See also: https://github.com/denoland/deno/pull/16242
|
||||||
let resource = Rc::try_unwrap(resource_rc)
|
let resource =
|
||||||
.map_err(|_| custom_error("Busy", "TCP stream is currently in use"))?;
|
Rc::try_unwrap(resource_rc).map_err(|_| NetError::TcpStreamBusy)?;
|
||||||
let (read_half, write_half) = resource.into_inner();
|
let (read_half, write_half) = resource.into_inner();
|
||||||
let tcp_stream = read_half.reunite(write_half)?;
|
let tcp_stream = read_half.reunite(write_half).map_err(NetError::Reunite)?;
|
||||||
|
|
||||||
let local_addr = tcp_stream.local_addr()?;
|
let local_addr = tcp_stream.local_addr()?;
|
||||||
let remote_addr = tcp_stream.peer_addr()?;
|
let remote_addr = tcp_stream.peer_addr()?;
|
||||||
|
@ -345,7 +347,7 @@ pub async fn op_net_connect_tls<NP>(
|
||||||
#[serde] addr: IpAddr,
|
#[serde] addr: IpAddr,
|
||||||
#[serde] args: ConnectTlsArgs,
|
#[serde] args: ConnectTlsArgs,
|
||||||
#[cppgc] key_pair: &TlsKeysHolder,
|
#[cppgc] key_pair: &TlsKeysHolder,
|
||||||
) -> Result<(ResourceId, IpAddr, IpAddr), AnyError>
|
) -> Result<(ResourceId, IpAddr, IpAddr), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -359,9 +361,14 @@ where
|
||||||
let mut s = state.borrow_mut();
|
let mut s = state.borrow_mut();
|
||||||
let permissions = s.borrow_mut::<NP>();
|
let permissions = s.borrow_mut::<NP>();
|
||||||
permissions
|
permissions
|
||||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.connectTls()")?;
|
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.connectTls()")
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
if let Some(path) = cert_file {
|
if let Some(path) = cert_file {
|
||||||
Some(permissions.check_read(path, "Deno.connectTls()")?)
|
Some(
|
||||||
|
permissions
|
||||||
|
.check_read(path, "Deno.connectTls()")
|
||||||
|
.map_err(NetError::Permission)?,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -382,17 +389,18 @@ where
|
||||||
let root_cert_store = state
|
let root_cert_store = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.borrow::<DefaultTlsOptions>()
|
.borrow::<DefaultTlsOptions>()
|
||||||
.root_cert_store()?;
|
.root_cert_store()
|
||||||
|
.map_err(NetError::RootCertStore)?;
|
||||||
let hostname_dns = if let Some(server_name) = args.server_name {
|
let hostname_dns = if let Some(server_name) = args.server_name {
|
||||||
ServerName::try_from(server_name)
|
ServerName::try_from(server_name)
|
||||||
} else {
|
} else {
|
||||||
ServerName::try_from(addr.hostname.clone())
|
ServerName::try_from(addr.hostname.clone())
|
||||||
}
|
}
|
||||||
.map_err(|_| invalid_hostname(&addr.hostname))?;
|
.map_err(|_| NetError::InvalidHostname(addr.hostname.clone()))?;
|
||||||
let connect_addr = resolve_addr(&addr.hostname, addr.port)
|
let connect_addr = resolve_addr(&addr.hostname, addr.port)
|
||||||
.await?
|
.await?
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| generic_error("No resolved address found"))?;
|
.ok_or_else(|| NetError::NoResolvedAddress)?;
|
||||||
let tcp_stream = TcpStream::connect(connect_addr).await?;
|
let tcp_stream = TcpStream::connect(connect_addr).await?;
|
||||||
let local_addr = tcp_stream.local_addr()?;
|
let local_addr = tcp_stream.local_addr()?;
|
||||||
let remote_addr = tcp_stream.peer_addr()?;
|
let remote_addr = tcp_stream.peer_addr()?;
|
||||||
|
@ -444,7 +452,7 @@ pub fn op_net_listen_tls<NP>(
|
||||||
#[serde] addr: IpAddr,
|
#[serde] addr: IpAddr,
|
||||||
#[serde] args: ListenTlsArgs,
|
#[serde] args: ListenTlsArgs,
|
||||||
#[cppgc] keys: &TlsKeysHolder,
|
#[cppgc] keys: &TlsKeysHolder,
|
||||||
) -> Result<(ResourceId, IpAddr), AnyError>
|
) -> Result<(ResourceId, IpAddr), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -455,12 +463,13 @@ where
|
||||||
{
|
{
|
||||||
let permissions = state.borrow_mut::<NP>();
|
let permissions = state.borrow_mut::<NP>();
|
||||||
permissions
|
permissions
|
||||||
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenTls()")?;
|
.check_net(&(&addr.hostname, Some(addr.port)), "Deno.listenTls()")
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let bind_addr = resolve_addr_sync(&addr.hostname, addr.port)?
|
let bind_addr = resolve_addr_sync(&addr.hostname, addr.port)?
|
||||||
.next()
|
.next()
|
||||||
.ok_or_else(|| generic_error("No resolved address found"))?;
|
.ok_or(NetError::NoResolvedAddress)?;
|
||||||
|
|
||||||
let tcp_listener = if args.load_balanced {
|
let tcp_listener = if args.load_balanced {
|
||||||
TcpListener::bind_load_balanced(bind_addr)
|
TcpListener::bind_load_balanced(bind_addr)
|
||||||
|
@ -475,28 +484,24 @@ where
|
||||||
.map(|s| s.into_bytes())
|
.map(|s| s.into_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
let listener = match keys.take() {
|
let listener = match keys.take() {
|
||||||
TlsKeys::Null => Err(anyhow!("Deno.listenTls requires a key")),
|
TlsKeys::Null => return Err(NetError::ListenTlsRequiresKey),
|
||||||
TlsKeys::Static(TlsKey(cert, key)) => {
|
TlsKeys::Static(TlsKey(cert, key)) => {
|
||||||
let mut tls_config = ServerConfig::builder()
|
let mut tls_config = ServerConfig::builder()
|
||||||
.with_no_client_auth()
|
.with_no_client_auth()
|
||||||
.with_single_cert(cert, key)
|
.with_single_cert(cert, key)?;
|
||||||
.map_err(|e| anyhow!(e))?;
|
|
||||||
tls_config.alpn_protocols = alpn;
|
tls_config.alpn_protocols = alpn;
|
||||||
Ok(TlsListener {
|
TlsListener {
|
||||||
tcp_listener,
|
tcp_listener,
|
||||||
tls_config: Some(tls_config.into()),
|
tls_config: Some(tls_config.into()),
|
||||||
server_config_provider: None,
|
server_config_provider: None,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
TlsKeys::Resolver(resolver) => Ok(TlsListener {
|
TlsKeys::Resolver(resolver) => TlsListener {
|
||||||
tcp_listener,
|
tcp_listener,
|
||||||
tls_config: None,
|
tls_config: None,
|
||||||
server_config_provider: Some(resolver.into_server_config_provider(alpn)),
|
server_config_provider: Some(resolver.into_server_config_provider(alpn)),
|
||||||
}),
|
},
|
||||||
}
|
};
|
||||||
.map_err(|e| {
|
|
||||||
custom_error("InvalidData", "Error creating TLS certificate").context(e)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let tls_listener_resource = NetworkListenerResource::new(listener);
|
let tls_listener_resource = NetworkListenerResource::new(listener);
|
||||||
|
|
||||||
|
@ -510,23 +515,23 @@ where
|
||||||
pub async fn op_net_accept_tls(
|
pub async fn op_net_accept_tls(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
) -> Result<(ResourceId, IpAddr, IpAddr), AnyError> {
|
) -> Result<(ResourceId, IpAddr, IpAddr), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<NetworkListenerResource<TlsListener>>(rid)
|
.get::<NetworkListenerResource<TlsListener>>(rid)
|
||||||
.map_err(|_| bad_resource("Listener has been closed"))?;
|
.map_err(|_| NetError::ListenerClosed)?;
|
||||||
|
|
||||||
let cancel_handle = RcRef::map(&resource, |r| &r.cancel);
|
let cancel_handle = RcRef::map(&resource, |r| &r.cancel);
|
||||||
let listener = RcRef::map(&resource, |r| &r.listener)
|
let listener = RcRef::map(&resource, |r| &r.listener)
|
||||||
.try_borrow_mut()
|
.try_borrow_mut()
|
||||||
.ok_or_else(|| custom_error("Busy", "Another accept task is ongoing"))?;
|
.ok_or_else(|| NetError::AcceptTaskOngoing)?;
|
||||||
|
|
||||||
let (tls_stream, remote_addr) =
|
let (tls_stream, remote_addr) =
|
||||||
match listener.accept().try_or_cancel(&cancel_handle).await {
|
match listener.accept().try_or_cancel(&cancel_handle).await {
|
||||||
Ok(tuple) => tuple,
|
Ok(tuple) => tuple,
|
||||||
Err(err) if err.kind() == ErrorKind::Interrupted => {
|
Err(err) if err.kind() == ErrorKind::Interrupted => {
|
||||||
return Err(bad_resource("Listener has been closed"));
|
return Err(NetError::ListenerClosed);
|
||||||
}
|
}
|
||||||
Err(err) => return Err(err.into()),
|
Err(err) => return Err(err.into()),
|
||||||
};
|
};
|
||||||
|
@ -547,11 +552,11 @@ pub async fn op_net_accept_tls(
|
||||||
pub async fn op_tls_handshake(
|
pub async fn op_tls_handshake(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
) -> Result<TlsHandshakeInfo, AnyError> {
|
) -> Result<TlsHandshakeInfo, NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<TlsStreamResource>(rid)
|
.get::<TlsStreamResource>(rid)
|
||||||
.map_err(|_| bad_resource("Listener has been closed"))?;
|
.map_err(|_| NetError::ListenerClosed)?;
|
||||||
resource.handshake().await
|
resource.handshake().await.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use crate::io::UnixStreamResource;
|
use crate::io::UnixStreamResource;
|
||||||
|
use crate::ops::NetError;
|
||||||
use crate::raw::NetworkListenerResource;
|
use crate::raw::NetworkListenerResource;
|
||||||
use crate::NetPermissions;
|
use crate::NetPermissions;
|
||||||
use deno_core::error::bad_resource;
|
|
||||||
use deno_core::error::custom_error;
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use deno_core::op2;
|
use deno_core::op2;
|
||||||
use deno_core::AsyncRefCell;
|
use deno_core::AsyncRefCell;
|
||||||
use deno_core::CancelHandle;
|
use deno_core::CancelHandle;
|
||||||
|
@ -26,11 +24,8 @@ use tokio::net::UnixListener;
|
||||||
pub use tokio::net::UnixStream;
|
pub use tokio::net::UnixStream;
|
||||||
|
|
||||||
/// A utility function to map OsStrings to Strings
|
/// A utility function to map OsStrings to Strings
|
||||||
pub fn into_string(s: std::ffi::OsString) -> Result<String, AnyError> {
|
pub fn into_string(s: std::ffi::OsString) -> Result<String, NetError> {
|
||||||
s.into_string().map_err(|s| {
|
s.into_string().map_err(NetError::InvalidUtf8)
|
||||||
let message = format!("File name or path {s:?} is not valid UTF-8");
|
|
||||||
custom_error("InvalidData", message)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct UnixDatagramResource {
|
pub struct UnixDatagramResource {
|
||||||
|
@ -63,15 +58,15 @@ pub struct UnixListenArgs {
|
||||||
pub async fn op_net_accept_unix(
|
pub async fn op_net_accept_unix(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
) -> Result<(ResourceId, Option<String>, Option<String>), AnyError> {
|
) -> Result<(ResourceId, Option<String>, Option<String>), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<NetworkListenerResource<UnixListener>>(rid)
|
.get::<NetworkListenerResource<UnixListener>>(rid)
|
||||||
.map_err(|_| bad_resource("Listener has been closed"))?;
|
.map_err(|_| NetError::ListenerClosed)?;
|
||||||
let listener = RcRef::map(&resource, |r| &r.listener)
|
let listener = RcRef::map(&resource, |r| &r.listener)
|
||||||
.try_borrow_mut()
|
.try_borrow_mut()
|
||||||
.ok_or_else(|| custom_error("Busy", "Listener already in use"))?;
|
.ok_or(NetError::ListenerBusy)?;
|
||||||
let cancel = RcRef::map(resource, |r| &r.cancel);
|
let cancel = RcRef::map(resource, |r| &r.cancel);
|
||||||
let (unix_stream, _socket_addr) = listener
|
let (unix_stream, _socket_addr) = listener
|
||||||
.accept()
|
.accept()
|
||||||
|
@ -95,7 +90,7 @@ pub async fn op_net_accept_unix(
|
||||||
pub async fn op_net_connect_unix<NP>(
|
pub async fn op_net_connect_unix<NP>(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[string] address_path: String,
|
#[string] address_path: String,
|
||||||
) -> Result<(ResourceId, Option<String>, Option<String>), AnyError>
|
) -> Result<(ResourceId, Option<String>, Option<String>), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -103,10 +98,12 @@ where
|
||||||
let mut state_ = state.borrow_mut();
|
let mut state_ = state.borrow_mut();
|
||||||
let address_path = state_
|
let address_path = state_
|
||||||
.borrow_mut::<NP>()
|
.borrow_mut::<NP>()
|
||||||
.check_read(&address_path, "Deno.connect()")?;
|
.check_read(&address_path, "Deno.connect()")
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
_ = state_
|
_ = state_
|
||||||
.borrow_mut::<NP>()
|
.borrow_mut::<NP>()
|
||||||
.check_write_path(&address_path, "Deno.connect()")?;
|
.check_write_path(&address_path, "Deno.connect()")
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
address_path
|
address_path
|
||||||
};
|
};
|
||||||
let unix_stream = UnixStream::connect(&address_path).await?;
|
let unix_stream = UnixStream::connect(&address_path).await?;
|
||||||
|
@ -127,15 +124,15 @@ pub async fn op_net_recv_unixpacket(
|
||||||
state: Rc<RefCell<OpState>>,
|
state: Rc<RefCell<OpState>>,
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
#[buffer] mut buf: JsBuffer,
|
#[buffer] mut buf: JsBuffer,
|
||||||
) -> Result<(usize, Option<String>), AnyError> {
|
) -> Result<(usize, Option<String>), NetError> {
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<UnixDatagramResource>(rid)
|
.get::<UnixDatagramResource>(rid)
|
||||||
.map_err(|_| bad_resource("Socket has been closed"))?;
|
.map_err(|_| NetError::SocketClosed)?;
|
||||||
let socket = RcRef::map(&resource, |r| &r.socket)
|
let socket = RcRef::map(&resource, |r| &r.socket)
|
||||||
.try_borrow_mut()
|
.try_borrow_mut()
|
||||||
.ok_or_else(|| custom_error("Busy", "Socket already in use"))?;
|
.ok_or(NetError::SocketBusy)?;
|
||||||
let cancel = RcRef::map(resource, |r| &r.cancel);
|
let cancel = RcRef::map(resource, |r| &r.cancel);
|
||||||
let (nread, remote_addr) =
|
let (nread, remote_addr) =
|
||||||
socket.recv_from(&mut buf).try_or_cancel(cancel).await?;
|
socket.recv_from(&mut buf).try_or_cancel(cancel).await?;
|
||||||
|
@ -150,24 +147,25 @@ pub async fn op_net_send_unixpacket<NP>(
|
||||||
#[smi] rid: ResourceId,
|
#[smi] rid: ResourceId,
|
||||||
#[string] address_path: String,
|
#[string] address_path: String,
|
||||||
#[buffer] zero_copy: JsBuffer,
|
#[buffer] zero_copy: JsBuffer,
|
||||||
) -> Result<usize, AnyError>
|
) -> Result<usize, NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
let address_path = {
|
let address_path = {
|
||||||
let mut s = state.borrow_mut();
|
let mut s = state.borrow_mut();
|
||||||
s.borrow_mut::<NP>()
|
s.borrow_mut::<NP>()
|
||||||
.check_write(&address_path, "Deno.DatagramConn.send()")?
|
.check_write(&address_path, "Deno.DatagramConn.send()")
|
||||||
|
.map_err(NetError::Permission)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let resource = state
|
let resource = state
|
||||||
.borrow()
|
.borrow()
|
||||||
.resource_table
|
.resource_table
|
||||||
.get::<UnixDatagramResource>(rid)
|
.get::<UnixDatagramResource>(rid)
|
||||||
.map_err(|_| custom_error("NotConnected", "Socket has been closed"))?;
|
.map_err(|_| NetError::SocketClosedNotConnected)?;
|
||||||
let socket = RcRef::map(&resource, |r| &r.socket)
|
let socket = RcRef::map(&resource, |r| &r.socket)
|
||||||
.try_borrow_mut()
|
.try_borrow_mut()
|
||||||
.ok_or_else(|| custom_error("Busy", "Socket already in use"))?;
|
.ok_or(NetError::SocketBusy)?;
|
||||||
let nwritten = socket.send_to(&zero_copy, address_path).await?;
|
let nwritten = socket.send_to(&zero_copy, address_path).await?;
|
||||||
|
|
||||||
Ok(nwritten)
|
Ok(nwritten)
|
||||||
|
@ -179,14 +177,18 @@ pub fn op_net_listen_unix<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] address_path: String,
|
#[string] address_path: String,
|
||||||
#[string] api_name: String,
|
#[string] api_name: String,
|
||||||
) -> Result<(ResourceId, Option<String>), AnyError>
|
) -> Result<(ResourceId, Option<String>), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
let permissions = state.borrow_mut::<NP>();
|
let permissions = state.borrow_mut::<NP>();
|
||||||
let api_call_expr = format!("{}()", api_name);
|
let api_call_expr = format!("{}()", api_name);
|
||||||
let address_path = permissions.check_read(&address_path, &api_call_expr)?;
|
let address_path = permissions
|
||||||
_ = permissions.check_write_path(&address_path, &api_call_expr)?;
|
.check_read(&address_path, &api_call_expr)
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
|
_ = permissions
|
||||||
|
.check_write_path(&address_path, &api_call_expr)
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
let listener = UnixListener::bind(address_path)?;
|
let listener = UnixListener::bind(address_path)?;
|
||||||
let local_addr = listener.local_addr()?;
|
let local_addr = listener.local_addr()?;
|
||||||
let pathname = local_addr.as_pathname().map(pathstring).transpose()?;
|
let pathname = local_addr.as_pathname().map(pathstring).transpose()?;
|
||||||
|
@ -198,14 +200,17 @@ where
|
||||||
pub fn net_listen_unixpacket<NP>(
|
pub fn net_listen_unixpacket<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
address_path: String,
|
address_path: String,
|
||||||
) -> Result<(ResourceId, Option<String>), AnyError>
|
) -> Result<(ResourceId, Option<String>), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
let permissions = state.borrow_mut::<NP>();
|
let permissions = state.borrow_mut::<NP>();
|
||||||
let address_path =
|
let address_path = permissions
|
||||||
permissions.check_read(&address_path, "Deno.listenDatagram()")?;
|
.check_read(&address_path, "Deno.listenDatagram()")
|
||||||
_ = permissions.check_write_path(&address_path, "Deno.listenDatagram()")?;
|
.map_err(NetError::Permission)?;
|
||||||
|
_ = permissions
|
||||||
|
.check_write_path(&address_path, "Deno.listenDatagram()")
|
||||||
|
.map_err(NetError::Permission)?;
|
||||||
let socket = UnixDatagram::bind(address_path)?;
|
let socket = UnixDatagram::bind(address_path)?;
|
||||||
let local_addr = socket.local_addr()?;
|
let local_addr = socket.local_addr()?;
|
||||||
let pathname = local_addr.as_pathname().map(pathstring).transpose()?;
|
let pathname = local_addr.as_pathname().map(pathstring).transpose()?;
|
||||||
|
@ -222,7 +227,7 @@ where
|
||||||
pub fn op_net_listen_unixpacket<NP>(
|
pub fn op_net_listen_unixpacket<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
) -> Result<(ResourceId, Option<String>), AnyError>
|
) -> Result<(ResourceId, Option<String>), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -235,13 +240,13 @@ where
|
||||||
pub fn op_node_unstable_net_listen_unixpacket<NP>(
|
pub fn op_node_unstable_net_listen_unixpacket<NP>(
|
||||||
state: &mut OpState,
|
state: &mut OpState,
|
||||||
#[string] path: String,
|
#[string] path: String,
|
||||||
) -> Result<(ResourceId, Option<String>), AnyError>
|
) -> Result<(ResourceId, Option<String>), NetError>
|
||||||
where
|
where
|
||||||
NP: NetPermissions + 'static,
|
NP: NetPermissions + 'static,
|
||||||
{
|
{
|
||||||
net_listen_unixpacket::<NP>(state, path)
|
net_listen_unixpacket::<NP>(state, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pathstring(pathname: &Path) -> Result<String, AnyError> {
|
pub fn pathstring(pathname: &Path) -> Result<String, NetError> {
|
||||||
into_string(pathname.into())
|
into_string(pathname.into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use deno_core::error::AnyError;
|
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
use tokio::net::lookup_host;
|
use tokio::net::lookup_host;
|
||||||
|
@ -9,7 +8,7 @@ use tokio::net::lookup_host;
|
||||||
pub async fn resolve_addr(
|
pub async fn resolve_addr(
|
||||||
hostname: &str,
|
hostname: &str,
|
||||||
port: u16,
|
port: u16,
|
||||||
) -> Result<impl Iterator<Item = SocketAddr> + '_, AnyError> {
|
) -> Result<impl Iterator<Item = SocketAddr> + '_, std::io::Error> {
|
||||||
let addr_port_pair = make_addr_port_pair(hostname, port);
|
let addr_port_pair = make_addr_port_pair(hostname, port);
|
||||||
let result = lookup_host(addr_port_pair).await?;
|
let result = lookup_host(addr_port_pair).await?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
@ -19,7 +18,7 @@ pub async fn resolve_addr(
|
||||||
pub fn resolve_addr_sync(
|
pub fn resolve_addr_sync(
|
||||||
hostname: &str,
|
hostname: &str,
|
||||||
port: u16,
|
port: u16,
|
||||||
) -> Result<impl Iterator<Item = SocketAddr>, AnyError> {
|
) -> Result<impl Iterator<Item = SocketAddr>, std::io::Error> {
|
||||||
let addr_port_pair = make_addr_port_pair(hostname, port);
|
let addr_port_pair = make_addr_port_pair(hostname, port);
|
||||||
let result = addr_port_pair.to_socket_addrs()?;
|
let result = addr_port_pair.to_socket_addrs()?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
|
|
@ -23,6 +23,7 @@ use deno_ffi::DlfcnError;
|
||||||
use deno_ffi::IRError;
|
use deno_ffi::IRError;
|
||||||
use deno_ffi::ReprError;
|
use deno_ffi::ReprError;
|
||||||
use deno_ffi::StaticError;
|
use deno_ffi::StaticError;
|
||||||
|
use deno_net::ops::NetError;
|
||||||
use deno_tls::TlsError;
|
use deno_tls::TlsError;
|
||||||
use deno_webstorage::WebStorageError;
|
use deno_webstorage::WebStorageError;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -292,6 +293,48 @@ fn get_broadcast_channel_error(error: &BroadcastChannelError) -> &'static str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_net_error(error: &NetError) -> &'static str {
|
||||||
|
match error {
|
||||||
|
NetError::ListenerClosed => "BadResource",
|
||||||
|
NetError::ListenerBusy => "Busy",
|
||||||
|
NetError::SocketClosed => "BadResource",
|
||||||
|
NetError::SocketClosedNotConnected => "NotConnected",
|
||||||
|
NetError::SocketBusy => "Busy",
|
||||||
|
NetError::Io(e) => get_io_error_class(e),
|
||||||
|
NetError::AcceptTaskOngoing => "Busy",
|
||||||
|
NetError::RootCertStore(e)
|
||||||
|
| NetError::Permission(e)
|
||||||
|
| NetError::Resource(e) => get_error_class_name(e).unwrap_or("Error"),
|
||||||
|
NetError::NoResolvedAddress => "Error",
|
||||||
|
NetError::AddrParse(_) => "Error",
|
||||||
|
NetError::Map(e) => get_net_map_error(e),
|
||||||
|
NetError::Canceled(e) => {
|
||||||
|
let io_err: io::Error = e.to_owned().into();
|
||||||
|
get_io_error_class(&io_err)
|
||||||
|
}
|
||||||
|
NetError::DnsNotFound(_) => "NotFound",
|
||||||
|
NetError::DnsNotConnected(_) => "NotConnected",
|
||||||
|
NetError::DnsTimedOut(_) => "TimedOut",
|
||||||
|
NetError::Dns(_) => "Error",
|
||||||
|
NetError::UnsupportedRecordType => "NotSupported",
|
||||||
|
NetError::InvalidUtf8(_) => "InvalidData",
|
||||||
|
NetError::UnexpectedKeyType => "Error",
|
||||||
|
NetError::InvalidHostname(_) => "TypeError",
|
||||||
|
NetError::TcpStreamBusy => "Busy",
|
||||||
|
NetError::Rustls(_) => "Error",
|
||||||
|
NetError::Tls(e) => get_tls_error_class(e),
|
||||||
|
NetError::ListenTlsRequiresKey => "InvalidData",
|
||||||
|
NetError::Reunite(_) => "Error",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_net_map_error(error: &deno_net::io::MapError) -> &'static str {
|
||||||
|
match error {
|
||||||
|
deno_net::io::MapError::Io(e) => get_io_error_class(e),
|
||||||
|
deno_net::io::MapError::NoResources => "Error",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> {
|
pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> {
|
||||||
deno_core::error::get_custom_error_class(e)
|
deno_core::error::get_custom_error_class(e)
|
||||||
.or_else(|| deno_webgpu::error::get_error_class_name(e))
|
.or_else(|| deno_webgpu::error::get_error_class_name(e))
|
||||||
|
@ -316,6 +359,11 @@ pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> {
|
||||||
.or_else(|| e.downcast_ref::<CronError>().map(get_cron_error_class))
|
.or_else(|| e.downcast_ref::<CronError>().map(get_cron_error_class))
|
||||||
.or_else(|| e.downcast_ref::<CanvasError>().map(get_canvas_error))
|
.or_else(|| e.downcast_ref::<CanvasError>().map(get_canvas_error))
|
||||||
.or_else(|| e.downcast_ref::<CacheError>().map(get_cache_error))
|
.or_else(|| e.downcast_ref::<CacheError>().map(get_cache_error))
|
||||||
|
.or_else(|| e.downcast_ref::<NetError>().map(get_net_error))
|
||||||
|
.or_else(|| {
|
||||||
|
e.downcast_ref::<deno_net::io::MapError>()
|
||||||
|
.map(get_net_map_error)
|
||||||
|
})
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
e.downcast_ref::<BroadcastChannelError>()
|
e.downcast_ref::<BroadcastChannelError>()
|
||||||
.map(get_broadcast_channel_error)
|
.map(get_broadcast_channel_error)
|
||||||
|
|
Loading…
Reference in a new issue