diff --git a/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h b/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h index b76b669e..947ee7ef 100644 --- a/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h +++ b/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h @@ -117,6 +117,9 @@ socket(int domain, int type, int protocol); int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen); + +int +getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen); #endif /** @@ -164,16 +167,15 @@ __wasi_sock_addr_local(__wasi_fd_t fd, __wasi_addr_t *addr) * either IP4 or IP6. */ int32_t -__imported_wasi_snapshot_preview1_sock_addr_remote(int32_t arg0, int32_t arg1, - int32_t arg2) +__imported_wasi_snapshot_preview1_sock_addr_remote(int32_t arg0, int32_t arg1) __attribute__((__import_module__("wasi_snapshot_preview1"), __import_name__("sock_addr_remote"))); static inline __wasi_errno_t -__wasi_sock_addr_remote(__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len) +__wasi_sock_addr_remote(__wasi_fd_t fd, __wasi_addr_t *addr) { return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_addr_remote( - (int32_t)fd, (int32_t)buf, (int32_t)buf_len); + (int32_t)fd, (int32_t)addr); } /** @@ -448,4 +450,4 @@ __wasi_sock_set_send_buf_size(__wasi_fd_t fd) * since don't want to re-compile the wasi-libc, * we tend to keep original implentations of recv() and send(). */ -#endif \ No newline at end of file +#endif diff --git a/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c b/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c index d90d8626..f798b3d2 100644 --- a/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c +++ b/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c @@ -64,10 +64,10 @@ wasi_addr_to_sockaddr(const __wasi_addr_t *wasi_addr, struct sockaddr_in sock_addr_in = { 0 }; uint32_t s_addr; - s_addr = (wasi_addr.addr.ip4.addr.n0 << 24) - | (wasi_addr.addr.ip4.addr.n1 << 16) - | (wasi_addr.addr.ip4.addr.n2 << 8) - | wasi_addr.addr.ip4.addr.n3; + s_addr = (wasi_addr->addr.ip4.addr.n0 << 24) + | (wasi_addr->addr.ip4.addr.n1 << 16) + | (wasi_addr->addr.ip4.addr.n2 << 8) + | wasi_addr->addr.ip4.addr.n3; sock_addr_in.sin_family = AF_INET; sock_addr_in.sin_addr.s_addr = htonl(s_addr); @@ -86,22 +86,6 @@ wasi_addr_to_sockaddr(const __wasi_addr_t *wasi_addr, return __WASI_ERRNO_SUCCESS; } -static __wasi_errno_t -sock_addr_remote(__wasi_fd_t fd, struct sockaddr *sock_addr, socklen_t *addrlen) -{ - __wasi_addr_t wasi_addr = { 0 }; - uint32_t s_addr; - __wasi_errno_t error; - - error = - __wasi_sock_addr_remote(fd, (uint8_t *)&wasi_addr, sizeof(wasi_addr)); - if (__WASI_ERRNO_SUCCESS != error) { - return error; - } - - return wasi_addr_to_sockaddr(&wasi_addr, sock_addr, addrlen); -} - int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { @@ -112,9 +96,8 @@ accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) error = __wasi_sock_accept(sockfd, &new_sockfd); HANDLE_ERROR(error) - // error = sock_addr_remote(new_sockfd, addr, addrlen); - // HANDLE_ERROR(error) - *addrlen = 0; + error = getpeername(new_sockfd, addr, addrlen); + HANDLE_ERROR(error) return new_sockfd; } @@ -284,3 +267,18 @@ getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) return __WASI_ERRNO_SUCCESS; } + +int +getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen) +{ + __wasi_addr_t wasi_addr = { 0 }; + __wasi_errno_t error; + + error = __wasi_sock_addr_remote(sockfd, &wasi_addr); + HANDLE_ERROR(error) + + error = wasi_addr_to_sockaddr(&wasi_addr, addr, addrlen); + HANDLE_ERROR(error) + + return __WASI_ERRNO_SUCCESS; +} diff --git a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c index 77285c27..52c890e1 100644 --- a/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c +++ b/core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c @@ -1028,8 +1028,8 @@ wasi_sock_addr_local(wasm_exec_env_t exec_env, wasi_fd_t fd, } static wasi_errno_t -wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 *buf, - wasi_size_t buf_len) +wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd, + __wasi_addr_t *addr) { wasm_module_inst_t module_inst = get_module_inst(exec_env); wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst); @@ -1038,9 +1038,12 @@ wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8 *buf, if (!wasi_ctx) return __WASI_EACCES; + if (!validate_native_addr(addr, sizeof(__wasi_addr_t))) + return __WASI_EINVAL; + curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx); - return wasi_ssp_sock_addr_remote(curfds, fd, buf, buf_len); + return wasi_ssp_sock_addr_remote(curfds, fd, addr); } static wasi_errno_t @@ -1405,7 +1408,7 @@ static NativeSymbol native_symbols_libc_wasi[] = { REG_NATIVE_FUNC(random_get, "(*~)i"), REG_NATIVE_FUNC(sock_accept, "(i*)i"), REG_NATIVE_FUNC(sock_addr_local, "(i*)i"), - REG_NATIVE_FUNC(sock_addr_remote, "(i*i)i"), + REG_NATIVE_FUNC(sock_addr_remote, "(i*)i"), REG_NATIVE_FUNC(sock_addr_resolve, "($$**i*)i"), REG_NATIVE_FUNC(sock_bind, "(i*)i"), REG_NATIVE_FUNC(sock_close, "(i)i"), 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 7bb40654..2083437c 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 @@ -1015,7 +1015,7 @@ wasi_ssp_sock_addr_remote( #if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, #endif - __wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len + __wasi_fd_t fd, __wasi_addr_t *addr ) __attribute__((__warn_unused_result__)); __wasi_errno_t 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 19d7d2b8..e3b79a88 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 @@ -2918,16 +2918,34 @@ wasi_ssp_sock_addr_remote( #if !defined(WASMTIME_SSP_STATIC_CURFDS) struct fd_table *curfds, #endif - __wasi_fd_t fd, uint8 *buf, __wasi_size_t buf_len) + __wasi_fd_t fd, __wasi_addr_t *addr) { struct fd_object *fo; + uint8 buf[16]; + __wasi_ip_port_t port; + uint8 is_ipv4; + int ret; + __wasi_errno_t error = - fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ADDR_REMOTE, 0); + fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ADDR_LOCAL, 0); if (error != __WASI_ESUCCESS) return error; + ret = os_socket_addr_remote(fd_number(fo), buf, + sizeof(buf) / sizeof(buf[0]), &port, &is_ipv4); fd_object_release(fo); - return __WASI_ENOSYS; + if (ret != BHT_OK) { + return convert_errno(errno); + } + + if (is_ipv4) { + ipv4_addr_to_wasi_addr(*(uint32_t *)buf, port, addr); + } + else { + ipv6_addr_to_wasi_addr((uint16 *)buf, port, addr); + } + + return __WASI_ESUCCESS; } __wasi_errno_t diff --git a/core/shared/platform/common/posix/posix_socket.c b/core/shared/platform/common/posix/posix_socket.c index a2c1b0f1..ccfde372 100644 --- a/core/shared/platform/common/posix/posix_socket.c +++ b/core/shared/platform/common/posix/posix_socket.c @@ -273,28 +273,18 @@ os_socket_addr_resolve(const char *host, const char *service, return BHT_OK; } -int -os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen, - uint16_t *port, uint8_t *is_ipv4) +static int +os_socket_convert_sockaddr(struct sockaddr *addr, uint8_t *buf, size_t buflen, + uint16_t *port, uint8_t *is_ipv4) { - struct sockaddr_storage addr_storage = { 0 }; - socklen_t addr_len = sizeof(addr_storage); - int ret; - assert(buf); assert(is_ipv4); assert(port); - ret = getsockname(socket, (struct sockaddr *)&addr_storage, &addr_len); - - if (ret != BHT_OK) { - return BHT_ERROR; - } - - switch (addr_storage.ss_family) { + switch (addr->sa_family) { case AF_INET: { - struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr_storage; + struct sockaddr_in *addr_in = (struct sockaddr_in *)addr; assert(buflen >= sizeof(addr_in->sin_addr)); *port = ntohs(addr_in->sin_port); @@ -304,7 +294,7 @@ os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen, } case AF_INET6: { - struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)&addr_storage; + struct sockaddr_in6 *addr_in = (struct sockaddr_in6 *)addr; assert(buflen >= sizeof(addr_in->sin6_addr)); *port = ntohs(addr_in->sin6_port); @@ -320,4 +310,40 @@ os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen, } return BHT_OK; +} + +int +os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen, + uint16_t *port, uint8_t *is_ipv4) +{ + struct sockaddr_storage addr_storage = { 0 }; + socklen_t addr_len = sizeof(addr_storage); + int ret; + + ret = getsockname(socket, (struct sockaddr *)&addr_storage, &addr_len); + + if (ret != BHT_OK) { + return BHT_ERROR; + } + + return os_socket_convert_sockaddr((struct sockaddr *)&addr_storage, buf, + buflen, port, is_ipv4); +} + +int +os_socket_addr_remote(bh_socket_t socket, uint8_t *buf, size_t buflen, + uint16_t *port, uint8_t *is_ipv4) +{ + struct sockaddr_storage addr_storage = { 0 }; + socklen_t addr_len = sizeof(addr_storage); + int ret; + + ret = getpeername(socket, (struct sockaddr *)&addr_storage, &addr_len); + + if (ret != BHT_OK) { + return BHT_ERROR; + } + + return os_socket_convert_sockaddr((struct sockaddr *)&addr_storage, buf, + buflen, port, is_ipv4); } \ No newline at end of file diff --git a/core/shared/platform/include/platform_api_extension.h b/core/shared/platform/include/platform_api_extension.h index b6e97406..9b30f4bf 100644 --- a/core/shared/platform/include/platform_api_extension.h +++ b/core/shared/platform/include/platform_api_extension.h @@ -393,6 +393,25 @@ int os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen, uint16_t *port, uint8_t *is_ipv4); +/** + * Returns an binary address and a port of the remote socket + * + * @param socket the remote socket + * + * @param buf buffer to store the address + * + * @param buflen length of the buf buffer + * + * @param port a buffer for storing socket's port + * + * @param is_ipv4 a buffer for storing information about the address family + * + * @return On success, returns 0; otherwise, it returns -1. + */ +int +os_socket_addr_remote(bh_socket_t socket, uint8_t *buf, size_t buflen, + uint16_t *port, uint8_t *is_ipv4); + #ifdef __cplusplus } #endif diff --git a/core/shared/platform/linux-sgx/sgx_socket.c b/core/shared/platform/linux-sgx/sgx_socket.c index b7dc5d01..c588d7f9 100644 --- a/core/shared/platform/linux-sgx/sgx_socket.c +++ b/core/shared/platform/linux-sgx/sgx_socket.c @@ -641,4 +641,13 @@ os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen, return BHT_ERROR; } +int +os_socket_addr_remote(bh_socket_t socket, uint8_t *buf, size_t buflen, + uint16_t *port, uint8_t *is_ipv4) +{ + errno = ENOSYS; + + return BHT_ERROR; +} + #endif diff --git a/core/shared/platform/windows/win_socket.c b/core/shared/platform/windows/win_socket.c index c023593f..ae502bfc 100644 --- a/core/shared/platform/windows/win_socket.c +++ b/core/shared/platform/windows/win_socket.c @@ -180,5 +180,14 @@ os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen, { errno = ENOSYS; + return BHT_ERROR; +} + +int +os_socket_addr_remote(bh_socket_t socket, uint8_t *buf, size_t buflen, + uint16_t *port, uint8_t *is_ipv4) +{ + errno = ENOSYS; + return BHT_ERROR; } \ No newline at end of file diff --git a/samples/socket-api/wasm-src/tcp_server.c b/samples/socket-api/wasm-src/tcp_server.c index 4b8b4362..b7a79aaf 100644 --- a/samples/socket-api/wasm-src/tcp_server.c +++ b/samples/socket-api/wasm-src/tcp_server.c @@ -49,6 +49,7 @@ main(int argc, char *argv[]) unsigned connections = 0; pthread_t workers[WORKER_NUM] = { 0 }; int client_sock_fds[WORKER_NUM] = { 0 }; + char ip_string[16]; printf("[Server] Create socket\n"); socket_fd = socket(AF_INET, SOCK_STREAM, 0); @@ -84,7 +85,11 @@ main(int argc, char *argv[]) break; } - printf("[Server] Client connected\n"); + inet_ntop(AF_INET, &addr.sin_addr, ip_string, + sizeof(ip_string) / sizeof(ip_string[0])); + + printf("[Server] Client connected (%s:%d)\n", ip_string, + ntohs(addr.sin_port)); if (pthread_create(&workers[connections], NULL, run, &client_sock_fds[connections])) { perror("Create a worker thread failed");