Skip to content

Commit

Permalink
fix: resolve conflicts from the prev PR
Browse files Browse the repository at this point in the history
  • Loading branch information
Erik Chi committed Nov 1, 2023
2 parents 400eb32 + 6611747 commit 177cbc0
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 35 deletions.
43 changes: 32 additions & 11 deletions crates/water/src/runtime/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ impl H2O<Host> {
}

store.data_mut().preview1_ctx = Some(WasiCtxBuilder::new().inherit_stdio().build());

if store.data().preview1_ctx.is_none() {
return Err(anyhow::anyhow!("Failed to retrieve preview1_ctx from Host"));
}

wasmtime_wasi::add_to_linker(&mut linker, |h: &mut Host| h.preview1_ctx.as_mut().unwrap())?;

// initializing stuff for multithreading
Expand All @@ -81,34 +86,41 @@ impl H2O<Host> {
)?));

wasmtime_wasi_threads::add_to_linker(&mut linker, &store, &module, |h: &mut Host| {
h.wasi_threads.as_ref().unwrap()
h.wasi_threads
.as_ref()
.context("Failed to get ref of wasi_threads from Host")?
})?;
}

// export functions -- version dependent -- has to be done before instantiate
match &version {
Some(Version::V0(v0_conf)) => {
let v0_conf = Arc::new(Mutex::new(v0_conf.clone()));
v0::funcs::export_tcp_connect(&mut linker, Arc::clone(&v0_conf));
v0::funcs::export_accept(&mut linker, Arc::clone(&v0_conf));
v0::funcs::export_defer(&mut linker, Arc::clone(&v0_conf));
v0::funcs::export_tcp_connect(&mut linker, Arc::clone(&v0_conf))?;
v0::funcs::export_accept(&mut linker, Arc::clone(&v0_conf))?;
v0::funcs::export_defer(&mut linker, Arc::clone(&v0_conf))?;
}
Some(Version::V1) => {
v1::funcs::export_tcp_connect(&mut linker);
v1::funcs::export_tcplistener_create(&mut linker);
v1::funcs::export_tcp_connect(&mut linker)?;
v1::funcs::export_tcplistener_create(&mut linker)?;
}
_ => {
unimplemented!("This version is not supported yet")
} // add export funcs for other versions here
}

// export functions -- version independent
version_common::funcs::export_config(&mut linker, conf.config_wasm.clone());
version_common::funcs::export_config(&mut linker, conf.config_wasm.clone())?;

let instance = linker.instantiate(&mut store, &module)?;

