Berkeley sockets usually means an API for Internet sockets and Unix domain sockets. A socket is an abstract representation of the local endpoint of a network communication path.
Currently, WAMR supports some Socket API features:
This document introduces a way to support the Berkeley/POSIX Socket API in WebAssembly code.
The first step is to include a header file of the WAMR socket extension in the native source code.
#ifdef __wasi__
#include <wasi_socket_ext.h>
#endif
__wasi__ is a macro defined by WASI. The host compiler will not enable it.
It is recommended that the project should use CMake as its build system. Use wasi-sdk as a toolchain to compile C/C++ to WebAssembly
$ cmake -DWASI_SDK_PREFIX=${WASI_SDK_DIR}
-DCMAKE_TOOLCHAIN_FILE=${WASI_TOOLCHAIN_FILE}
-DCMAKE_SYSROOT=${WASI_SYS_ROOT}
..
In the CMakeLists.txt, include an extension of socket support and link with it.
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake)
add_executable(socket_example tcp_server.c)
target_link_libraries(socket_example socket_wasi_ext)
Now, the native code with socket APIs is ready for compilation.
If having the .wasm, the last step is to run it with iwasm.
The iwasm should be compiled with WAMR_BUILD_LIBC_WASI=1. By default, it is
enabled.
iwasm accepts address ranges via an option, --addr-pool, to implement
the capability control. All IP address the WebAssembly application may need to bind() or connect()
should be announced first. Every IP address should be in CIDR notation.
$ iwasm --addr-pool=1.2.3.4/15,2.3.4.6/16 socket_example.wasm
iwasm also accepts list of domain names and domain name patterns for the address resolution via an option, --allow-resolve, to implement the capability control. Every domain that will be resolved using sock_addr_resolve needs to be added to the allowlist first.
$ iwasm --allow-resolve=*.example.com --allow-resolve=domain.com
The example above shows how to allow for resolving all example.com's subdomains (e.g. x.example.com, a.b.c.example.com) and domain.com domain.
Refer to socket api sample for more details.
WAMR also supports the socket API within Intel SGX enclaves.
The iwasm should be compiled with WAMR_BUILD_LIBC_WASI=1 and WAMR_BUILD_LIB_PTHREAD=1, which are enabled by default.
Similarly to running iwasm outside of an enclave, the allowed address ranges are given via the option --addr-pool.
$ iwasm --addr-pool=1.2.3.4/15,2.3.4.6/16 socket_example.wasm
Refer to socket api sample for the compilation of the Wasm applications and iwasm for Intel SGX for the Wasm runtime.
The WASIp1 provides a subset of the socket API. Namely,
Functionalities like connect() and listen() are intentionally omitted there to maintain the capability-based security model, inherited from cloudabi. The common practice for applications is to make the host code pass already connected/listening sockets to wasm module.
WAMR extends the WASIp1 with the rest of socket API functionalities for convenience.
Many of runtimes (eg. Wasmer and WasmEdge) provide similar extensions. Unfortunately, they are all incompatible. Thus, portable applications should not rely on these extensions.