diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ae3e54..d470df1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,65 +18,34 @@ concurrency: name: Webtransport CI jobs: build: - name: ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }} if: | - github.event_name == 'push' || - !startsWith(github.event.pull_request.head.label, 'hironichu:') - runs-on: ${{ matrix.os }} - timeout-minutes: 90 + github.event_name == 'push' || !startsWith(github.event.pull_request.head.label, 'hironichu:') strategy: matrix: + os: [ 'ubuntu-latest', 'self-hosted'] + job: [build] + profile: [debug, release] include: - - os: macos-latest - job: test - profile: debug - - os: macos-latest - job: test - profile: release - - os: windows-latest - job: test - profile: debug - - os: windows-latest - job: test - profile: release - - os: 'ubuntu-22.04' - job: test - profile: release - use_sysroot: true - - os: 'ubuntu-22.04' - job: test - profile: debug - - - os: 'ubuntu-22.04' + - os: 'ubuntu-latest' job: lint profile: debug - - os: 'self-hosted' - job: test - profile: debug - - - os: 'self-hosted' - job: test - profile: release - fail-fast: ${{ github.event_name == 'pull_request' || (github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/')) }} + name: ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }} + runs-on: ${{ matrix.os }} + timeout-minutes: 10 env: CARGO_TERM_COLOR: always RUST_BACKTRACE: full steps: - - name: Configure git - run: | - git config --global core.symlinks true - git config --global fetch.parallel 4 - name: Clone repository uses: actions/checkout@v3 with: fetch-depth: 2 - submodules: recursive - name: Create source tarballs (release, linux) if: | startsWith(matrix.os, 'ubuntu') && matrix.profile == 'release' && - matrix.job == 'test' && + matrix.job == 'build' && github.repository == 'hironichu/webtransport' && startsWith(github.ref, 'refs/tags/') run: | @@ -86,9 +55,10 @@ jobs: - name: Setting Up Rust uses: dtolnay/rust-toolchain@master + if: | + matrix.job != 'lint' with: - toolchain: nightly - + toolchain: stable - name: Install Deno from .land if: matrix.os != 'self-hosted' uses: denoland/setup-deno@v1 @@ -108,37 +78,6 @@ jobs: - name: Error on warning run: echo "RUSTFLAGS=-D warnings" >> $GITHUB_ENV - - name: Log versions - shell: bash - run: | - rustc --version - cargo --version - deno --version - - - name: Cache build output (main) - uses: actions/cache@v3 - if: (matrix.job == 'test' && matrix.profile == 'release') && - github.ref == 'refs/heads/main' - with: - path: | - !./target/*/*.dll - !./target/*/*.so - !./target/*/*.dylib - key: | - 16-cargo-target-${{ matrix.os }}-${{ matrix.profile }}-${{ github.sha }} - - name: Cache build output (PR) - uses: actions/cache@v3 - if: github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/') && - matrix.job == 'test' && matrix.profile == 'release' - with: - path: | - !./target/*/*.dll - !./target/*/*.so - !./target/*/*.dylib - key: never_saved - restore-keys: | - 16-cargo-target-${{ matrix.os }}-${{ matrix.profile }}- - - name: Deno Format if: matrix.job == 'lint' run: deno task util:fmt @@ -149,34 +88,104 @@ jobs: - name: Build Debug if: | - (!startsWith(matrix.os, 'self-hosted')) && - (matrix.job == 'test' && matrix.profile == 'debug') - run: deno task build:debug - - - name: Build Debug ARM - if: | - (startsWith(matrix.os, 'self-hosted')) && - (matrix.job == 'test' && matrix.profile == 'debug') - run: | - deno task build:debug-arm + (matrix.job == 'build' && matrix.profile == 'debug') + run: deno task build:${{matrix.profile}} - name: Build release if: | - (!startsWith(matrix.os, 'self-hosted')) && - (matrix.job == 'test' && matrix.profile == 'release') && + (matrix.job == 'build' && matrix.profile == 'release') && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) - run: deno task build:release + run: deno task build:${{matrix.profile}} - - name: Build release Linux ARM + - name: Move arm file (release) + if: startsWith(matrix.os, 'self-hosted') && matrix.job == 'build' && matrix.profile == 'release' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) + run: | + mv target/${{matrix.profile}}/libwebtransport.so target/${{matrix.profile}}/libwebtransport_aarch64.so + + - name: Move arm file (debug) + if: startsWith(matrix.os, 'self-hosted') && matrix.job == 'build' && matrix.profile == 'debug' + run: | + mv target/${{matrix.profile}}/libwebtransport.so target/${{matrix.profile}}/libwebtransport_aarch64.so + - name: Upload artifact (release) + uses: actions/upload-artifact@master + if: | + (matrix.job == 'build' && matrix.profile == 'release') && + ((github.ref == 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/'))) + with: + name: release + path: | + target/${{matrix.profile}}/webtransport.dll + target/${{matrix.profile}}/libwebtransport.so + target/${{matrix.profile}}/libwebtransport_aarch64.so + target/${{matrix.profile}}/libwebtransport.dylib + - name: Upload artifact (debug) + uses: actions/upload-artifact@master + if: | + matrix.job == 'build' && matrix.profile == 'debug' && !startsWith(github.ref, 'refs/tags/') + with: + name: debug + path: | + target/${{matrix.profile}}/webtransport.dll + target/${{matrix.profile}}/libwebtransport.so + target/${{matrix.profile}}/libwebtransport_aarch64.so + target/${{matrix.profile}}/libwebtransport.dylib + - name: Upload release to GitHub + uses: softprops/action-gh-release@59c3b4891632ff9a897f99a91d7bc557467a3a22 if: | - (startsWith(matrix.os, 'self-hosted')) && - (matrix.job == 'test' && matrix.profile == 'release') && (matrix.use_sysroot || - (github.repository == 'hironichu/webtransport' && - (github.ref == 'refs/heads/main' || - startsWith(github.ref, 'refs/tags/')))) + (matrix.job == 'build' && matrix.profile == 'release') && + github.repository == 'hironichu/webtransport' && + github.ref == 'refs/heads/main' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + files: | + target/${{matrix.profile}}/webtransport.dll + target/${{matrix.profile}}/libwebtransport.so + target/${{matrix.profile}}/libwebtransport_aarch64.so + target/${{matrix.profile}}/libwebtransport.dylib + draft: true + test: + needs: build + if: | + github.event_name == 'push' || !startsWith(github.event.pull_request.head.label, 'hironichu:') + strategy: + matrix: + os: [ 'ubuntu-latest', 'self-hosted'] + job: [test] + profile: [debug, release] + name: ${{ matrix.job }} ${{ matrix.profile }} ${{ matrix.os }} + runs-on: ${{ matrix.os }} + timeout-minutes: 5 + + steps: + - uses: actions/checkout@master + - name: Creating target structure run: | - deno task build:release-arm + mkdir -p target + + - name: Download artifact + uses: actions/download-artifact@master + with: + path: target + - name: Display structure of downloaded files + run: ls -R + - name: Install Deno from .land + if: matrix.os != 'self-hosted' + uses: denoland/setup-deno@v1 + with: + deno-version: v1.x + + - name: Install Deno from source + if: matrix.os == 'self-hosted' + run: | + echo "Check if Deno is already installed" + if ! type deno > /dev/null; then + echo "Deno is not installed, installing..." + curl -s https://gist.githubusercontent.com/LukeChannings/09d53f5c364391042186518c8598b85e/raw/ac8cd8c675b985edd4b3e16df63ffef14d1f0e24/deno_install.sh | sh + else + echo "Deno is already installed" + fi - name: Run deno test (debug) if: | matrix.job == 'test' && matrix.profile == 'debug' && !startsWith(github.ref, 'refs/tags/') @@ -194,19 +203,4 @@ jobs: BUILD_TARGET: release DEVELOPMENT: true run: | - deno task test - - name: Upload release to GitHub - uses: softprops/action-gh-release@59c3b4891632ff9a897f99a91d7bc557467a3a22 - if: | - (matrix.job == 'test' && matrix.profile == 'release') && - github.repository == 'hironichu/webtransport' && - github.ref == 'refs/heads/main' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - files: | - dist/webtransport.dll - dist/libwebtransport.so - dist/libwebtransport_aarch64.so - dist/libwebtransport.dylib - draft: true \ No newline at end of file + deno task test \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 156432a..ea236c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "webtransport" +name = "Webtransport" description = "Deno WebTransport FFI library for Deno" version = "0.1.0" edition = "2021" @@ -47,6 +47,7 @@ tokio = { version = "=1.32.0", default-features = false, features = [ wtransport = { git = "https://github.com/hironichu/wtransport", branch = "feat/new", features = [ "dangerous-configuration", ] } +wtransport-proto = { git = "https://github.com/hironichu/wtransport", branch = "feat/new" } rcgen = "=0.11.1" ring = "=0.16.20" time = "=0.3.28" diff --git a/deno.jsonc b/deno.jsonc index c7c98b4..3b25d9e 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -6,17 +6,16 @@ "example:web": "deno run -A ./examples/web_server/web.js", "example:server": "deno run -A --unstable ./examples/deno/wt_server.ts", "example:client": "deno run -A --unstable ./examples/deno/wt_client.ts", - // Build task - "build:release": "deno task util:clean && cargo build --out-dir ./dist -Z unstable-options --release", - "build:release-arm": "deno task util:clean && cargo build --out-dir ./dist -Z unstable-options --release && mv ./dist/libwebtransport.so ./dist/libwebtransport_aarch64.so", - "build:debug": "deno task util:clean && cargo build --out-dir ./dist -Z unstable-options", - "build:debug-arm": "deno task util:clean && cargo build --out-dir ./dist -Z unstable-options && mv ./dist/libwebtransport.so ./dist/libwebtransport_aarch64.so", + // CI Build task + "build:release": "cargo clean && cargo build --release", + "build:debug": "cargo clean && cargo build", //Utils - "util:clean": "deno run --allow-write --allow-read ./utils/clean.js", "util:fmt": "deno fmt --unstable", "util:lint": "deno lint --unstable", //Tests - "test": "deno test -A --unstable examples/deno/wt_server_test.ts" + "test": "deno test -A --unstable ", + //Non CI build + "build": "cargo build" }, "compilerOptions": { "checkJs": true, diff --git a/examples/deno/wt_client_test.ts b/examples/deno/wt_client_test.ts index 1b8b1eb..9094858 100644 --- a/examples/deno/wt_client_test.ts +++ b/examples/deno/wt_client_test.ts @@ -35,6 +35,7 @@ Deno.test( sanitizeResources: false, }, async () => { + //THis causes panic??????? // const server = new WebTransportServer(4433, { // certFile: "./certs/cert.pem", // keyFile: "./certs/key.pem", diff --git a/examples/deno/wt_server_test.ts b/examples/deno/wt_server_test.ts index 00fa685..2d88cbc 100644 --- a/examples/deno/wt_server_test.ts +++ b/examples/deno/wt_server_test.ts @@ -1,25 +1,51 @@ -import "../../mod/mod.ts"; -Deno.test({ name: "Server startup/close" }, async () => { - const server = new WebTransportServer(4433, { - certFile: "./certs/cert.pem", - keyFile: "./certs/key.pem", - maxTimeout: 10, - keepAlive: 3, - }); +// import { join } from "https://deno.land/std@0.201.0/path/mod.ts"; +// import { GenerateCertKeyFile } from "../../mod/crypto.ts"; +// import "../../mod/mod.ts"; +// import { assert } from "https://deno.land/std@0.201.0/assert/assert.ts"; - await server.close(); -}); +// //add certs cleanup methods after tests +// const certPath = join(Deno.cwd(), "./certs/"); +// Deno.test({ name: "Server startup/close" }, () => { +// //generate a certificate +// const [cert, key] = GenerateCertKeyFile( +// "localhost", +// 0, +// 10, +// undefined, +// "cert.pem", +// "key.pem", +// ); +// const server = new WebTransportServer(4433, { +// certFile: cert, +// keyFile: key, +// maxTimeout: 10, +// keepAlive: 3, +// }); +// server.close(); +// //try to start a UDP socket on the same port to see if it's closed +// const sock = Deno.listenDatagram({ +// hostname: "0.0.0.0", +// port: 4433, +// transport: "udp", +// }); +// assert(sock, "Server did not close"); +// sock.close(); +// }); -// Deno.test( -// { name: "Server with generated certificate startup/close" }, -// async () => { -// const server = new WebTransportServer(4434, { -// maxTimeout: 10, -// keepAlive: 3, -// notAfter: 10, -// notBefore: 0, -// domain: "localhost", -// }); -// await server.close(); -// }, -// ); +// // Deno.test( +// // { name: "Server with generated certificate startup/close" }, +// // () => { +// // const server = new WebTransportServer(4433, { +// // maxTimeout: 10, +// // keepAlive: 3, +// // notAfter: 10, +// // notBefore: 0, +// // domain: "localhost", +// // }); +// // server.close(); +// // }, +// // ); + +// Deno.test({ name: "Server Cleanup certs" }, () => { +// Deno.removeSync(certPath, { recursive: true }); +// }); diff --git a/mod/client.ts b/mod/client.ts index 78f8042..cbf1c64 100644 --- a/mod/client.ts +++ b/mod/client.ts @@ -84,7 +84,7 @@ export class WebTransport extends EventEmitter { private connection(client: Deno.PointerValue) { const CONN_BUFFER = new Uint8Array(65536); // - window.WTLIB.symbols.proc_client_init_streams( + window.WTLIB.symbols.proc_init_datagrams( client, CONN_BUFFER, CONN_BUFFER.byteLength, diff --git a/mod/crypto.ts b/mod/crypto.ts index 0822482..0ca41f3 100644 --- a/mod/crypto.ts +++ b/mod/crypto.ts @@ -71,12 +71,26 @@ export function GenerateCertKeyFile( domainStr: string, start: number, end: number, - path = join(Deno.cwd(), "./certs/"), + path?: string, + keyFileName?: string, + certFileName?: string, ) { + if (start > end) throw new Error("Invalid date range"); + path = path ?? join(Deno.cwd(), "./certs/"); + //check path + try { + Deno.statSync(path); + } catch { + console.info("[Webtransport] Creating directory: ", path); + Deno.mkdirSync(path, { + recursive: true, + }); + } const [cert, key] = GenerateCertKey(domainStr, start, end); try { - const certpath = join(path, `${domainStr}.crt`); - const keypath = join(path, `${domainStr}.key`); + const certpath = join(path, `${certFileName ?? domainStr + ".crt"}`); + const keypath = join(path, `${keyFileName ?? domainStr + ".key"}`); + Deno.writeFileSync(certpath, cert, { mode: 0o444, // createNew: true, diff --git a/mod/deps.ts b/mod/deps.ts index eed783d..b0cd8ed 100644 --- a/mod/deps.ts +++ b/mod/deps.ts @@ -1,3 +1,5 @@ +import "https://deno.land/std@0.201.0/dotenv/load.ts"; + export { dlopen, type FetchOptions, diff --git a/mod/interface.ts b/mod/interface.ts index 4567352..409c218 100644 --- a/mod/interface.ts +++ b/mod/interface.ts @@ -51,11 +51,6 @@ export const symbols = { result: "pointer", callback: true, }, - proc_server_init_streams: { - parameters: ["pointer", "buffer", "usize"], - result: "void", - nonblocking: true, - }, proc_server_close: { parameters: ["pointer"], result: "usize", @@ -81,11 +76,6 @@ export const symbols = { result: "pointer", callback: true, }, - proc_client_init_streams: { - parameters: ["pointer", "buffer", "usize"], - result: "void", - nonblocking: true, - }, proc_client_close: { parameters: ["pointer", "pointer"], result: "void", @@ -102,6 +92,11 @@ export const symbols = { result: "void", nonblocking: false, }, + proc_init_datagrams: { + parameters: ["pointer", "buffer", "usize"], + result: "void", + nonblocking: true, + }, // Crypto symbols proc_gencert: { parameters: [ diff --git a/mod/lib.ts b/mod/lib.ts index 25d2b55..2961e60 100644 --- a/mod/lib.ts +++ b/mod/lib.ts @@ -1,11 +1,19 @@ import { dlopen, FetchOptions } from "./deps.ts"; import LIB_URL from "../utils/download_lib.ts"; import { symbols } from "./interface.ts"; +import { CacheSetting } from "https://deno.land/x/plug@1.0.2/mod.ts"; + +const cache: CacheSetting = Deno.env.has("DEVELOPMENT") ? "reloadAll" : "only"; const options: FetchOptions = { name: "webtransport", - cache: "reloadAll", + cache: cache, url: LIB_URL!, + suffixes: { + linux: { + "aarch64": "_aarch64", + }, + }, }; export const LIB = async () => await dlopen(options, symbols); diff --git a/mod/server.ts b/mod/server.ts index 1a55a55..c70c463 100644 --- a/mod/server.ts +++ b/mod/server.ts @@ -81,7 +81,7 @@ export class WebTransportServer extends EventEmitter { */ private connection(client: Deno.PointerValue) { const CONN_BUFFER = new Uint8Array(65536); - window.WTLIB.symbols.proc_server_init_streams( + window.WTLIB.symbols.proc_init_datagrams( client, CONN_BUFFER, CONN_BUFFER.byteLength, diff --git a/src/client.rs b/src/client.rs index 11ad669..ed9f6e6 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,7 +1,7 @@ -use std::{path::Path, slice::from_raw_parts_mut, time::Duration}; +use std::{path::Path, time::Duration}; use wtransport::{endpoint, tls::Certificate, ClientConfig, Endpoint}; -use crate::{connection::Conn, executor, CLIENT_CONN_FN, RUNTIME, SEND_FN}; +use crate::{connection::Conn, CLIENT_CONN_FN, RUNTIME, SEND_FN}; pub struct WebTransportClient { pub client: Option>, @@ -118,82 +118,6 @@ pub unsafe extern "C" fn proc_client_connect( client.connect(url.to_string()); } -#[no_mangle] -pub unsafe extern "C" fn proc_client_init_streams( - clientptr: *mut Conn, - buffer: *mut u8, - buflen: usize, -) { - assert!(!clientptr.is_null()); - - let client = &mut *clientptr; - let sender = client.datagram_ch_sender.clone(); - - client.buffer = Some(from_raw_parts_mut(buffer, buflen)); - - executor::spawn(async move { - loop { - tokio::select! { - _ = client.conn.accept_bi() => { - // match stream { - // Ok(mut stream) => { - - // println!("Accepted BI stream"); - // let bytes_read = stream.1.read(&mut buffer).await.unwrap().unwrap(); - // let str_data = std::str::from_utf8(&buffer[..bytes_read]).unwrap(); - - // println!("Received (bi) '{str_data}' from client"); - - // stream.0.write_all(b"ACK").await.unwrap(); - // }, - // _ => { - // client.conn.closed().await; - // } - // }; - return client.conn.closed().await; - } - _ = client.conn.accept_uni() => { - //close the connection until we implement the uni stream - return client.conn.closed().await; - // match stream { - // Ok(mut stream) => { - // println!("Accepted UNI stream"); - // let bytes_read = match stream.read(&mut buffer).await.unwrap() { - // Some(bytes_read) => bytes_read, - // None => continue, - // }; - - // let str_data = std::str::from_utf8(&buffer[..bytes_read]).unwrap(); - - // println!("Received (uni) '{str_data}' from client"); - - // let mut stream = client.conn.open_uni().await.unwrap().await.unwrap(); - // stream.write_all(b"ACK").await.unwrap(); - // }, - // _ => { - // client.conn.closed().await; - // } - // } - - } - stream = client.conn.receive_datagram() => { - match stream { - Ok(dgram) => sender.send_async(dgram).await.unwrap(), - _ => { - client.conn.closed().await; - //TODO(hironichu): Send action to Deno to free the pointer and buffer - // SEND_FN.unwrap()(client, std::ptr::null_mut(), 0); - return ; - } - } - }, - - } - } - }) - .detach(); -} - #[no_mangle] pub unsafe extern "C" fn proc_client_close( client_ptr: *mut WebTransportClient, @@ -211,4 +135,8 @@ pub unsafe extern "C" fn proc_client_close( } #[no_mangle] -pub unsafe extern "C" fn free_all_client(_a: *mut WebTransportClient, _b: *mut Conn) {} +pub unsafe extern "C" fn free_all_client(_a: *mut WebTransportClient, _b: *mut Conn) { + let _con = &mut *_b; + drop(_con.datagram_ch_receiver.drain()); + drop(_con.datagram_ch_sender.downgrade()); +} diff --git a/src/connection.rs b/src/connection.rs index dc7b37a..3a4a709 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -1,6 +1,8 @@ use flume::{Receiver, Sender}; use wtransport::{datagram::Datagram, Connection}; +use wtransport_proto::varint::VarInt; +use crate::executor; pub struct Conn { pub conn: Connection, pub buffer: Option<&'static mut [u8]>, @@ -10,7 +12,7 @@ pub struct Conn { impl Conn { pub(crate) fn new(conn: Connection) -> Self { - let (sender, receiver) = flume::bounded(1); + let (sender, receiver) = flume::bounded(2); Self { conn, @@ -23,4 +25,43 @@ impl Conn { pub async fn closed(&mut self) { self.conn.closed().await } + + pub fn close(&mut self, code: u32, reason: Option<&[u8]>) { + let reason = match reason { + Some(reason) => reason, + None => b"closed", + }; + self.conn.close(VarInt::from_u32(code), reason); + } + + pub fn datagrams(&'static mut self) { + executor::spawn(async move { + loop { + tokio::select! { + stream = self.conn.receive_datagram() => { + match stream { + Ok(dgram) => match self.datagram_ch_sender.send_async(dgram).await { + Ok(_) => {} + Err(_) => { + //We should close the connection from Deno. + self.conn.closed().await; + // SEND_FN.unwrap()(client, std::ptr::null_mut(), 0); + return ; + } + }, + _ => { + //We should close the connection from Deno. + self.conn.closed().await; + //TODO(hironichu): Send action to Deno to free the pointer and buffer + // SEND_FN.unwrap()(client, std::ptr::null_mut(), 0); + return ; + } + } + }, + + } + } + }) + .detach(); + } } diff --git a/src/server.rs b/src/server.rs index 5d57e2a..e303c76 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,8 +1,8 @@ -use std::{path::Path, slice::from_raw_parts_mut, time::Duration}; +use std::{path::Path, time::Duration}; use tokio::runtime::Runtime; use wtransport::{endpoint, tls::Certificate, Endpoint, ServerConfig}; -use crate::{connection::Conn, executor, RUNTIME, SEND_FN, SERVER_CONN_FN}; +use crate::{connection::Conn, RUNTIME, SEND_FN, SERVER_CONN_FN}; pub struct WebTransportServer { pub server: Option>, @@ -137,82 +137,6 @@ pub unsafe extern "C" fn proc_server_listen( server.handle_sess_in(); } -#[no_mangle] -pub unsafe extern "C" fn proc_server_init_streams( - clientptr: *mut Conn, - buffer: *mut u8, - buflen: usize, -) { - assert!(!clientptr.is_null()); - - let client = &mut *clientptr; - let sender = client.datagram_ch_sender.clone(); - - client.buffer = Some(from_raw_parts_mut(buffer, buflen)); - - executor::spawn(async move { - loop { - tokio::select! { - _ = client.conn.accept_bi() => { - // match stream { - // Ok(mut stream) => { - - // println!("Accepted BI stream"); - // let bytes_read = stream.1.read(&mut buffer).await.unwrap().unwrap(); - // let str_data = std::str::from_utf8(&buffer[..bytes_read]).unwrap(); - - // println!("Received (bi) '{str_data}' from client"); - - // stream.0.write_all(b"ACK").await.unwrap(); - // }, - // _ => { - // client.conn.closed().await; - // } - // }; - return client.conn.closed().await; - } - _ = client.conn.accept_uni() => { - //close the connection until we implement the uni stream - return client.conn.closed().await; - // match stream { - // Ok(mut stream) => { - // println!("Accepted UNI stream"); - // let bytes_read = match stream.read(&mut buffer).await.unwrap() { - // Some(bytes_read) => bytes_read, - // None => continue, - // }; - - // let str_data = std::str::from_utf8(&buffer[..bytes_read]).unwrap(); - - // println!("Received (uni) '{str_data}' from client"); - - // let mut stream = client.conn.open_uni().await.unwrap().await.unwrap(); - // stream.write_all(b"ACK").await.unwrap(); - // }, - // _ => { - // client.conn.closed().await; - // } - // } - - } - stream = client.conn.receive_datagram() => { - match stream { - Ok(dgram) => sender.send_async(dgram).await.unwrap(), - _ => { - client.conn.closed().await; - //TODO(hironichu): Send action to Deno to free the pointer and buffer - // SEND_FN.unwrap()(client, std::ptr::null_mut(), 0); - return ; - } - } - }, - - } - } - }) - .detach(); -} - #[no_mangle] pub unsafe extern "C" fn proc_server_close(server_ptr: *mut WebTransportServer) -> usize { assert!(!server_ptr.is_null()); @@ -229,4 +153,7 @@ pub unsafe extern "C" fn proc_server_close(server_ptr: *mut WebTransportServer) pub unsafe extern "C" fn free_all_server(_a: *mut WebTransportServer, _c: *mut Runtime) {} #[no_mangle] -pub unsafe extern "C" fn free_server(_: *mut WebTransportServer) {} +pub unsafe extern "C" fn free_server(_v: *mut WebTransportServer) { + let _s = &mut *_v; + drop(_s.server.take()); +} diff --git a/src/shared.rs b/src/shared.rs index ccaf9e6..014646a 100644 --- a/src/shared.rs +++ b/src/shared.rs @@ -44,6 +44,14 @@ pub unsafe extern "C" fn proc_send_datagram(connptr: *mut Conn, buf: *const u8, } } } +#[no_mangle] +pub unsafe extern "C" fn proc_init_datagrams(conn_ptr: *mut Conn, buffer: *mut u8, buflen: usize) { + assert!(!conn_ptr.is_null()); + + let connection = &mut *conn_ptr; + connection.buffer = Some(from_raw_parts_mut(buffer, buflen)); + connection.datagrams(); +} #[no_mangle] pub unsafe extern "C" fn proc_open_bi(connptr: *mut Conn, _buf: *mut u8) { diff --git a/utils/clean.js b/utils/clean.js deleted file mode 100644 index c459be9..0000000 --- a/utils/clean.js +++ /dev/null @@ -1,15 +0,0 @@ -if (import.meta.main) { - try { - Deno.statSync("./dist"); - const rule = /^(.*)\.so$|^(.*)\.dll$|^(.*)\.dylib$/; - const files = Deno.readDirSync("./dist"); - for (const file of files) { - if (rule.test(file.name)) { - Deno.removeSync("./dist/" + file.name); - } - } - console.info(`Cleaned up ./dist`); - } catch { - console.error(`Count not find ./dist`); - } -} diff --git a/utils/download_lib.ts b/utils/download_lib.ts index 2bb9bb9..01a3430 100644 --- a/utils/download_lib.ts +++ b/utils/download_lib.ts @@ -30,37 +30,14 @@ if (!Deno.env.get("DEVELOPMENT")) { if (json.length === 0) { throw new Error("No release found"); } - - switch (Deno.build.os) { - case "windows": - LIB_URL = new URL( - // json[0].assets.filter((item: { name: string }) => - // item.name.endsWith(".dll") - // )[0].url, - json[0].assets[`${LIB_NAME}.dll`][0].url, - ); - break; - case "linux": - { - let filename = LIB_NAME; - if (Deno.build.arch === "aarch64") { - filename = `lib${LIB_NAME}_aarch64.so`; - } else { - filename = `lib${LIB_NAME}.so`; - } - LIB_URL = new URL( - json[0].assets[filename][0].url, - ); - } - break; - case "darwin": - LIB_URL = new URL( - json[0].assets[`${LIB_NAME}.dylib`][0].url, - ); - break; - } + LIB_URL = new URL( + json[0] + .assets[ + `${LIB_NAME}_${Deno.build.os}_${Deno.build.arch}` + ][0].url, + ); LIB_URL!.username = Deno.env.get("DENO_AUTH_TOKENS")!.split("@")[0]!; } - -LIB_URL = LIB_URL ?? new URL("../dist/", import.meta.url); +const build_target = Deno.env.get("DEVELOPMENT") ? "debug" : "release"; +LIB_URL = LIB_URL ?? new URL(`../target/${build_target}/`, import.meta.url); export default LIB_URL;