Ok(H2O {
version: version.unwrap(),
version: match version {
Some(v) => v,
None => {
return Err(anyhow::anyhow!("Version is None"));
}
},

engine,
linker,
Expand Down Expand Up @@ -178,8 +190,13 @@ impl H2O<Host> {

// Obtain the directory path and file name from config_wasm
let full_path = Path::new(&config.config_wasm);
let parent_dir = full_path.parent().unwrap(); // Assumes config_wasm has a parent directory
let file_name = full_path.file_name().unwrap().to_str().unwrap(); // Assumes file_name is valid UTF-8
let parent_dir = full_path
.parent()
.ok_or_else(|| anyhow::anyhow!("config_wasm does not have a parent directory"))?; // Assumes config_wasm has a parent directory
let file_name = full_path
.file_name()
.and_then(|os_str| os_str.to_str())
.ok_or_else(|| anyhow::anyhow!("file_name is not valid UTF-8"))?; // Assumes file_name is valid UTF-8

// Open the parent directory
let dir = Dir::open_ambient_dir(parent_dir, ambient_authority())?;
Expand All @@ -188,7 +205,11 @@ impl H2O<Host> {

let wasi_file = wasmtime_wasi::sync::file::File::from_cap_std(wasi_file);

let ctx = store.data_mut().preview1_ctx.as_mut().unwrap();
let ctx = store
.data_mut()
.preview1_ctx
.as_mut()
.ok_or(anyhow::anyhow!("preview1_ctx in Store is None"))?;
let config_fd = ctx.push_file(Box::new(wasi_file), FileAccessMode::all())? as i32;

let params = vec![Val::I32(config_fd); config_fn.ty(&*store).params().len()];
Expand Down
9 changes: 7 additions & 2 deletions crates/water/src/runtime/listener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ impl WATERListener<Host> {
.core
.instance
.get_func(&mut *store, &conf.entry_fn)
.unwrap();
.context(format!("Failed to get function {}", &conf.entry_fn))?;

match fnc.call(&mut *store, &[], &mut []) {
Ok(_) => {}
Err(e) => {
Expand Down Expand Up @@ -179,7 +180,11 @@ impl WATERListener<Host> {
.store
.lock()
.map_err(|e| anyhow::Error::msg(format!("Failed to lock store: {}", e)))?;
let ctx = store.data_mut().preview1_ctx.as_mut().unwrap();
let ctx = store
.data_mut()
.preview1_ctx
.as_mut()
.ok_or(anyhow::anyhow!("preview1_ctx in Store is None"))?;
let water_reader_fd =
ctx.push_file(Box::new(wasi_water_reader), FileAccessMode::all())?;
let water_writer_fd =
Expand Down
46 changes: 36 additions & 10 deletions crates/water/src/runtime/v0/funcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use crate::runtime::v0::config::V0Config;
use crate::runtime::*;
use std::sync::{Arc, Mutex};

pub fn export_tcp_connect(linker: &mut Linker<Host>, config: Arc<Mutex<V0Config>>) {
pub fn export_tcp_connect(
linker: &mut Linker<Host>,
config: Arc<Mutex<V0Config>>,
) -> Result<(), anyhow::Error> {
linker
.func_wrap(
"env",
Expand All @@ -22,14 +25,25 @@ pub fn export_tcp_connect(linker: &mut Linker<Host>, config: Arc<Mutex<V0Config>
let socket_file: Box<dyn WasiFile> = wasmtime_wasi::net::Socket::from(tcp).into();

// Get the WasiCtx of the caller(WASM), then insert_file into it
let ctx: &mut WasiCtx = caller.data_mut().preview1_ctx.as_mut().unwrap();
ctx.push_file(socket_file, FileAccessMode::all()).unwrap() as i32
let ctx: &mut WasiCtx = caller
.data_mut()
.preview1_ctx
.as_mut()
.context("preview1_ctx in Store is None")
.unwrap();
ctx.push_file(socket_file, FileAccessMode::all())
.context("Failed to push file into WASM")
.unwrap() as i32
},
)
.unwrap();
.context("Failed to export Dial function to WASM")?;
Ok(())
}

pub fn export_accept(linker: &mut Linker<Host>, config: Arc<Mutex<V0Config>>) {
pub fn export_accept(
linker: &mut Linker<Host>,
config: Arc<Mutex<V0Config>>,
) -> Result<(), anyhow::Error> {
linker
.func_wrap(
"env",
Expand All @@ -49,15 +63,26 @@ pub fn export_accept(linker: &mut Linker<Host>, config: Arc<Mutex<V0Config>>) {
let socket_file: Box<dyn WasiFile> = wasmtime_wasi::net::Socket::from(tcp).into();

// Get the WasiCtx of the caller(WASM), then insert_file into it
let ctx: &mut WasiCtx = caller.data_mut().preview1_ctx.as_mut().unwrap();
ctx.push_file(socket_file, FileAccessMode::all()).unwrap() as i32
let ctx: &mut WasiCtx = caller
.data_mut()
.preview1_ctx
.as_mut()
.context("preview1_ctx in Store is None")
.unwrap();
ctx.push_file(socket_file, FileAccessMode::all())
.context("Failed to push file into WASM")
.unwrap() as i32
},
)
.unwrap();
.context("Failed to export TcpListener create function to WASM")?;
Ok(())
}

// TODO: implement this
pub fn export_defer(linker: &mut Linker<Host>, config: Arc<Mutex<V0Config>>) {
pub fn export_defer(
linker: &mut Linker<Host>,
config: Arc<Mutex<V0Config>>,
) -> Result<(), anyhow::Error> {
linker
.func_wrap("env", "host_defer", move |_caller: Caller<'_, Host>| {
info!("[WASM] invoking Host exported host_defer func...");
Expand All @@ -66,5 +91,6 @@ pub fn export_defer(linker: &mut Linker<Host>, config: Arc<Mutex<V0Config>>) {

config.defer();
})
.unwrap();
.context("Failed to export defer function to WASM")?;
Ok(())
}
40 changes: 31 additions & 9 deletions crates/water/src/runtime/v1/funcs.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use anyhow::Ok;

use crate::config::wasm_shared_config::StreamConfig;
use crate::runtime::*;
use std::convert::TryInto;
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};

// TODO: rename this to dial_v1, since it has the ability to let WASM choose ip:port
pub fn export_tcp_connect(linker: &mut Linker<Host>) {
pub fn export_tcp_connect(linker: &mut Linker<Host>) -> Result<(), anyhow::Error> {
linker
.func_wrap(
"env",
Expand Down Expand Up @@ -48,22 +50,33 @@ pub fn export_tcp_connect(linker: &mut Linker<Host>) {
addr => std::net::TcpStream::connect(addr),
}
.map(TcpStream::from_std)
.context("failed to connect to endpoint")
.context(format!(
"Failed to connect to {}:{} in Host exported dial",
host, port
))
.unwrap();

// Connecting Tcp
let socket_file: Box<dyn WasiFile> = wasmtime_wasi::net::Socket::from(tcp).into();

// Get the WasiCtx of the caller(WASM), then insert_file into it
let ctx: &mut WasiCtx = caller.data_mut().preview1_ctx.as_mut().unwrap();
ctx.push_file(socket_file, FileAccessMode::all()).unwrap() as i32
let ctx: &mut WasiCtx = caller
.data_mut()
.preview1_ctx
.as_mut()
.context("preview1_ctx in Store is None")
.unwrap();
ctx.push_file(socket_file, FileAccessMode::all())
.context("Failed to push file into WASM")
.unwrap() as i32
},
)
.unwrap();
.context("Failed to export Dial function to WASM")?;
Ok(())
}

// TODO: rename this to dial_v1, since it has the ability to let WASM listen on a TcpListener
pub fn export_tcplistener_create(linker: &mut Linker<Host>) {
pub fn export_tcplistener_create(linker: &mut Linker<Host>) -> Result<(), anyhow::Error> {
linker
.func_wrap(
"env",
Expand Down Expand Up @@ -104,14 +117,23 @@ pub fn export_tcplistener_create(linker: &mut Linker<Host>) {
// Creating Tcp Listener
let tcp = std::net::TcpListener::bind((addr.as_str(), port)).unwrap();
let tcp = TcpListener::from_std(tcp);
// tcp.set_nonblocking(true);
let socket_file: Box<dyn WasiFile> = wasmtime_wasi::net::Socket::from(tcp).into();

// Get the WasiCtx of the caller(WASM), then insert_file into it
let ctx: &mut WasiCtx = caller.data_mut().preview1_ctx.as_mut().unwrap();
ctx.push_file(socket_file, FileAccessMode::all()).unwrap() as i32
let ctx: &mut WasiCtx = caller
.data_mut()
.preview1_ctx
.as_mut()
.context("preview1_ctx in Store is None")
.unwrap();
ctx.push_file(socket_file, FileAccessMode::all())
.context("Failed to push file into WASM")
.unwrap() as i32
},
)
.unwrap();
.context("Failed to export TcpListener create function to WASM")?;
Ok(())
}

// Generically link dial functions
Expand Down
5 changes: 3 additions & 2 deletions crates/water/src/runtime/version_common/funcs.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::runtime::*;

// exportint a function for WASM to get CONFIG file
pub fn export_config(linker: &mut Linker<Host>, config_file: String) {
pub fn export_config(linker: &mut Linker<Host>, config_file: String) -> Result<(), anyhow::Error> {
linker
.func_wrap(
"env",
Expand All @@ -22,5 +22,6 @@ pub fn export_config(linker: &mut Linker<Host>, config_file: String) {
.expect("Error with pushing file") as i32
},
)
.unwrap();
.context("Failed to export config function to WASM")?;
Ok(())
}
2 changes: 1 addition & 1 deletion tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ shadowsocks-service = {version = "1.17.0", features = ["server"]}
shadowsocks-rust = "1.17.0"
tokio = { version = "1.24.2", features = ["full", "macros"] }
futures = "0.3.28"
tempfile = "3.8.0"
tempfile = "3.8.0"

0 comments on commit 177cbc0

Please sign in to comment.