;
+ }
+}
diff --git a/ext/quic/lib.rs b/ext/quic/lib.rs
new file mode 100644
index 00000000000000..3a6a43868d26fb
--- /dev/null
+++ b/ext/quic/lib.rs
@@ -0,0 +1,604 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+
+use deno_core::error::generic_error;
+use deno_core::error::type_error;
+use deno_core::error::AnyError;
+use deno_core::op2;
+use deno_core::AsyncRefCell;
+use deno_core::AsyncResult;
+use deno_core::BufView;
+use deno_core::OpState;
+use deno_core::RcRef;
+use deno_core::Resource;
+use deno_core::ResourceId;
+use deno_core::WriteOutcome;
+use deno_net::resolve_addr::resolve_addr;
+use deno_net::DefaultTlsOptions;
+use deno_net::NetPermissions;
+use deno_net::UnsafelyIgnoreCertificateErrors;
+use deno_tls::create_client_config;
+use deno_tls::load_certs;
+use deno_tls::load_private_keys;
+use deno_tls::RootCertStoreProvider;
+use deno_tls::SocketUse;
+use serde::Deserialize;
+use serde::Serialize;
+use std::borrow::Cow;
+use std::cell::RefCell;
+use std::io::BufReader;
+use std::path::PathBuf;
+use std::rc::Rc;
+use std::sync::Arc;
+
+pub fn get_declaration() -> PathBuf {
+ PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_quic.d.ts")
+}
+
+pub const UNSTABLE_FEATURE_NAME: &str = "quic";
+
+deno_core::extension!(
+ deno_quic,
+ // deps = [],
+ parameters = [ P: NetPermissions ],
+ ops = [
+ op_quic_listen,
+ op_quic_accept,
+ op_quic_connect
,
+ op_quic_accept_bi,
+ op_quic_accept_uni,
+ op_quic_open_bi,
+ op_quic_open_uni,
+ op_quic_open_datagrams,
+ op_quic_max_datagram_size,
+ op_quic_close_connection,
+ op_quic_close_endpoint,
+ op_quic_connection_closed,
+ op_quic_get_send_stream_priority,
+ op_quic_set_send_stream_priority,
+ ],
+ esm = ["01_quic.js"],
+ options = {
+ root_cert_store_provider: Option>,
+ unsafely_ignore_certificate_errors: Option>,
+ },
+ state = |state, options| {
+ state.put(DefaultTlsOptions {
+ root_cert_store_provider: options.root_cert_store_provider,
+ });
+ state.put(UnsafelyIgnoreCertificateErrors(
+ options.unsafely_ignore_certificate_errors,
+ ));
+ },
+);
+
+#[derive(Debug, Deserialize, Serialize)]
+pub struct Addr {
+ pub hostname: String,
+ pub port: u16,
+}
+
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ListenArgs {
+ cert: String,
+ key: String,
+ alpn_protocols: Option>,
+}
+
+struct EndpointResource(quinn::Endpoint);
+
+impl Resource for EndpointResource {
+ fn name(&self) -> Cow {
+ "quicListener".into()
+ }
+}
+
+#[op2(async)]
+#[serde]
+async fn op_quic_listen(
+ state: Rc>,
+ #[serde] addr: Addr,
+ #[serde] args: ListenArgs,
+) -> Result<(ResourceId, Addr), AnyError>
+where
+ NP: NetPermissions + 'static,
+{
+ state
+ .borrow_mut()
+ .borrow_mut::()
+ .check_net(&(&addr.hostname, Some(addr.port)), "Deno.connectQuic()")?;
+
+ let cert_chain = load_certs(&mut BufReader::new(args.cert.as_bytes()))?;
+ let key_der = load_private_keys(args.key.as_bytes())?.remove(0);
+
+ let addr = resolve_addr(&addr.hostname, addr.port)
+ .await?
+ .next()
+ .ok_or_else(|| generic_error("No resolved address found"))?;
+
+ let mut crypto = rustls::ServerConfig::builder()
+ .with_safe_defaults()
+ .with_no_client_auth()
+ .with_single_cert(cert_chain, key_der)?;
+ if let Some(alpn_protocols) = args.alpn_protocols {
+ crypto.alpn_protocols = alpn_protocols
+ .into_iter()
+ .map(|alpn| alpn.into_bytes())
+ .collect();
+ }
+ let config = quinn::ServerConfig::with_crypto(Arc::new(crypto));
+ let endpoint = quinn::Endpoint::server(config, addr)?;
+
+ let addr = endpoint.local_addr()?;
+ let addr = Addr {
+ hostname: format!("{}", addr.ip()),
+ port: addr.port(),
+ };
+
+ let rid = state
+ .borrow_mut()
+ .resource_table
+ .add(EndpointResource(endpoint));
+ Ok((rid, addr))
+}
+
+#[derive(Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct CloseInfo {
+ close_code: u64,
+ reason: String,
+}
+
+#[op2]
+#[serde]
+fn op_quic_close_endpoint(
+ state: Rc>,
+ #[smi] rid: ResourceId,
+ #[serde] info: CloseInfo,
+) -> Result<(), AnyError> {
+ let endpoint = {
+ state
+ .borrow_mut()
+ .resource_table
+ .get::(rid)?
+ .0
+ .clone()
+ };
+ endpoint.close(
+ quinn::VarInt::from_u64(info.close_code)?,
+ info.reason.as_bytes(),
+ );
+ Ok(())
+}
+
+struct ConnectionResource(quinn::Connection);
+
+impl Resource for ConnectionResource {
+ fn name(&self) -> Cow {
+ "quicConnection".into()
+ }
+
+ fn read(self: Rc, _limit: usize) -> AsyncResult {
+ Box::pin(async move {
+ let data = self.0.read_datagram().await?;
+ Ok(BufView::from(data))
+ })
+ }
+
+ fn write(self: Rc, view: BufView) -> AsyncResult {
+ Box::pin(async move {
+ let len = view.len();
+ self.0.send_datagram(view.into())?;
+ Ok(WriteOutcome::Full { nwritten: len })
+ })
+ }
+}
+
+#[op2(async)]
+#[serde]
+async fn op_quic_accept(
+ state: Rc>,
+ #[smi] rid: ResourceId,
+) -> Result