Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement part of Berkeley Socket API for libc-wasi #1036

Merged
merged 12 commits into from
Mar 10, 2022
Prev Previous commit
Refine socket-api sample (#1040)
Refine the source code of tcp_server.c and tcp_client.c
Add building of iwasm with lib-pthread and libc-wasi enabled
Add sample document
Update iwasm --addr-pool argument description
  • Loading branch information
wenyongh authored Mar 10, 2022
commit d5f4f18dbe5cf9a6264bd817885f172cba2858bd
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ The WAMR [samples](./samples) integrate the iwasm VM core, application manager a
- **[multi-module](./samples/multi-module)**: Demonstrating the [multiple modules as dependencies](./doc/multi_module.md) feature which implements the [load-time dynamic linking](https://webassembly.org/docs/dynamic-linking/).
- **[ref-types](./samples/ref-types)**: Demonstrating how to call wasm functions with argument of externref type introduced by [reference types proposal](https://github.com/WebAssembly/reference-types).
- **[wasm-c-api](./samples/wasm-c-api/README.md)**: Demonstrating how to run some samples from [wasm-c-api proposal](https://github.com/WebAssembly/wasm-c-api) and showing the supported API's.
- **[socket-api](./samples/socket-api/README.md)**: Demonstrating how to run wasm tcp server and tcp client applications, and how they communicate with each other.
- **[workload](./samples/workload/README.md)**: Demonstrating how to build and run some complex workloads, e.g. tensorflow-lite, XNNPACK, wasm-av1, meshoptimizer and bwa.


Expand Down
2 changes: 2 additions & 0 deletions doc/socket_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,5 @@ the capability control. All IP address the WebAssebmly application may need to `
```bash
$ iwasm --addr-pool=1.2.3.4/15,2.3.4.6/16 socket_example.wasm
```

Refer to [socket api sample](../samples/socket-api) for more details.
6 changes: 4 additions & 2 deletions product-mini/platforms/posix/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ print_help()
printf(" --dir=<dir> Grant wasi access to the given host directories\n");
printf(" to the program, for example:\n");
printf(" --dir=<dir1> --dir=<dir2>\n");
printf(" --addr-pool= Indicate network addresses in CIRD noation, \n");
printf(" separate with ','\n");
printf(" --addr-pool= Grant wasi access to the given network addresses in\n");
printf(" CIRD notation to the program, seperated with ',',\n");
printf(" for example:\n");
printf(" --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
printf(" --module-path= Indicate a module search path. default is current\n"
Expand Down
83 changes: 76 additions & 7 deletions samples/socket-api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
cmake_minimum_required(VERSION 2.8...3.18)
project(socket_api_sample)

message(CHECK_START "Detecting WASI-SDK")
#######################################
## Detect toolchain
#######################################
message(CHECK_START "Detecting WASI-SDK at /opt/wasi-sdk")
if(NOT (DEFINED WASI_SDK_DIR OR DEFINED CACHE{WASI_SDK_DIR}))
find_path(WASI_SDK_PARENT
wasi-sdk
Expand All @@ -23,7 +26,7 @@ else()
endif()

if(NOT EXISTS ${WASI_SDK_DIR})
message(FATAL_ERROR "Please set the absolute path of wasi-sdk with \'cmake -DWASI_SDK_HOME=XXX\'")
message(FATAL_ERROR "Please install WASI-SDK under /opt/wasi-sdk")
endif()

message(CHECK_START "Detecting WASI_TOOLCHAIN_FILE at ${WASI_SDK_DIR}")
Expand Down Expand Up @@ -65,14 +68,19 @@ message(STATUS "WASI_SDK_DIR is ${WASI_SDK_DIR}")
message(STATUS "WASI_TOOLCHAIN_FILE is ${WASI_TOOLCHAIN_FILE}")
message(STATUS "WASI_SYS_ROOT is ${WASI_SYS_ROOT}")

#######################################
###############################################################
## Build socket applications of wasm version and native version
###############################################################
include(ExternalProject)

ExternalProject_Add(wasm-app
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/wasm-src
UPDATE_COMMAND ""
PATCH_COMMAND ""
CONFIGURE_COMMAND ${CMAKE_COMMAND}
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/../../wamr-sdk/app/libc-builtin-sysroot/include/pthread.h
${CMAKE_CURRENT_SOURCE_DIR}/wasm-src/inc
&& ${CMAKE_COMMAND}
-DWASI_SDK_PREFIX=${WASI_SDK_DIR}
-DCMAKE_TOOLCHAIN_FILE=${WASI_TOOLCHAIN_FILE}
-DCMAKE_SYSROOT=${WASI_SYS_ROOT}
Expand All @@ -83,11 +91,72 @@ ExternalProject_Add(wasm-app
tcp_server.wasm ${CMAKE_CURRENT_SOURCE_DIR}/build
tcp_client.wasm.dump ${CMAKE_CURRENT_SOURCE_DIR}/build
tcp_server.wasm.dump ${CMAKE_CURRENT_SOURCE_DIR}/build
&& ${CMAKE_COMMAND} -E create_symlink
${CMAKE_CURRENT_SOURCE_DIR}/../../product-mini/platforms/linux/build/iwasm
${CMAKE_CURRENT_SOURCE_DIR}/build/iwasm
)

add_executable(tcp_server ${CMAKE_CURRENT_SOURCE_DIR}/wasm-src/tcp_server.c)
target_link_libraries(tcp_server pthread)
add_executable(tcp_client ${CMAKE_CURRENT_SOURCE_DIR}/wasm-src/tcp_client.c)

############################################
## Build iwasm with wasi and pthread support
############################################
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
if (APPLE)
add_definitions(-DBH_PLATFORM_DARWIN)
endif ()

# Reset linker flags
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")

# Set WAMR features

# Set WAMR_BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
if (NOT DEFINED WAMR_BUILD_TARGET)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)")
set (WAMR_BUILD_TARGET "AARCH64")
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
set (WAMR_BUILD_TARGET "RISCV64")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform
set (WAMR_BUILD_TARGET "X86_64")
else ()
# Build as X86_32 by default in 32-bit platform
set (WAMR_BUILD_TARGET "X86_32")
endif ()
endif ()

if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Release)
endif ()

set(WAMR_BUILD_INTERP 1)
set(WAMR_BUILD_FAST_INTERP 1)
set(WAMR_BUILD_AOT 1)
set(WAMR_BUILD_JIT 0)
set(WAMR_BUILD_LIBC_BUILTIN 1)
set(WAMR_BUILD_LIBC_WASI 1)
set(WAMR_BUILD_LIB_PTHREAD 1)

# compiling and linking flags
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie -fPIE")
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
endif ()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")

# build vmlib static lib
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})

# build iwasm
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
set (RUNTIME_SOURCE_ALL
${CMAKE_CURRENT_LIST_DIR}/../../product-mini/platforms/linux/main.c
${UNCOMMON_SHARED_SOURCE}
)
add_executable (iwasm ${RUNTIME_SOURCE_ALL})
target_link_libraries(iwasm vmlib -lpthread -lm)
57 changes: 57 additions & 0 deletions samples/socket-api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"socket-api" sample introduction
================================

This sample demonstrates how to use WAMR socket-api to develop wasm network applications.
Two wasm applications are provided: tcp-server and tcp-client, and this sample demonstrates
how they communicate with each other.

## Preparation

Please install WASI SDK, download the [wasi-sdk release](https://github.com/CraneStation/wasi-sdk/releases) and extract the archive to default path `/opt/wasi-sdk`.
And install wabt, download the [wabt release](https://github.com/WebAssembly/wabt/releases) and extract the archive to default path `/opt/wabt`

## Build the sample

```bash
mkdir build
cd build
cmake ..
make
```

The file `tcp_server.wasm`, `tcp_client.wasm` and `iwasm` will be created.
And also file `tcp_server` and `tcp_client` of native version are created.

Note that iwasm is built with libc-wasi and lib-pthread enabled.

## Run workload

Start the tcp server, which opens port 1234 and waits for clients to connect.
```bash
cd build
./iwasm --addr-pool=0.0.0.0/15 tcp_server.wasm
```

Start the tcp client, which connects the server and receives message.
```bash
cd build
./iwasm --addr-pool=127.0.0.1/15 tcp_client.wasm
```

The output of client is like:
```bash
[Client] Create socket
[Client] Connect socket
[Client] Client receive
[Client] 115 bytes received:
Buffer recieved:
Say Hi from the Server
Say Hi from the Server
Say Hi from the Server
Say Hi from the Server
Say Hi from the Server

[Client] BYE
```

Refer to [socket api document](../../doc/socket_api.md) for more details.
1 change: 1 addition & 0 deletions samples/socket-api/wasm-src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ function(COMPILE_WITH_CLANG SOURCE_FILE)
LINKER:--export=__data_end
LINKER:--shared-memory,--max-memory=196608
LINKER:--no-check-features
LINKER:--allow-undefined
)

if(EXISTS ${WASM_OBJDUMP})
Expand Down
Empty file.
124 changes: 0 additions & 124 deletions samples/socket-api/wasm-src/inc/pthread.h

This file was deleted.

23 changes: 16 additions & 7 deletions samples/socket-api/wasm-src/tcp_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
int
main(int argc, char *argv[])
{
int socket_fd;
int socket_fd, ret, total_size = 0;
char buffer[1024] = { 0 };
struct sockaddr_in server_address = { 0 };

printf("[Client] Create socket\n");
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1) {
perror("Create socket failed");
Expand All @@ -32,6 +33,7 @@ main(int argc, char *argv[])
server_address.sin_port = htons(1234);
server_address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

printf("[Client] Connect socket\n");
if (connect(socket_fd, (struct sockaddr *)&server_address,
sizeof(server_address))
== -1) {
Expand All @@ -40,14 +42,21 @@ main(int argc, char *argv[])
return EXIT_FAILURE;
}

if (recv(socket_fd, buffer, 1024, 0) == -1) {
perror("Recv failed");
close(socket_fd);
return EXIT_FAILURE;
printf("[Client] Client receive\n");
while (1) {
ret = recv(socket_fd, buffer + total_size, sizeof(buffer) - total_size,
0);
if (ret <= 0)
break;
total_size += ret;
}

printf("[Client] %d bytes received:\n", total_size);
if (total_size > 0) {
printf("Buffer recieved:\n%s\n", buffer);
}
printf("[Client] Received \"%s\"\n", buffer);

close(socket_fd);
printf("[Client] BYE \n");
return EXIT_SUCCESS;
}
}
Loading