celinesantosh98 opened issue #10125:
Hi,
I am trying to intercept the wasi call start-connect in wasi:sockets/tcp. I am planning to put all wasi calls except wasi:sockets/tcp into the linker and create a custom implementation say mwasi:sockets/tcp and implement my custom start-connect , for now I am writing a print statement.
So I have created a host embedding which I implemented. Then I have a random go_app which simply makes tcp connection, I have used WASI API calls start-connect for making tcp call because afaik ,go hasn't implemented the sockets yet. Then I have wit file .host embedding:
use wasmtime::{Engine, Result, Store, Config}; use wasmtime::component::{ Linker, Component}; use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiView, ResourceTable}; use wasmtime_wasi::WasiImpl; use std::sync::{Arc, Mutex}; use anyhow::{Context}; use wasmtime::component::bindgen; use wasmtime_wasi::bindings::sockets::network::{Network, ErrorCode, IpSocketAddress, IpAddressFamily}; use std::net::SocketAddr; use wasmtime_wasi::SocketResult; use wasmtime_wasi::bindings::sockets::tcp_create_socket::Host; //use crate::wasi::sockets::{tcp_create_socket, udp_create_socket};use wasmtime::component::Resource; use wasmtime_wasi::SocketError; // Bindgen the provided WIT bindgen!({ path: "wit", world: "wrapper", with: { "wasi": wasmtime_wasi::bindings, }, require_store_data_send: true, }); struct MyState { ctx: WasiCtx, table: ResourceTable, } impl WasiView for MyState { fn ctx(&mut self) -> &mut WasiCtx { &mut self.ctx } fn table(&mut self) -> &mut ResourceTable { &mut self.table } } fn type_annotate<T: WasiView, F>(val: F) -> F where F: Fn(&mut T) -> WasiImpl<&mut T>, { val } impl mwasi::sockets::tcp::Host for MyState { fn start_connect(&mut self, network:Resource<Network>, remote_address: IpSocketAddress) -> Result<(), ErrorCode> { println!("Intercepted TCP call: Printing from the monitor"); println!("start-connect operation successful!"); Ok(()) } } pub fn add_to_linker_without_tcp<T: WasiView>( linker: &mut wasmtime::component::Linker<T>, ) -> anyhow::Result<()> { let l = linker; let closure = type_annotate::<T, _>(|t| WasiImpl(t)); wasmtime_wasi::bindings::clocks::wall_clock::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::clocks::monotonic_clock::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::sync::filesystem::types::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::filesystem::preopens::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::io::error::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::sync::io::poll::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::sync::io::streams::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::random::random::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::random::insecure::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::random::insecure_seed::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::cli::exit::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::cli::environment::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::cli::stdin::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::cli::stdout::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::cli::stderr::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::cli::terminal_input::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::cli::terminal_output::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::cli::terminal_stdin::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::cli::terminal_stdout::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::cli::terminal_stderr::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::sockets::tcp_create_socket::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::sync::sockets::udp::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::sockets::udp_create_socket::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::sockets::instance_network::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::sockets::network::add_to_linker_get_host(l, closure)?; wasmtime_wasi::bindings::sockets::ip_name_lookup::add_to_linker_get_host(l, closure)?; Wrapper::add_to_linker(l, |state: &mut T| state)?; Ok(()) } fn main() -> Result<()> { //let engine = Engine::default(); let mut config = Config::new(); config.wasm_component_model(true); let engine = Engine::new(&config)?; let mut linker = Linker::<MyState>::new(&engine); let wasi_ctx = WasiCtxBuilder::new() .inherit_stdio() .inherit_env() .inherit_network() .allow_ip_name_lookup(true) .allow_tcp(true) .allow_udp(true) .build(); let state = MyState { ctx: wasi_ctx, table: ResourceTable::new(), }; let mut store = Store::new(&engine, state); let app_component = Component::from_file(&engine, "go_app.wasm") .context("Failed to load Rust app")?; // Instantiate both components linker.instantiate(&mut store, &app_component)?; let bindings = Wrapper::instantiate(&mut store, &app_component, &linker)?; let command = wasmtime_wasi::bindings::sync::Command::instantiate( &mut store, &app_component, &linker, )?; let result = command .wasi_cli_run() .call_run(&mut store) .context("failed to invoke `run` function"); //.map_err(|e| handle_core_dump(&mut store, e)); Ok(()) }
Wit file
package mwasi:sockets@0.2.0; interface tcp{ use wasi:sockets/network@0.2.0.{network, error-code, ip-socket-address, ip-address-family}; start-connect: func(network: borrow<network>, remote-address: ip-socket-address) -> result<_, error-code>; } world wrapper{ import wasi:io/error@0.2.0; import wasi:sockets/tcp@0.2.0; import wasi:sockets/network@0.2.0; include wasi:cli/imports@0.2.0; import tcp; }
go_app
package main //go:generate go run github.com/bytecodealliance/wasm-tools-go/cmd/wit-bindgen-go generate --world go_app --out gen ../wit import ( "fmt" "log" //"go_app/src/gen/wasi/sockets/tcp" //mwasi_tcp "go_app/src/gen/mwasi/sockets/tcp" instancenetwork "go_app/src/gen/wasi/sockets/instance-network" "go_app/src/gen/wasi/sockets/network" tcpcreatesocket "go_app/src/gen/wasi/sockets/tcp-create-socket" ) func main() { googleAddress := network.IPSocketAddressIPv4(network.IPv4SocketAddress{ Address: network.IPv4Address{142, 250, 181, 206}, Port: 80, }) // Connect to Google.com fmt.Println("Connecting to Google.com...") err = connectToServer(googleAddress) if err != nil { log.Fatalf("Failed to connect to Google.com: %v", err) } else { fmt.Println("Connected to Google.com.") } } func connectToServer(address network.IPSocketAddress) error { // Get a handle to the default network netInstance := instancenetwork.InstanceNetwork() // Create a new TCP socket socketResult := tcpcreatesocket.CreateTCPSocket(network.IPAddressFamilyIPv4) if !socketResult.IsOK() { return fmt.Errorf("failed to create TCP socket: %v", socketResult.Err()) } socket := socketResult.OK() // Start the connection connectResult := socket.StartConnect(netInstance, address) if !connectResult.IsOK() { return fmt.Errorf("start-connect failed: %v", connectResult.Err()) }
I have the necessary's folder and go bindings in gen folder.
So the expected outcome is that it should print "Intercepted TCP call: Printing from the monitor" when app makes the network call. so then I can confirm the wasi call start-connect is intercepted.But I am getting error
error[E0277]: the trait bound `T: wasmtime_wasi::bindings::random::insecure_seed::Host` is not satisfied --> src/main.rs:102:5 | 102 | Wrapper::add_to_linker(l, |state: &mut T| state)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `wasmtime_wasi::bindings::random::insecure_seed::Host` is not implemented for `T` | note: required by a bound in `_::<impl Wrapper>::add_to_linker` --> src/main.rs:21:1 | 21 | / bindgen!({ 22 | | path: "wit", 23 | | world: "wrapper", 24 | | with: { ... | 27 | | require_store_data_send: true, 28 | | }); | |__^ required by this bound in `_::<impl Wrapper>::add_to_linker` = note: this error originates in the macro `bindgen` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound | 70 | pub fn add_to_linker_without_tcp<T: WasiView + wasmtime_wasi::bindings::random::insecure_seed::Host>( | ++++++++++++++++++++++++++++++++++++++++++++++++++++++
I am getting 28 similar errors for each interface.
I have already given wasmtime_Wasi in the with clause of bindgen macro, then why is it giving me this error
celinesantosh98 edited issue #10125:
The issue is not relevant now, so had to delete it.
fitzgen closed issue #10125:
The issue is not relevant now, so had to delete it.
Last updated: Feb 28 2025 at 02:27 UTC