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

Refer to [Networking API design](https://github.com/WebAssembly/WASI/issues/370)
and [feat(socket): berkeley socket API v2](https://github.com/WebAssembly/WASI/pull/459):

- Support the socket API of synchronous mode, including `socket/bind/listen/accept/send/recv/close/shutdown`,
    the asynchronous mode isn't supported yet.
- Support adding `--addr-pool=<pool1,pool2,..>` argument for command line to identify the valid ip address range
- Add socket-api sample and update the document
This commit is contained in:
Wenyong Huang
2022-03-10 15:13:38 +08:00
committed by GitHub
parent 0065743075
commit 9c87a1ee17
28 changed files with 2211 additions and 214 deletions

View File

@ -49,6 +49,9 @@ _Static_assert(_Alignof(int64_t) == 8, "non-wasi data layout");
_Static_assert(_Alignof(uint64_t) == 8, "non-wasi data layout");
#endif
typedef uint32_t __wasi_size_t;
_Static_assert(_Alignof(__wasi_size_t) == 4, "non-wasi data layout");
typedef uint8_t __wasi_advice_t;
#define __WASI_ADVICE_NORMAL (0)
#define __WASI_ADVICE_SEQUENTIAL (1)
@ -211,35 +214,44 @@ typedef uint64_t __wasi_rights_t;
* Observe that WASI defines rights in the plural form
* TODO: refactor to use RIGHTS instead of RIGHT
*/
#define __WASI_RIGHT_FD_DATASYNC ((__wasi_rights_t)(1 << 0))
#define __WASI_RIGHT_FD_READ ((__wasi_rights_t)(1 << 1))
#define __WASI_RIGHT_FD_SEEK ((__wasi_rights_t)(1 << 2))
#define __WASI_RIGHT_FD_FDSTAT_SET_FLAGS ((__wasi_rights_t)(1 << 3))
#define __WASI_RIGHT_FD_SYNC ((__wasi_rights_t)(1 << 4))
#define __WASI_RIGHT_FD_TELL ((__wasi_rights_t)(1 << 5))
#define __WASI_RIGHT_FD_WRITE ((__wasi_rights_t)(1 << 6))
#define __WASI_RIGHT_FD_ADVISE ((__wasi_rights_t)(1 << 7))
#define __WASI_RIGHT_FD_ALLOCATE ((__wasi_rights_t)(1 << 8))
#define __WASI_RIGHT_PATH_CREATE_DIRECTORY ((__wasi_rights_t)(1 << 9))
#define __WASI_RIGHT_PATH_CREATE_FILE ((__wasi_rights_t)(1 << 10))
#define __WASI_RIGHT_PATH_LINK_SOURCE ((__wasi_rights_t)(1 << 11))
#define __WASI_RIGHT_PATH_LINK_TARGET ((__wasi_rights_t)(1 << 12))
#define __WASI_RIGHT_PATH_OPEN ((__wasi_rights_t)(1 << 13))
#define __WASI_RIGHT_FD_READDIR ((__wasi_rights_t)(1 << 14))
#define __WASI_RIGHT_PATH_READLINK ((__wasi_rights_t)(1 << 15))
#define __WASI_RIGHT_PATH_RENAME_SOURCE ((__wasi_rights_t)(1 << 16))
#define __WASI_RIGHT_PATH_RENAME_TARGET ((__wasi_rights_t)(1 << 17))
#define __WASI_RIGHT_PATH_FILESTAT_GET ((__wasi_rights_t)(1 << 18))
#define __WASI_RIGHT_PATH_FILESTAT_SET_SIZE ((__wasi_rights_t)(1 << 19))
#define __WASI_RIGHT_PATH_FILESTAT_SET_TIMES ((__wasi_rights_t)(1 << 20))
#define __WASI_RIGHT_FD_FILESTAT_GET ((__wasi_rights_t)(1 << 21))
#define __WASI_RIGHT_FD_FILESTAT_SET_SIZE ((__wasi_rights_t)(1 << 22))
#define __WASI_RIGHT_FD_FILESTAT_SET_TIMES ((__wasi_rights_t)(1 << 23))
#define __WASI_RIGHT_PATH_SYMLINK ((__wasi_rights_t)(1 << 24))
#define __WASI_RIGHT_PATH_REMOVE_DIRECTORY ((__wasi_rights_t)(1 << 25))
#define __WASI_RIGHT_PATH_UNLINK_FILE ((__wasi_rights_t)(1 << 26))
#define __WASI_RIGHT_POLL_FD_READWRITE ((__wasi_rights_t)(1 << 27))
#define __WASI_RIGHT_SOCK_SHUTDOWN ((__wasi_rights_t)(1 << 28))
#define __WASI_RIGHT_FD_DATASYNC ((__wasi_rights_t)(UINT64_C(1) << 0))
#define __WASI_RIGHT_FD_READ ((__wasi_rights_t)(UINT64_C(1) << 1))
#define __WASI_RIGHT_FD_SEEK ((__wasi_rights_t)(UINT64_C(1) << 2))
#define __WASI_RIGHT_FD_FDSTAT_SET_FLAGS ((__wasi_rights_t)(UINT64_C(1) << 3))
#define __WASI_RIGHT_FD_SYNC ((__wasi_rights_t)(UINT64_C(1) << 4))
#define __WASI_RIGHT_FD_TELL ((__wasi_rights_t)(UINT64_C(1) << 5))
#define __WASI_RIGHT_FD_WRITE ((__wasi_rights_t)(UINT64_C(1) << 6))
#define __WASI_RIGHT_FD_ADVISE ((__wasi_rights_t)(UINT64_C(1) << 7))
#define __WASI_RIGHT_FD_ALLOCATE ((__wasi_rights_t)(UINT64_C(1) << 8))
#define __WASI_RIGHT_PATH_CREATE_DIRECTORY ((__wasi_rights_t)(UINT64_C(1) << 9))
#define __WASI_RIGHT_PATH_CREATE_FILE ((__wasi_rights_t)(UINT64_C(1) << 10))
#define __WASI_RIGHT_PATH_LINK_SOURCE ((__wasi_rights_t)(UINT64_C(1) << 11))
#define __WASI_RIGHT_PATH_LINK_TARGET ((__wasi_rights_t)(UINT64_C(1) << 12))
#define __WASI_RIGHT_PATH_OPEN ((__wasi_rights_t)(UINT64_C(1) << 13))
#define __WASI_RIGHT_FD_READDIR ((__wasi_rights_t)(UINT64_C(1) << 14))
#define __WASI_RIGHT_PATH_READLINK ((__wasi_rights_t)(UINT64_C(1) << 15))
#define __WASI_RIGHT_PATH_RENAME_SOURCE ((__wasi_rights_t)(UINT64_C(1) << 16))
#define __WASI_RIGHT_PATH_RENAME_TARGET ((__wasi_rights_t)(UINT64_C(1) << 17))
#define __WASI_RIGHT_PATH_FILESTAT_GET ((__wasi_rights_t)(UINT64_C(1) << 18))
#define __WASI_RIGHT_PATH_FILESTAT_SET_SIZE ((__wasi_rights_t)(UINT64_C(1) << 19))
#define __WASI_RIGHT_PATH_FILESTAT_SET_TIMES ((__wasi_rights_t)(UINT64_C(1) << 20))
#define __WASI_RIGHT_FD_FILESTAT_GET ((__wasi_rights_t)(UINT64_C(1) << 21))
#define __WASI_RIGHT_FD_FILESTAT_SET_SIZE ((__wasi_rights_t)(UINT64_C(1) << 22))
#define __WASI_RIGHT_FD_FILESTAT_SET_TIMES ((__wasi_rights_t)(UINT64_C(1) << 23))
#define __WASI_RIGHT_PATH_SYMLINK ((__wasi_rights_t)(UINT64_C(1) << 24))
#define __WASI_RIGHT_PATH_REMOVE_DIRECTORY ((__wasi_rights_t)(UINT64_C(1) << 25))
#define __WASI_RIGHT_PATH_UNLINK_FILE ((__wasi_rights_t)(UINT64_C(1) << 26))
#define __WASI_RIGHT_POLL_FD_READWRITE ((__wasi_rights_t)(UINT64_C(1) << 27))
#define __WASI_RIGHT_SOCK_CONNECT ((__wasi_rights_t)(UINT64_C(1) << 28))
#define __WASI_RIGHT_SOCK_LISTEN ((__wasi_rights_t)(UINT64_C(1) << 29))
#define __WASI_RIGHT_SOCK_BIND ((__wasi_rights_t)(UINT64_C(1) << 30))
#define __WASI_RIGHT_SOCK_ACCEPT ((__wasi_rights_t)(UINT64_C(1) << 31))
#define __WASI_RIGHT_SOCK_RECV ((__wasi_rights_t)(UINT64_C(1) << 32))
#define __WASI_RIGHT_SOCK_SEND ((__wasi_rights_t)(UINT64_C(1) << 33))
#define __WASI_RIGHT_SOCK_ADDR_LOCAL ((__wasi_rights_t)(UINT64_C(1) << 34))
#define __WASI_RIGHT_SOCK_ADDR_REMOTE ((__wasi_rights_t)(UINT64_C(1) << 35))
#define __WASI_RIGHT_SOCK_RECV_FROM ((__wasi_rights_t)(UINT64_C(1) << 36))
#define __WASI_RIGHT_SOCK_SEND_TO ((__wasi_rights_t)(UINT64_C(1) << 37))
typedef uint16_t __wasi_roflags_t;
#define __WASI_SOCK_RECV_DATA_TRUNCATED (0x0001)
@ -301,6 +313,7 @@ typedef uint8_t __wasi_preopentype_t;
struct fd_table;
struct fd_prestats;
struct argv_environ_values;
struct addr_pool;
typedef struct __wasi_dirent_t {
__wasi_dircookie_t d_next;
@ -536,6 +549,55 @@ _Static_assert(_Alignof(__wasi_subscription_t) == 8, "witx calculated align");
_Static_assert(offsetof(__wasi_subscription_t, userdata) == 0, "witx calculated offset");
_Static_assert(offsetof(__wasi_subscription_t, u) == 8, "witx calculated offset");
/* keep syncing with wasi_socket_ext.h */
typedef enum {
SOCKET_DGRAM = 0,
SOCKET_STREAM,
} __wasi_sock_type_t;
typedef uint16_t __wasi_ip_port_t;
typedef enum { IPv4 = 0, IPv6 } __wasi_addr_type_t;
/* n0.n1.n2.n3 */
typedef struct __wasi_addr_ip4_t {
uint8_t n0;
uint8_t n1;
uint8_t n2;
uint8_t n3;
} __wasi_addr_ip4_t;
typedef struct __wasi_addr_ip4_port_t {
__wasi_addr_ip4_t addr;
__wasi_ip_port_t port;
} __wasi_addr_ip4_port_t;
typedef struct __wasi_addr_ip6_t {
uint16_t n0;
uint16_t n1;
uint16_t n2;
uint16_t n3;
uint16_t h0;
uint16_t h1;
uint16_t h2;
uint16_t h3;
} __wasi_addr_ip6_t;
typedef struct __wasi_addr_ip6_port_t {
__wasi_addr_ip6_t addr;
__wasi_ip_port_t port;
} __wasi_addr_ip6_port_t;
typedef struct __wasi_addr_t {
__wasi_addr_type_t kind;
union {
__wasi_addr_ip4_port_t ip4;
__wasi_addr_ip6_port_t ip6;
} addr;
} __wasi_addr_t;
typedef enum { INET4 = 0, INET6 } __wasi_address_family_t;
#if defined(WASMTIME_SSP_WASI_API)
#define WASMTIME_SSP_SYSCALL_NAME(name) \
asm("__wasi_" #name)
@ -920,16 +982,71 @@ __wasi_errno_t wasmtime_ssp_random_get(
size_t buf_len
) WASMTIME_SSP_SYSCALL_NAME(random_get) __attribute__((__warn_unused_result__));
__wasi_errno_t
wasi_ssp_sock_accept(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t *fd_new
) __attribute__((__warn_unused_result__));
__wasi_errno_t
wasi_ssp_sock_addr_local(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd, uint8_t *buf, __wasi_size_t buf_len
) __attribute__((__warn_unused_result__));
__wasi_errno_t
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
) __attribute__((__warn_unused_result__));
__wasi_errno_t
wasi_ssp_sock_open(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t poolfd, __wasi_address_family_t af, __wasi_sock_type_t socktype,
__wasi_fd_t *sockfd
) __attribute__((__warn_unused_result__));
__wasi_errno_t
wasi_ssp_sock_bind(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds, struct addr_pool *addr_pool,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr
) __attribute__((__warn_unused_result__));
__wasi_errno_t
wasi_ssp_sock_connect(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds, struct addr_pool *addr_pool,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr
) __attribute__((__warn_unused_result__));
__wasi_errno_t
wasi_ssp_sock_listen(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t backlog
) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_recv(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
const __wasi_iovec_t *ri_data,
size_t ri_data_len,
__wasi_riflags_t ri_flags,
size_t *ro_datalen,
__wasi_roflags_t *ro_flags
void *buf,
size_t buf_len,
size_t *recv_len
) WASMTIME_SSP_SYSCALL_NAME(sock_recv) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_send(
@ -937,18 +1054,16 @@ __wasi_errno_t wasmtime_ssp_sock_send(
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
const __wasi_ciovec_t *si_data,
size_t si_data_len,
__wasi_siflags_t si_flags,
size_t *so_datalen
const void *buf,
size_t buf_len,
size_t *sent_len
) WASMTIME_SSP_SYSCALL_NAME(sock_send) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sock_shutdown(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
__wasi_sdflags_t how
__wasi_fd_t sock
) WASMTIME_SSP_SYSCALL_NAME(sock_shutdown) __attribute__((__warn_unused_result__));
__wasi_errno_t wasmtime_ssp_sched_yield(void)

View File

@ -60,6 +60,7 @@ static_assert(sizeof(struct iovec) == sizeof(__wasi_ciovec_t),
static __thread struct fd_table *curfds;
static __thread struct fd_prestats *prestats;
static __thread struct argv_environ_values *argv_environ;
static __thread struct addr_pool *addr_pool;
#endif
// Converts a POSIX error code to a CloudABI error code.
@ -2715,44 +2716,246 @@ wasmtime_ssp_random_get(void *buf, size_t nbyte)
return 0;
}
__wasi_errno_t
wasi_ssp_sock_accept(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fd_t *fd_new)
{
__wasi_filetype_t wasi_type;
__wasi_rights_t max_base, max_inheriting;
struct fd_object *fo;
bh_socket_t new_sock;
int ret;
__wasi_errno_t error =
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ACCEPT, 0);
if (error != __WASI_ESUCCESS)
return error;
ret = os_socket_accept(fd_number(fo), &new_sock, NULL, NULL);
fd_object_release(fo);
if (ret == BHT_ERROR)
return convert_errno(errno);
error = fd_determine_type_rights(new_sock, &wasi_type, &max_base,
&max_inheriting);
if (error != __WASI_ESUCCESS) {
os_socket_close(ret);
return error;
}
error = fd_table_insert_fd(curfds, new_sock, wasi_type, max_base,
max_inheriting, fd_new);
if (error != __WASI_ESUCCESS) {
os_socket_close(ret);
return error;
}
return __WASI_ESUCCESS;
}
__wasi_errno_t
wasi_ssp_sock_addr_local(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd, uint8 *buf, __wasi_size_t buf_len)
{
struct fd_object *fo;
__wasi_errno_t error =
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ADDR_LOCAL, 0);
if (error != __WASI_ESUCCESS)
return error;
fd_object_release(fo);
return __WASI_ENOSYS;
}
__wasi_errno_t
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)
{
struct fd_object *fo;
__wasi_errno_t error =
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_ADDR_REMOTE, 0);
if (error != __WASI_ESUCCESS)
return error;
fd_object_release(fo);
return __WASI_ENOSYS;
}
__wasi_errno_t
wasi_ssp_sock_bind(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds, struct addr_pool *addr_pool,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr)
{
char buf[24] = { 0 };
const char *format = "%u.%u.%u.%u";
struct fd_object *fo;
__wasi_errno_t error;
int port = addr->addr.ip4.port;
int ret;
snprintf(buf, 24, format, addr->addr.ip4.addr.n0, addr->addr.ip4.addr.n1,
addr->addr.ip4.addr.n2, addr->addr.ip4.addr.n3);
if (!addr_pool_search(addr_pool, buf)) {
return __WASI_EACCES;
}
error = fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_BIND, 0);
if (error != __WASI_ESUCCESS)
return error;
ret = os_socket_bind(fd_number(fo), buf, &port);
fd_object_release(fo);
if (ret == BHT_ERROR) {
return convert_errno(errno);
}
return __WASI_ESUCCESS;
}
__wasi_errno_t
wasi_ssp_sock_connect(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds, struct addr_pool *addr_pool,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr)
{
char buf[24] = { 0 };
const char *format = "%u.%u.%u.%u";
struct fd_object *fo;
__wasi_errno_t error;
int ret;
snprintf(buf, 24, format, addr->addr.ip4.addr.n0, addr->addr.ip4.addr.n1,
addr->addr.ip4.addr.n2, addr->addr.ip4.addr.n3);
if (!addr_pool_search(addr_pool, buf)) {
return __WASI_EACCES;
}
error = fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_BIND, 0);
if (error != __WASI_ESUCCESS)
return error;
ret = os_socket_connect(fd_number(fo), buf, addr->addr.ip4.port);
fd_object_release(fo);
if (ret == BHT_ERROR) {
return convert_errno(errno);
}
return __WASI_ESUCCESS;
}
__wasi_errno_t
wasi_ssp_sock_listen(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t backlog)
{
struct fd_object *fo;
int ret;
__wasi_errno_t error =
fd_object_get(curfds, &fo, fd, __WASI_RIGHT_SOCK_LISTEN, 0);
if (error != __WASI_ESUCCESS)
return error;
ret = os_socket_listen(fd_number(fo), backlog);
fd_object_release(fo);
if (ret == BHT_ERROR) {
return convert_errno(errno);
}
return __WASI_ESUCCESS;
}
__wasi_errno_t
wasi_ssp_sock_open(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t poolfd, __wasi_address_family_t af, __wasi_sock_type_t socktype,
__wasi_fd_t *sockfd)
{
bh_socket_t sock;
int tcp_or_udp = 0;
int ret;
__wasi_filetype_t wasi_type;
__wasi_rights_t max_base, max_inheriting;
__wasi_errno_t error;
(void)poolfd;
if (INET4 != af) {
return __WASI_EAFNOSUPPORT;
}
tcp_or_udp = SOCKET_DGRAM == socktype ? 0 : 1;
ret = os_socket_create(&sock, tcp_or_udp);
if (ret == BHT_ERROR) {
return convert_errno(errno);
}
error =
fd_determine_type_rights(sock, &wasi_type, &max_base, &max_inheriting);
if (error != __WASI_ESUCCESS) {
os_socket_close(ret);
return error;
}
if (SOCKET_DGRAM == socktype) {
assert(wasi_type == __WASI_FILETYPE_SOCKET_DGRAM);
}
else {
assert(wasi_type == __WASI_FILETYPE_SOCKET_STREAM);
}
// TODO: base rights and inheriting rights ?
error = fd_table_insert_fd(curfds, sock, wasi_type, max_base,
max_inheriting, sockfd);
if (error != __WASI_ESUCCESS) {
os_socket_close(ret);
return error;
}
return __WASI_ESUCCESS;
}
__wasi_errno_t
wasmtime_ssp_sock_recv(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t sock, const __wasi_iovec_t *ri_data, size_t ri_data_len,
__wasi_riflags_t ri_flags, size_t *ro_datalen, __wasi_roflags_t *ro_flags)
__wasi_fd_t sock, void *buf, size_t buf_len, size_t *recv_len)
{
// Convert input to msghdr.
struct msghdr hdr = {
.msg_iov = (struct iovec *)ri_data,
.msg_iovlen = ri_data_len,
};
int nflags = 0;
if ((ri_flags & __WASI_SOCK_RECV_PEEK) != 0)
nflags |= MSG_PEEK;
if ((ri_flags & __WASI_SOCK_RECV_WAITALL) != 0)
nflags |= MSG_WAITALL;
struct fd_object *fo;
__wasi_errno_t error =
fd_object_get(curfds, &fo, sock, __WASI_RIGHT_FD_READ, 0);
__wasi_errno_t error;
int ret;
error = fd_object_get(curfds, &fo, sock, __WASI_RIGHT_FD_READ, 0);
if (error != 0) {
return error;
}
ssize_t datalen = recvmsg(fd_number(fo), &hdr, nflags);
ret = os_socket_recv(fd_number(fo), buf, buf_len);
fd_object_release(fo);
if (datalen < 0) {
if (ret == BHT_ERROR) {
return convert_errno(errno);
}
// Convert msghdr to output.
*ro_datalen = (size_t)datalen;
*ro_flags = 0;
if ((hdr.msg_flags & MSG_TRUNC) != 0)
*ro_flags |= __WASI_SOCK_RECV_DATA_TRUNCATED;
return 0;
*recv_len = (size_t)ret;
return __WASI_ESUCCESS;
}
__wasi_errno_t
@ -2760,34 +2963,25 @@ wasmtime_ssp_sock_send(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t sock, const __wasi_ciovec_t *si_data, size_t si_data_len,
__wasi_siflags_t si_flags, size_t *so_datalen) NO_LOCK_ANALYSIS
__wasi_fd_t sock, const void *buf, size_t buf_len, size_t *sent_len)
{
// Convert input to msghdr.
struct msghdr hdr = {
.msg_iov = (struct iovec *)si_data,
.msg_iovlen = si_data_len,
};
// Attach file descriptors if present.
__wasi_errno_t error;
// Send message.
struct fd_object *fo;
__wasi_errno_t error;
int ret;
error = fd_object_get(curfds, &fo, sock, __WASI_RIGHT_FD_WRITE, 0);
if (error != 0)
goto out;
ssize_t len = sendmsg(fd_number(fo), &hdr, 0);
fd_object_release(fo);
if (len < 0) {
error = convert_errno(errno);
}
else {
*so_datalen = (size_t)len;
if (error != 0) {
return error;
}
out:
return error;
ret = os_socket_send(fd_number(fo), buf, buf_len);
fd_object_release(fo);
if (ret == BHT_ERROR) {
return convert_errno(errno);
}
*sent_len = (size_t)ret;
return __WASI_ESUCCESS;
}
__wasi_errno_t
@ -2795,34 +2989,22 @@ wasmtime_ssp_sock_shutdown(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_table *curfds,
#endif
__wasi_fd_t sock, __wasi_sdflags_t how)
__wasi_fd_t sock)
{
int nhow;
switch (how) {
case __WASI_SHUT_RD:
nhow = SHUT_RD;
break;
case __WASI_SHUT_WR:
nhow = SHUT_WR;
break;
case __WASI_SHUT_RD | __WASI_SHUT_WR:
nhow = SHUT_RDWR;
break;
default:
return __WASI_EINVAL;
}
struct fd_object *fo;
__wasi_errno_t error =
fd_object_get(curfds, &fo, sock, __WASI_RIGHT_SOCK_SHUTDOWN, 0);
__wasi_errno_t error;
int ret;
error = fd_object_get(curfds, &fo, sock, 0, 0);
if (error != 0)
return error;
int ret = shutdown(fd_number(fo), nhow);
ret = os_socket_shutdown(fd_number(fo));
fd_object_release(fo);
if (ret < 0)
if (ret == BHT_ERROR)
return convert_errno(errno);
return 0;
return __WASI_ESUCCESS;
}
__wasi_errno_t
@ -2943,3 +3125,88 @@ fd_prestats_destroy(struct fd_prestats *pt)
wasm_runtime_free(pt->prestats);
}
}
bool
addr_pool_init(struct addr_pool *addr_pool)
{
addr_pool->next = NULL;
addr_pool->addr = 0;
addr_pool->mask = 0;
return true;
}
bool
addr_pool_insert(struct addr_pool *addr_pool, const char *addr, uint8 mask)
{
struct addr_pool *cur = addr_pool;
struct addr_pool *next;
if (!addr_pool) {
return false;
}
if (!(next = wasm_runtime_malloc(sizeof(struct addr_pool)))) {
return false;
}
next->next = NULL;
next->mask = mask;
if (os_socket_inet_network(addr, &next->addr) != BHT_OK) {
wasm_runtime_free(next);
return false;
}
/* attach with */
while (cur->next) {
cur = cur->next;
}
cur->next = next;
return true;
}
static bool
compare_address(const struct addr_pool *addr_pool_entry, const char *addr)
{
/* host order */
uint32 target;
uint32 address = addr_pool_entry->addr;
/* 0.0.0.0 means any address */
if (0 == address) {
return true;
}
if (os_socket_inet_network(addr, &target) != BHT_OK) {
return false;
}
uint32 mask = addr_pool_entry->mask;
uint32 first_address = address & mask;
uint32 last_address = address | (~mask);
return first_address <= target && target <= last_address;
}
bool
addr_pool_search(struct addr_pool *addr_pool, const char *addr)
{
struct addr_pool *cur = addr_pool->next;
while (cur) {
if (compare_address(cur, addr))
return true;
cur = cur->next;
}
return false;
}
void
addr_pool_destroy(struct addr_pool *addr_pool)
{
struct addr_pool *cur = addr_pool->next;
while (cur) {
struct addr_pool *next = cur->next;
wasm_runtime_free(cur);
cur = next;
}
}

