Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Related: #90 #64
This commit adds an initial support for networking. Please also refer to
./examples/networking/
dir for the documents.As of now, we rely on the network stack running outside of the wasm image. We use
gvisor-tap-vsock
as the network stack written in Go. This commit ports TinyEMU's virtio-net device to Bochs and they are patched to forward all packets from the container togvisor-tap-vsock
and vice-versa, when-net=qemu
flag is provided. Andgvisor-tap-vsock
forwards these packets to/from the destination.The protocol between the emulator and gvisor-tap-vsock is the following (according to containers/gvisor-tap-vsock#22 )
The network stack can run with the different types of setup:
Containers on browser
WebSocket-based networking
gvisor-tap-vsock
runs on the host (outside of the browser) and forwards packets to/from the on-browser container. We provide a wrapper commandc2w-net
that enablesgvisor-tap-vsock
to receive packets from the container over an WebSocket port (and vice-versa). The emulators running on browser connects to that WebSocket and forwards all packets to/fromc2w-net
over the WebSocket port and letc2w-net
forward them on the host.On emscripten, emscripten's WebSocket networking support can be used for connecting to the WebSocket port. On WASI-on-browser configuration, our example JS wrapper (
/examples/wasi-browser/
) uses the browser's WebSocket API and sends/receives packets to/from a socket fd of WASI. The emulator usessock_*
API for accessing to the fd.Example
This runs the network stack on the host:
The following runs alpine:3.18 on browser (with WASI-on-browser configuration).
Container on browser is available on
localhost:8080/?net=delegate=ws://localhost:8888
.The parameter
net=delegate
tells the container's JS wrapper to forward packets over the specified WebSocket port listened byc2w-net
.Fetch-API-based networking
gvisor-tap-vsock
is compiled to WASM(WASI) and runs on browser. HTTP(S) proxy runs on top of the network stack and the container can perform HTTP(S) networking via that proxy. The proxy is implemented relying on the browser's Fetch API for HTTP(S) networking on browser.c2w-net-proxy
is the wrapper command forgvisor-tap-vsock
that adds the proxy implementation and is runnable on browser.For HTTPS, the proxy terminates the TLS connection from the container with its self-signed certificate and re-encrypt the connection to the destination using the Fetch API. So the proxy's certificate needs to be trusted by the processes in the container (
SSL_CERT_FILE
envvar is pre-configured). The proxy generates its self-signed certificate and our example JS wrapper (/examples/wasi-browser/
) mounts it to/.wasmenv/proxy.crt
. in the containerpros: No need to run network stack daemon on the host. Networking is done based on browser's Fetch API and follows its security configuration including CORS restriction.
cons: Container can send only HTTP/HTTPS packets to outside of the browser. And the set of accessible HTTP/HTTPS sites is limited by the browser's security rule (e.g. limited CORS).
Current limitations:
apt-get
. We expect more sites will allow CORS access.Example
The following builds
c2w-net-proxy
and puts it to the document root (/tmp/out-js2/htdocs/
).Go >= 1.21 is required.
The following runs debian (with curl) on browser.
Container on browser is available on
localhost:8080/?net=browser
.The set of accesible HTTP/HTTPS sites is limited by the browser's security rule (e.g. limited CORS).
Containers on WASI runtime
wasmtime and wazero are supported as of now. Other runtimes (including wamr #64) will be future works.
gvisor-tap-vsock
runs on the host (outside of runtime) and forwards packets to/from the container.c2w-net
is a wrapper command forgvisor-tap-vsock
that connectsgvisor-tap-vsock
and the container. The emulator sends/receives packets to/from a socket provided by WASI runtime, usingsock_*
API. WASI runtime binds the socket on a TCP port (e.g. using wasmtime's--tcplisten
flag and wazero'sWithTCPListener
option).c2w-net
running on the host connects to that port and forwards the container's packets to/from the network stack.The following runs alpine:3.18 on wasmtime with enabling networking. (Requirement: wasmtime needs to be installed)
./tests/wazero/
. And the docs available at./examples/networking/wasi/README.md
.