mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-11 09:25:20 +00:00
Implement Berkeley Socket API for Intel SGX (#1061)
Implement Berkeley Socket API for Intel SGX - bring Berkeley socket API in Intel SGX enclaves, - adapt the documentation of the socket API to mention Intel SGX enclaves, - adapt _iwasm_ in the mini-product _linux-sgx_ to support the same option as the one for _linux_, - tested on the socket sample as provided by WAMR (the TCP client/server).
This commit is contained in:
parent
5264ce4118
commit
106974d915
|
@ -9,21 +9,194 @@
|
|||
|
||||
#define TRACE_OCALL_FAIL() os_printf("ocall %s failed!\n", __FUNCTION__)
|
||||
|
||||
/** OCALLs prototypes **/
|
||||
int
|
||||
ocall_socket(int *p_ret, int domain, int type, int protocol);
|
||||
ocall_accept(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
|
||||
uint32_t addr_size);
|
||||
|
||||
int
|
||||
ocall_bind(int *p_ret, int sockfd, const void *addr, uint32_t addrlen);
|
||||
|
||||
int
|
||||
ocall_close(int *p_ret, int fd);
|
||||
|
||||
int
|
||||
ocall_connect(int *p_ret, int sockfd, void *addr, uint32_t addrlen);
|
||||
|
||||
int
|
||||
ocall_fcntl_long(int *p_ret, int fd, int cmd, long arg);
|
||||
|
||||
int
|
||||
ocall_getsockname(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
|
||||
uint32_t addr_size);
|
||||
|
||||
int
|
||||
ocall_getsockopt(int *p_ret, int sockfd, int level, int optname, void *val_buf,
|
||||
unsigned int val_buf_size, void *len_buf);
|
||||
|
||||
int
|
||||
ocall_sendmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
|
||||
unsigned int msg_buf_size, int flags);
|
||||
ocall_listen(int *p_ret, int sockfd, int backlog);
|
||||
|
||||
int
|
||||
ocall_recv(int *p_ret, int sockfd, void *buf, size_t len, int flags);
|
||||
|
||||
int
|
||||
ocall_recvmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
|
||||
unsigned int msg_buf_size, int flags);
|
||||
|
||||
int
|
||||
ocall_send(int *p_ret, int sockfd, const void *buf, size_t len, int flags);
|
||||
|
||||
int
|
||||
ocall_sendmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
|
||||
unsigned int msg_buf_size, int flags);
|
||||
|
||||
int
|
||||
ocall_setsockopt(int *p_ret, int sockfd, int level, int optname, void *optval,
|
||||
unsigned int optlen);
|
||||
|
||||
int
|
||||
ocall_shutdown(int *p_ret, int sockfd, int how);
|
||||
|
||||
int
|
||||
ocall_socket(int *p_ret, int domain, int type, int protocol);
|
||||
/** OCALLs prototypes end **/
|
||||
|
||||
/** In-enclave implementation of POSIX functions **/
|
||||
static bool
|
||||
is_little_endian()
|
||||
{
|
||||
long i = 0x01020304;
|
||||
unsigned char *c = (unsigned char *)&i;
|
||||
return (*c == 0x04) ? true : false;
|
||||
}
|
||||
|
||||
static void
|
||||
swap32(uint8 *pData)
|
||||
{
|
||||
uint8 value = *pData;
|
||||
*pData = *(pData + 3);
|
||||
*(pData + 3) = value;
|
||||
|
||||
value = *(pData + 1);
|
||||
*(pData + 1) = *(pData + 2);
|
||||
*(pData + 2) = value;
|
||||
}
|
||||
|
||||
static void
|
||||
swap16(uint8 *pData)
|
||||
{
|
||||
uint8 value = *pData;
|
||||
*(pData) = *(pData + 1);
|
||||
*(pData + 1) = value;
|
||||
}
|
||||
|
||||
static uint32
|
||||
htonl(uint32 value)
|
||||
{
|
||||
uint32 ret;
|
||||
if (is_little_endian()) {
|
||||
ret = value;
|
||||
swap32((uint8 *)&ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static uint32
|
||||
ntohl(uint32 value)
|
||||
{
|
||||
return htonl(value);
|
||||
}
|
||||
|
||||
static uint16
|
||||
htons(uint16 value)
|
||||
{
|
||||
uint16 ret;
|
||||
if (is_little_endian()) {
|
||||
ret = value;
|
||||
swap16((uint8 *)&ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static uint16
|
||||
ntohs(uint16 value)
|
||||
{
|
||||
return htons(value);
|
||||
}
|
||||
|
||||
/* Coming from musl, under MIT license */
|
||||
static int
|
||||
__inet_aton(const char *s0, struct in_addr *dest)
|
||||
{
|
||||
const char *s = s0;
|
||||
unsigned char *d = (void *)dest;
|
||||
unsigned long a[4] = { 0 };
|
||||
char *z;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
a[i] = strtoul(s, &z, 0);
|
||||
if (z == s || (*z && *z != '.') || !isdigit(*s))
|
||||
return 0;
|
||||
if (!*z)
|
||||
break;
|
||||
s = z + 1;
|
||||
}
|
||||
if (i == 4)
|
||||
return 0;
|
||||
switch (i) {
|
||||
case 0:
|
||||
a[1] = a[0] & 0xffffff;
|
||||
a[0] >>= 24;
|
||||
case 1:
|
||||
a[2] = a[1] & 0xffff;
|
||||
a[1] >>= 16;
|
||||
case 2:
|
||||
a[3] = a[2] & 0xff;
|
||||
a[2] >>= 8;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (a[i] > 255)
|
||||
return 0;
|
||||
d[i] = a[i];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Coming from musl, under MIT license */
|
||||
static int
|
||||
inet_addr(const char *p)
|
||||
{
|
||||
struct in_addr a;
|
||||
if (!__inet_aton(p, &a))
|
||||
return -1;
|
||||
return a.s_addr;
|
||||
}
|
||||
|
||||
static int
|
||||
inet_network(const char *p)
|
||||
{
|
||||
return ntohl(inet_addr(p));
|
||||
}
|
||||
/** In-enclave implementation of POSIX functions end **/
|
||||
|
||||
static int
|
||||
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);
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
socket(int domain, int type, int protocol)
|
||||
{
|
||||
|
@ -232,67 +405,219 @@ os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
|
|||
unsigned int *addrlen)
|
||||
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
struct sockaddr addr_tmp;
|
||||
unsigned int len = sizeof(struct sockaddr);
|
||||
|
||||
if (ocall_accept(sock, server_sock, &addr_tmp, &len, len) != SGX_SUCCESS) {
|
||||
TRACE_OCALL_FAIL();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*sock < 0) {
|
||||
errno = get_errno();
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
int
|
||||
os_socket_bind(bh_socket_t socket, const char *host, int *port)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
struct sockaddr_in addr;
|
||||
struct linger ling;
|
||||
unsigned int socklen;
|
||||
int ret;
|
||||
|
||||
assert(host);
|
||||
assert(port);
|
||||
|
||||
ling.l_onoff = 1;
|
||||
ling.l_linger = 0;
|
||||
|
||||
if (ocall_fcntl_long(&ret, socket, F_SETFD, FD_CLOEXEC) != SGX_SUCCESS) {
|
||||
TRACE_OCALL_FAIL();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ocall_setsockopt(&ret, socket, SOL_SOCKET, SO_LINGER, &ling,
|
||||
sizeof(ling))
|
||||
!= SGX_SUCCESS) {
|
||||
TRACE_OCALL_FAIL();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
addr.sin_addr.s_addr = inet_addr(host);
|
||||
addr.sin_port = htons(*port);
|
||||
addr.sin_family = AF_INET;
|
||||
|
||||
if (ocall_bind(&ret, socket, &addr, sizeof(addr)) != SGX_SUCCESS) {
|
||||
TRACE_OCALL_FAIL();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
socklen = sizeof(addr);
|
||||
|
||||
if (ocall_getsockname(&ret, socket, (void *)&addr, &socklen, socklen)
|
||||
!= SGX_SUCCESS) {
|
||||
TRACE_OCALL_FAIL();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == -1) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*port = ntohs(addr.sin_port);
|
||||
|
||||
return BHT_OK;
|
||||
|
||||
fail:
|
||||
errno = get_errno();
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_close(bh_socket_t socket)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
int ret;
|
||||
|
||||
if (ocall_close(&ret, socket) != SGX_SUCCESS) {
|
||||
TRACE_OCALL_FAIL();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
errno = get_errno();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if ((ret = textual_addr_to_sockaddr(addr, port, &addr_in)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ocall_connect(&ret, socket, &addr_in, addr_len) != SGX_SUCCESS) {
|
||||
TRACE_OCALL_FAIL();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
errno = get_errno();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_create(bh_socket_t *sock, int tcp_or_udp)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
if (!sock) {
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
if (1 == tcp_or_udp) {
|
||||
if (ocall_socket(sock, AF_INET, SOCK_STREAM, IPPROTO_TCP)
|
||||
!= SGX_SUCCESS) {
|
||||
TRACE_OCALL_FAIL();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (0 == tcp_or_udp) {
|
||||
if (ocall_socket(sock, AF_INET, SOCK_DGRAM, 0) != SGX_SUCCESS) {
|
||||
TRACE_OCALL_FAIL();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (*sock == -1) {
|
||||
errno = get_errno();
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_inet_network(const char *cp, uint32 *out)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
if (!cp)
|
||||
return BHT_ERROR;
|
||||
|
||||
*out = inet_network(cp);
|
||||
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_listen(bh_socket_t socket, int max_client)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
int ret;
|
||||
|
||||
if (ocall_listen(&ret, socket, max_client) != SGX_SUCCESS) {
|
||||
TRACE_OCALL_FAIL();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
errno = get_errno();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
int ret;
|
||||
|
||||
if (ocall_recv(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
errno = get_errno();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
int ret;
|
||||
|
||||
if (ocall_send(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == -1)
|
||||
errno = get_errno();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
os_socket_shutdown(bh_socket_t socket)
|
||||
{
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
return shutdown(socket, O_RDWR);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,11 +14,12 @@ extern "C" {
|
|||
|
||||
#define SOL_SOCKET 1
|
||||
|
||||
#define SO_TYPE 3
|
||||
#define SO_LINGER 13
|
||||
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
|
||||
#define SO_TYPE 3
|
||||
|
||||
#define MSG_OOB 0x0001
|
||||
#define MSG_PEEK 0x0002
|
||||
#define MSG_DONTROUTE 0x0004
|
||||
|
@ -44,6 +45,16 @@ extern "C" {
|
|||
#define SHUT_WR 1
|
||||
#define SHUT_RDWR 2
|
||||
|
||||
/* Address families. */
|
||||
#define AF_INET 2 /* IP protocol family. */
|
||||
|
||||
/* Standard well-defined IP protocols. */
|
||||
#define IPPROTO_TCP 6 /* Transmission Control Protocol. */
|
||||
|
||||
/* Types of sockets. */
|
||||
#define SOCK_DGRAM \
|
||||
2 /* Connectionless, unreliable datagrams of fixed maximum length. */
|
||||
|
||||
struct msghdr {
|
||||
void *msg_name;
|
||||
socklen_t msg_namelen;
|
||||
|
@ -54,6 +65,36 @@ struct msghdr {
|
|||
int msg_flags;
|
||||
};
|
||||
|
||||
/* Internet address. */
|
||||
struct in_addr {
|
||||
uint32_t s_addr;
|
||||
};
|
||||
typedef struct in_addr in_addr_t;
|
||||
|
||||
/* Structure describing an Internet socket address. */
|
||||
#define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */
|
||||
struct sockaddr_in {
|
||||
uint16_t sin_family;
|
||||
uint16_t sin_port; /* Port number. */
|
||||
struct in_addr sin_addr; /* Internet address. */
|
||||
|
||||
/* Pad to size of `struct sockaddr'. */
|
||||
unsigned char__pad[__SOCK_SIZE__ - sizeof(uint16_t) - sizeof(uint16_t)
|
||||
- sizeof(struct in_addr)];
|
||||
};
|
||||
|
||||
/* Structure used to manipulate the SO_LINGER option. */
|
||||
struct linger {
|
||||
int l_onoff; /* Nonzero to linger on close. */
|
||||
int l_linger; /* Time to linger. */
|
||||
};
|
||||
|
||||
/* Structure describing a generic socket address. */
|
||||
struct sockaddr {
|
||||
unsigned short int sa_family; /* Common data: address family and length. */
|
||||
char sa_data[14]; /* Address data. */
|
||||
};
|
||||
|
||||
int
|
||||
socket(int domain, int type, int protocol);
|
||||
|
||||
|
|
|
@ -118,19 +118,34 @@ enclave {
|
|||
int ocall_pthread_rwlock_unlock([user_check]void *rwlock);
|
||||
|
||||
int ocall_get_errno();
|
||||
int ocall_socket(int domain, int type, int protocol);
|
||||
|
||||
/* sockets */
|
||||
int ocall_accept(int sockfd, [in, size=addr_size]void *addr,
|
||||
[in, size=4] uint32_t *addrlen, uint32_t addr_size);
|
||||
int ocall_bind(int sockfd, [in, size=addrlen]const void *addr,
|
||||
uint32_t addrlen);
|
||||
int ocall_connect(int sockfd, [in, size=addrlen]void *addr, uint32_t addrlen);
|
||||
int ocall_getsockname(int sockfd, [in, size=addr_size]void *addr,
|
||||
[in, out, size=4]uint32_t *addrlen, uint32_t addr_size);
|
||||
int ocall_getsockopt(int sockfd, int level, int optname,
|
||||
[out, size=val_buf_size]void *val_buf,
|
||||
unsigned int val_buf_size,
|
||||
[in, out, size=4]void *len_buf);
|
||||
ssize_t ocall_sendmsg(int sockfd,
|
||||
[in, size=msg_buf_size]void *msg_buf,
|
||||
unsigned int msg_buf_size,
|
||||
int flags);
|
||||
int ocall_listen(int sockfd, int backlog);
|
||||
int ocall_recv(int sockfd, [out, size=len]void *buf, size_t len, int flags);
|
||||
ssize_t ocall_recvmsg(int sockfd,
|
||||
[in, out, size=msg_buf_size]void *msg_buf,
|
||||
unsigned int msg_buf_size,
|
||||
int flags);
|
||||
int ocall_send(int sockfd, [in, size=len]const void *buf, size_t len, int flags);
|
||||
ssize_t ocall_sendmsg(int sockfd,
|
||||
[in, size=msg_buf_size]void *msg_buf,
|
||||
unsigned int msg_buf_size,
|
||||
int flags);
|
||||
int ocall_setsockopt(int sockfd, int level, int optname,
|
||||
[in, size=optlen]void *optval,
|
||||
unsigned int optlen);
|
||||
int ocall_shutdown(int sockfd, int how);
|
||||
int ocall_socket(int domain, int type, int protocol);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <sys/socket.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int
|
||||
ocall_socket(int domain, int type, int protocol)
|
||||
|
@ -72,4 +74,53 @@ int
|
|||
ocall_shutdown(int sockfd, int how)
|
||||
{
|
||||
return shutdown(sockfd, how);
|
||||
}
|
||||
|
||||
int
|
||||
ocall_setsockopt(int sockfd, int level, int optname, void *optval,
|
||||
unsigned int optlen)
|
||||
{
|
||||
return setsockopt(sockfd, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
int
|
||||
ocall_bind(int sockfd, const void *addr, uint32_t addrlen)
|
||||
{
|
||||
return bind(sockfd, (const struct sockaddr *)addr, addrlen);
|
||||
}
|
||||
|
||||
int
|
||||
ocall_getsockname(int sockfd, void *addr, uint32_t *addrlen, uint32_t addr_size)
|
||||
{
|
||||
return getsockname(sockfd, (struct sockaddr *)addr, addrlen);
|
||||
}
|
||||
|
||||
int
|
||||
ocall_listen(int sockfd, int backlog)
|
||||
{
|
||||
return listen(sockfd, backlog);
|
||||
}
|
||||
|
||||
int
|
||||
ocall_accept(int sockfd, void *addr, uint32_t *addrlen, uint32_t addr_size)
|
||||
{
|
||||
return accept(sockfd, (struct sockaddr *)addr, addrlen);
|
||||
}
|
||||
|
||||
int
|
||||
ocall_recv(int sockfd, void *buf, size_t len, int flags)
|
||||
{
|
||||
return recv(sockfd, buf, len, flags);
|
||||
}
|
||||
|
||||
int
|
||||
ocall_send(int sockfd, const void *buf, size_t len, int flags)
|
||||
{
|
||||
return send(sockfd, buf, len, flags);
|
||||
}
|
||||
|
||||
int
|
||||
ocall_connect(int sockfd, void *addr, uint32_t addrlen)
|
||||
{
|
||||
return connect(sockfd, (const struct sockaddr *)addr, addrlen);
|
||||
}
|
|
@ -10,7 +10,7 @@ and `socket()`. Users can call those functions in WebAssembly code directly.
|
|||
Those WebAssembly socket calls will be dispatched to the imported
|
||||
functions and eventually will be implemented by host socket APIs.
|
||||
|
||||
This document introduces a way to support _Berkeley/Posix Socket APIs_ in
|
||||
This document introduces a way to support the _Berkeley/POSIX Socket API_ in
|
||||
WebAssembly code.
|
||||
|
||||
## Patch the native code
|
||||
|
@ -24,7 +24,7 @@ native source code.
|
|||
#endif
|
||||
```
|
||||
|
||||
`__wasi__` is a Marco defined by WASI. The host compiler will not enable it.
|
||||
`__wasi__` is a macro defined by WASI. The host compiler will not enable it.
|
||||
|
||||
## CMake files
|
||||
|
||||
|
@ -57,10 +57,25 @@ 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 WebAssebmly application may need to `bind()` or `connect()` should be announced first. Every IP address should be in CIRD notation.
|
||||
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 CIRD notation.
|
||||
|
||||
```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.
|
||||
|
||||
## Intel SGX support
|
||||
|
||||
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`.
|
||||
|
||||
```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 the compilation of the Wasm applications and [_iwasm_ for Intel SGX](../product-mini/platforms/linux-sgx) for the Wasm runtime.
|
|
@ -227,6 +227,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= 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");
|
||||
printf(" --max-threads=n Set maximum thread number per cluster, default is 4\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -550,9 +554,10 @@ app_instance_func(void *wasm_module_inst, const char *func_name, int app_argc,
|
|||
static bool
|
||||
set_wasi_args(void *wasm_module, const char **dir_list, uint32_t dir_list_size,
|
||||
const char **env_list, uint32_t env_list_size, int stdinfd,
|
||||
int stdoutfd, int stderrfd, char **argv, uint32_t argc)
|
||||
int stdoutfd, int stderrfd, char **argv, uint32_t argc,
|
||||
const char **addr_pool, uint32_t addr_pool_size)
|
||||
{
|
||||
uint64_t ecall_args[10];
|
||||
uint64_t ecall_args[12];
|
||||
|
||||
ecall_args[0] = (uint64_t)(uintptr_t)wasm_module;
|
||||
ecall_args[1] = (uint64_t)(uintptr_t)dir_list;
|
||||
|
@ -564,9 +569,11 @@ set_wasi_args(void *wasm_module, const char **dir_list, uint32_t dir_list_size,
|
|||
ecall_args[7] = stderrfd;
|
||||
ecall_args[8] = (uint64_t)(uintptr_t)argv;
|
||||
ecall_args[9] = argc;
|
||||
ecall_args[10] = (uint64_t)(uintptr_t)addr_pool;
|
||||
ecall_args[11] = addr_pool_size;
|
||||
if (SGX_SUCCESS
|
||||
!= ecall_handle_command(g_eid, CMD_SET_WASI_ARGS, (uint8_t *)ecall_args,
|
||||
sizeof(uint64_t) * 10)) {
|
||||
sizeof(uint64_t) * 12)) {
|
||||
printf("Call ecall_handle_command() failed.\n");
|
||||
}
|
||||
|
||||
|
@ -590,6 +597,8 @@ main(int argc, char *argv[])
|
|||
uint32_t dir_list_size = 0;
|
||||
const char *env_list[8] = { NULL };
|
||||
uint32_t env_list_size = 0;
|
||||
const char *addr_pool[8] = { NULL };
|
||||
uint32_t addr_pool_size = 0;
|
||||
uint32_t max_thread_num = 4;
|
||||
|
||||
if (enclave_init(&g_eid) < 0) {
|
||||
|
@ -666,6 +675,26 @@ main(int argc, char *argv[])
|
|||
return print_help();
|
||||
}
|
||||
}
|
||||
/* TODO: parse the configuration file via --addr-pool-file */
|
||||
else if (!strncmp(argv[0], "--addr-pool=", strlen("--addr-pool="))) {
|
||||
/* like: --addr-pool=100.200.244.255/30 */
|
||||
char *token = NULL;
|
||||
|
||||
if ('\0' == argv[0][12])
|
||||
return print_help();
|
||||
|
||||
token = strtok(argv[0] + strlen("--addr-pool="), ",");
|
||||
while (token) {
|
||||
if (addr_pool_size >= sizeof(addr_pool) / sizeof(char *)) {
|
||||
printf("Only allow max address number %d\n",
|
||||
(int)(sizeof(addr_pool) / sizeof(char *)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
addr_pool[addr_pool_size++] = token;
|
||||
token = strtok(NULL, ";");
|
||||
}
|
||||
}
|
||||
else if (!strncmp(argv[0], "--max-threads=", 14)) {
|
||||
if (argv[0][14] == '\0')
|
||||
return print_help();
|
||||
|
@ -705,7 +734,8 @@ main(int argc, char *argv[])
|
|||
|
||||
/* Set wasi arguments */
|
||||
if (!set_wasi_args(wasm_module, dir_list, dir_list_size, env_list,
|
||||
env_list_size, 0, 1, 2, argv, argc)) {
|
||||
env_list_size, 0, 1, 2, argv, argc, addr_pool,
|
||||
addr_pool_size)) {
|
||||
printf("%s\n", "set wasi arguments failed.\n");
|
||||
goto fail3;
|
||||
}
|
||||
|
@ -771,6 +801,8 @@ wamr_pal_create_process(struct wamr_pal_create_process_args *args)
|
|||
uint32_t dir_list_size = 0;
|
||||
const char *env_list[8] = { NULL };
|
||||
uint32_t env_list_size = 0;
|
||||
const char *addr_pool[8] = { NULL };
|
||||
uint32_t addr_pool_size = 0;
|
||||
uint32_t max_thread_num = 4;
|
||||
char *wasm_files[16];
|
||||
void *wasm_module_inst[16];
|
||||
|
@ -845,7 +877,7 @@ wamr_pal_create_process(struct wamr_pal_create_process_args *args)
|
|||
/* Set wasi arguments */
|
||||
if (!set_wasi_args(wasm_module, dir_list, dir_list_size, env_list,
|
||||
env_list_size, stdinfd, stdoutfd, stderrfd, argv,
|
||||
argc)) {
|
||||
argc, addr_pool, addr_pool_size)) {
|
||||
printf("%s\n", "set wasi arguments failed.\n");
|
||||
unload_module(wasm_module);
|
||||
free(wasm_file_buf);
|
||||
|
|
|
@ -50,6 +50,8 @@ typedef struct EnclaveModule {
|
|||
uint32 wasi_dir_list_size;
|
||||
char **wasi_env_list;
|
||||
uint32 wasi_env_list_size;
|
||||
char **wasi_addr_pool_list;
|
||||
uint32 wasi_addr_pool_list_size;
|
||||
char **wasi_argv;
|
||||
uint32 wasi_argc;
|
||||
bool is_xip_file;
|
||||
|
@ -407,6 +409,8 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
|
|||
char **wasi_argv = *(char ***)args++;
|
||||
char *p, *p1;
|
||||
uint32 wasi_argc = *(uint32 *)args++;
|
||||
char **addr_pool_list = *(char ***)args++;
|
||||
uint32 addr_pool_list_size = *(uint32 *)args++;
|
||||
uint64 total_size = 0;
|
||||
int32 i, str_len;
|
||||
|
||||
|
@ -414,6 +418,7 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
|
|||
|
||||
total_size += sizeof(char *) * (uint64)dir_list_size
|
||||
+ sizeof(char *) * (uint64)env_list_size
|
||||
+ sizeof(char *) * (uint64)addr_pool_list_size
|
||||
+ sizeof(char *) * (uint64)wasi_argc;
|
||||
|
||||
for (i = 0; i < dir_list_size; i++) {
|
||||
|
@ -424,6 +429,10 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
|
|||
total_size += strlen(env_list[i]) + 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < addr_pool_list_size; i++) {
|
||||
total_size += strlen(addr_pool_list[i]) + 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < wasi_argc; i++) {
|
||||
total_size += strlen(wasi_argv[i]) + 1;
|
||||
}
|
||||
|
@ -436,7 +445,7 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
|
|||
}
|
||||
|
||||
p1 = p + sizeof(char *) * dir_list_size + sizeof(char *) * env_list_size
|
||||
+ sizeof(char *) * wasi_argc;
|
||||
+ sizeof(char *) * addr_pool_list_size + sizeof(char *) * wasi_argc;
|
||||
|
||||
if (dir_list_size > 0) {
|
||||
enclave_module->wasi_dir_list = (char **)p;
|
||||
|
@ -462,6 +471,18 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
|
|||
p += sizeof(char *) * env_list_size;
|
||||
}
|
||||
|
||||
if (addr_pool_list_size > 0) {
|
||||
enclave_module->wasi_addr_pool_list = (char **)p;
|
||||
enclave_module->wasi_addr_pool_list_size = addr_pool_list_size;
|
||||
for (i = 0; i < addr_pool_list_size; i++) {
|
||||
enclave_module->wasi_addr_pool_list[i] = p1;
|
||||
str_len = strlen(addr_pool_list[i]);
|
||||
bh_memcpy_s(p1, str_len + 1, addr_pool_list[i], str_len + 1);
|
||||
p1 += str_len + 1;
|
||||
}
|
||||
p += sizeof(char *) * addr_pool_list_size;
|
||||
}
|
||||
|
||||
if (wasi_argc > 0) {
|
||||
enclave_module->wasi_argv = (char **)p;
|
||||
enclave_module->wasi_argc = wasi_argc;
|
||||
|
@ -481,6 +502,11 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
|
|||
(stdinfd != -1) ? stdinfd : 0, (stdoutfd != -1) ? stdoutfd : 1,
|
||||
(stderrfd != -1) ? stderrfd : 2);
|
||||
|
||||
wasm_runtime_set_wasi_addr_pool(
|
||||
enclave_module->module,
|
||||
(const char **)enclave_module->wasi_addr_pool_list,
|
||||
addr_pool_list_size);
|
||||
|
||||
*args_org = true;
|
||||
}
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue
Block a user