diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h index 7c0405c5..feadf2f9 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/include/wasmtime_ssp.h @@ -1062,6 +1062,70 @@ wasi_ssp_sock_connect( __wasi_fd_t fd, __wasi_addr_t *addr ) __attribute__((__warn_unused_result__)); +__wasi_errno_t +wasi_ssp_sock_get_recv_buf_size( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, __wasi_size_t *size +) __attribute__((__warn_unused_result__)); + +__wasi_errno_t +wasi_ssp_sock_get_reuse_addr( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, uint8_t *reuse +) __attribute__((__warn_unused_result__)); + +__wasi_errno_t +wasi_ssp_sock_get_reuse_port( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, uint8_t *reuse +) __attribute__((__warn_unused_result__)); + +__wasi_errno_t +wasi_ssp_sock_get_send_buf_size( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, __wasi_size_t *size +) __attribute__((__warn_unused_result__)); + +__wasi_errno_t +wasi_ssp_sock_set_recv_buf_size( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, __wasi_size_t size +) __attribute__((__warn_unused_result__)); + +__wasi_errno_t +wasi_ssp_sock_set_reuse_addr( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, uint8_t reuse +) __attribute__((__warn_unused_result__)); + +__wasi_errno_t +wasi_ssp_sock_set_reuse_port( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, uint8_t reuse +) __attribute__((__warn_unused_result__)); + +__wasi_errno_t +wasi_ssp_sock_set_send_buf_size( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, __wasi_size_t size +) __attribute__((__warn_unused_result__)); + __wasi_errno_t wasi_ssp_sock_listen( #if !defined(WASMTIME_SSP_STATIC_CURFDS) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index e43ba8ce..487db655 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -3149,6 +3149,115 @@ wasi_ssp_sock_connect( return __WASI_ESUCCESS; } +__wasi_errno_t +wasi_ssp_sock_get_recv_buf_size( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, __wasi_size_t *size) +{ + struct fd_object *fo; + int ret; + __wasi_errno_t error = fd_object_get(curfds, &fo, fd, 0, 0); + if (error != __WASI_ESUCCESS) + return error; + + int optval; + socklen_t optlen = sizeof(optval); + + ret = getsockopt(fd_number(fo), SOL_SOCKET, SO_RCVBUF, &optval, &optlen); + fd_object_release(fo); + if (BHT_OK != ret) { + return convert_errno(errno); + } + + *size = optval; + + return __WASI_ESUCCESS; +} + +__wasi_errno_t +wasi_ssp_sock_get_reuse_addr( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, uint8_t *reuse) +{ + + struct fd_object *fo; + int ret; + __wasi_errno_t error = fd_object_get(curfds, &fo, fd, 0, 0); + if (error != __WASI_ESUCCESS) + return error; + + int optval; + socklen_t optlen = sizeof(optval); + + ret = getsockopt(fd_number(fo), SOL_SOCKET, SO_REUSEADDR, &optval, &optlen); + fd_object_release(fo); + if (BHT_OK != ret) { + return convert_errno(errno); + } + + *reuse = optval; + + return __WASI_ESUCCESS; +} + +__wasi_errno_t +wasi_ssp_sock_get_reuse_port( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, uint8_t *reuse) +{ + struct fd_object *fo; + int ret; + __wasi_errno_t error = fd_object_get(curfds, &fo, fd, 0, 0); + if (error != __WASI_ESUCCESS) + return error; + + int optval; + socklen_t optlen = sizeof(optval); + + ret = getsockopt(fd_number(fo), SOL_SOCKET, SO_REUSEPORT, &optval, &optlen); + fd_object_release(fo); + if (BHT_OK != ret) { + return convert_errno(errno); + } + + *reuse = optval; + + return __WASI_ESUCCESS; +} + +__wasi_errno_t +wasi_ssp_sock_get_send_buf_size( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, __wasi_size_t *size) +{ + struct fd_object *fo; + int ret; + __wasi_errno_t error = fd_object_get(curfds, &fo, fd, 0, 0); + if (error != __WASI_ESUCCESS) + return error; + + int optval; + socklen_t optlen = sizeof(optval); + + ret = getsockopt(fd_number(fo), SOL_SOCKET, SO_SNDBUF, &optval, &optlen); + fd_object_release(fo); + if (BHT_OK != ret) { + return convert_errno(errno); + } + + *size = optval; + + return __WASI_ESUCCESS; +} + __wasi_errno_t wasi_ssp_sock_listen( #if !defined(WASMTIME_SSP_STATIC_CURFDS) @@ -3219,6 +3328,106 @@ wasi_ssp_sock_open( return __WASI_ESUCCESS; } +__wasi_errno_t +wasi_ssp_sock_set_recv_buf_size( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, __wasi_size_t size) +{ + struct fd_object *fo; + int ret; + __wasi_errno_t error = fd_object_get(curfds, &fo, fd, 0, 0); + if (error != __WASI_ESUCCESS) + return error; + + int optval = size; + + ret = setsockopt(fd_number(fo), SOL_SOCKET, SO_RCVBUF, &optval, + sizeof(optval)); + fd_object_release(fo); + if (BHT_OK != ret) { + return convert_errno(errno); + } + + return __WASI_ESUCCESS; +} + +__wasi_errno_t +wasi_ssp_sock_set_reuse_addr( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, uint8_t reuse) +{ + struct fd_object *fo; + int ret; + __wasi_errno_t error = fd_object_get(curfds, &fo, fd, 0, 0); + if (error != __WASI_ESUCCESS) + return error; + + int optval = reuse; + + ret = setsockopt(fd_number(fo), SOL_SOCKET, SO_REUSEADDR, &optval, + sizeof(optval)); + fd_object_release(fo); + if (BHT_OK != ret) { + return convert_errno(errno); + } + + return __WASI_ESUCCESS; +} + +__wasi_errno_t +wasi_ssp_sock_set_reuse_port( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, uint8_t reuse) +{ + struct fd_object *fo; + int ret; + __wasi_errno_t error = fd_object_get(curfds, &fo, fd, 0, 0); + if (error != __WASI_ESUCCESS) + return error; + + int optval = reuse; + + ret = setsockopt(fd_number(fo), SOL_SOCKET, SO_REUSEPORT, &optval, + sizeof(optval)); + fd_object_release(fo); + if (BHT_OK != ret) { + return convert_errno(errno); + } + + return __WASI_ESUCCESS; +} + +__wasi_errno_t +wasi_ssp_sock_set_send_buf_size( +#if !defined(WASMTIME_SSP_STATIC_CURFDS) + struct fd_table *curfds, +#endif + __wasi_fd_t fd, __wasi_size_t size) +{ + struct fd_object *fo; + int ret; + __wasi_errno_t error = fd_object_get(curfds, &fo, fd, 0, 0); + if (error != __WASI_ESUCCESS) + return error; + + int optval = size; + + ret = setsockopt(fd_number(fo), SOL_SOCKET, SO_SNDBUF, &optval, + sizeof(optval)); + fd_object_release(fo); + if (BHT_OK != ret) { + return convert_errno(errno); + } + + return __WASI_ESUCCESS; +} + __wasi_errno_t wasmtime_ssp_sock_recv( #if !defined(WASMTIME_SSP_STATIC_CURFDS) diff --git a/core/shared/platform/esp-idf/espidf_socket.c b/core/shared/platform/esp-idf/espidf_socket.c new file mode 100644 index 00000000..37e412b2 --- /dev/null +++ b/core/shared/platform/esp-idf/espidf_socket.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2021 Intel Corporation. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include "platform_api_vmcore.h" +#include "platform_api_extension.h" + +#include + +static void +textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr_in *out) +{ + assert(textual); + + out->sin_family = AF_INET; + out->sin_port = htons(port); + out->sin_addr.s_addr = inet_addr(textual); +} + +static int +sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, socklen_t socklen, + bh_sockaddr_t *bh_sockaddr) +{ + switch (sockaddr->sa_family) { + case AF_INET: + { + struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr; + + assert(socklen >= sizeof(struct sockaddr_in)); + + bh_sockaddr->port = ntohs(addr->sin_port); + bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr); + bh_sockaddr->is_ipv4 = true; + return BHT_OK; + } + default: + errno = EAFNOSUPPORT; + return BHT_ERROR; + } +} + +int +os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp) +{ + if (!sock) { + return BHT_ERROR; + } + + if (is_tcp) { + *sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + } + else { + *sock = socket(AF_INET, SOCK_DGRAM, 0); + } + + return (*sock == -1) ? BHT_ERROR : BHT_OK; +} + +int +os_socket_bind(bh_socket_t socket, const char *host, int *port) +{ + struct sockaddr_in addr; + socklen_t socklen; + int ret; + + assert(host); + assert(port); + + addr.sin_addr.s_addr = inet_addr(host); + addr.sin_port = htons(*port); + addr.sin_family = AF_INET; + + ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) { + goto fail; + } + + socklen = sizeof(addr); + if (getsockname(socket, (void *)&addr, &socklen) == -1) { + goto fail; + } + + *port = ntohs(addr.sin_port); + + return BHT_OK; + +fail: + return BHT_ERROR; +} + +int +os_socket_settimeout(bh_socket_t socket, uint64 timeout_us) +{ + struct timeval tv; + tv.tv_sec = timeout_us / 1000000UL; + tv.tv_usec = timeout_us % 1000000UL; + + if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, + sizeof(tv)) + != 0) { + return BHT_ERROR; + } + + return BHT_OK; +} + +int +os_socket_listen(bh_socket_t socket, int max_client) +{ + if (listen(socket, max_client) != 0) { + return BHT_ERROR; + } + + return BHT_OK; +} + +int +os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr, + unsigned int *addrlen) +{ + struct sockaddr addr_tmp; + unsigned int len = sizeof(struct sockaddr); + + *sock = accept(server_sock, (struct sockaddr *)&addr_tmp, &len); + + if (*sock < 0) { + return BHT_ERROR; + } + + return BHT_OK; +} + +int +os_socket_connect(bh_socket_t socket, const char *addr, int port) +{ + struct sockaddr_in addr_in = { 0 }; + socklen_t addr_len = sizeof(struct sockaddr_in); + int ret = 0; + + textual_addr_to_sockaddr(addr, port, &addr_in); + + ret = connect(socket, (struct sockaddr *)&addr_in, addr_len); + if (ret == -1) { + return BHT_ERROR; + } + + return BHT_OK; +} + +int +os_socket_recv(bh_socket_t socket, void *buf, unsigned int len) +{ + return recv(socket, buf, len, 0); +} + +int +os_socket_send(bh_socket_t socket, const void *buf, unsigned int len) +{ + return send(socket, buf, len, 0); +} + +int +os_socket_close(bh_socket_t socket) +{ + close(socket); + return BHT_OK; +} + +int +os_socket_shutdown(bh_socket_t socket) +{ + shutdown(socket, O_RDWR); + return BHT_OK; +} + +int +os_socket_inet_network(bool is_ipv4, const char *cp, bh_ip_addr_buffer_t *out) +{ + if (!cp) + return BHT_ERROR; + + if (is_ipv4) { + if (inet_pton(AF_INET, cp, &out->ipv4) != 1) { + return BHT_ERROR; + } + /* Note: ntohl(INADDR_NONE) == INADDR_NONE */ + out->ipv4 = ntohl(out->ipv4); + } + else { + if (inet_pton(AF_INET6, cp, out->ipv6) != 1) { + return BHT_ERROR; + } + for (int i = 0; i < 8; i++) { + out->ipv6[i] = ntohs(out->ipv6[i]); + } + } + + return BHT_OK; +} + +int +os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr) +{ + struct sockaddr_in addr; + socklen_t addr_len = sizeof(addr); + + if (getpeername(socket, &addr, &addr_len) == -1) { + return BHT_ERROR; + } + + return sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len, + sockaddr); +} + +int +os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr) +{ + struct sockaddr_in addr; + socklen_t addr_len = sizeof(addr); + + if (getsockname(socket, &addr, &addr_len) == -1) { + return BHT_ERROR; + } + + return sockaddr_to_bh_sockaddr((struct sockaddr *)&addr, addr_len, + sockaddr); +} diff --git a/core/shared/platform/linux-sgx/sgx_socket.c b/core/shared/platform/linux-sgx/sgx_socket.c index cfaaaf1b..afb6d601 100644 --- a/core/shared/platform/linux-sgx/sgx_socket.c +++ b/core/shared/platform/linux-sgx/sgx_socket.c @@ -370,6 +370,24 @@ getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen) return ret; } +int +setsockopt(int sockfd, int level, int optname, const void *optval, + socklen_t optlen) +{ + int ret; + + if (ocall_setsockopt(&ret, sockfd, level, optname, (void *)optval, optlen) + != SGX_SUCCESS) { + TRACE_OCALL_FAIL(); + return -1; + } + + if (ret == -1) + errno = get_errno(); + + return ret; +} + ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) { diff --git a/core/shared/platform/linux-sgx/sgx_socket.h b/core/shared/platform/linux-sgx/sgx_socket.h index b7a58ba0..edf977dd 100644 --- a/core/shared/platform/linux-sgx/sgx_socket.h +++ b/core/shared/platform/linux-sgx/sgx_socket.h @@ -312,6 +312,10 @@ socket(int domain, int type, int protocol); int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen); +int +setsockopt(int sockfd, int level, int optname, const void *optval, + socklen_t optlen); + ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);