View File

@ -46,6 +46,13 @@ struct argv_environ_values {
size_t environ_count;
};
struct addr_pool {
struct addr_pool *next;
/* addr and mask in host order */
uint32 addr;
uint8 mask;
};
bool
fd_table_init(struct fd_table *);
bool
@ -66,4 +73,13 @@ fd_table_destroy(struct fd_table *ft);
void
fd_prestats_destroy(struct fd_prestats *pt);
bool
addr_pool_init(struct addr_pool *);
bool
addr_pool_insert(struct addr_pool *, const char *, uint8 mask);
bool
addr_pool_search(struct addr_pool *, const char *);
void
addr_pool_destroy(struct addr_pool *);
#endif

View File

@ -32,7 +32,13 @@
__WASI_RIGHT_FD_FILESTAT_SET_SIZE | \
__WASI_RIGHT_PATH_SYMLINK | __WASI_RIGHT_PATH_UNLINK_FILE | \
__WASI_RIGHT_PATH_REMOVE_DIRECTORY | \
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_SHUTDOWN)
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_CONNECT | \
__WASI_RIGHT_SOCK_LISTEN | __WASI_RIGHT_SOCK_BIND | \
__WASI_RIGHT_SOCK_ACCEPT | __WASI_RIGHT_SOCK_RECV | \
__WASI_RIGHT_SOCK_SEND | __WASI_RIGHT_SOCK_ADDR_LOCAL | \
__WASI_RIGHT_SOCK_ADDR_REMOTE | __WASI_RIGHT_SOCK_RECV_FROM | \
__WASI_RIGHT_SOCK_SEND_TO)
// Block and character device interaction is outside the scope of
// CloudABI. Simply allow everything.
@ -71,10 +77,15 @@
#define RIGHTS_REGULAR_FILE_INHERITING 0
// Operations that apply to sockets and socket pairs.
#define RIGHTS_SOCKET_BASE \
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FD_FILESTAT_GET | \
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_SHUTDOWN)
#define RIGHTS_SOCKET_BASE \
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FD_FILESTAT_GET | \
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_CONNECT | \
__WASI_RIGHT_SOCK_LISTEN | __WASI_RIGHT_SOCK_BIND | \
__WASI_RIGHT_SOCK_ACCEPT | __WASI_RIGHT_SOCK_RECV | \
__WASI_RIGHT_SOCK_SEND | __WASI_RIGHT_SOCK_ADDR_LOCAL | \
__WASI_RIGHT_SOCK_ADDR_REMOTE | __WASI_RIGHT_SOCK_RECV_FROM | \
__WASI_RIGHT_SOCK_SEND_TO)
#define RIGHTS_SOCKET_INHERITING RIGHTS_ALL
// Operations that apply to TTYs.