Merge dev/socket into main (#1393)

Implement more socket APIs, refer to #1336 and below PRs:
- Implement wasi_addr_resolve function (#1319)
- Fix socket-api byte order issue when host/network order are the same (#1327)
- Enhance sock_addr_local syscall (#1320)
- Implement sock_addr_remote syscall (#1360)
- Add support for IPv6 in WAMR (#1411)
- Implement ns lookup allowlist (#1420)
- Implement sock_send_to and sock_recv_from system calls (#1457)
- Added http downloader and multicast socket options (#1467)
- Fix `bind()` calls to receive the correct size of `sockaddr` structure (#1490)
- Assert on correct parameters (#1505)
- Copy only received bytes from socket recv buffer into the app buffer (#1497)

Co-authored-by: Marcin Kolny <mkolny@amazon.com>
Co-authored-by: Marcin Kolny <marcin.kolny@gmail.com>
Co-authored-by: Callum Macmillan <callumimacmillan@gmail.com>
This commit is contained in:
Wenyong Huang
2022-09-22 21:46:14 +08:00
committed by GitHub
parent 32d2d16908
commit 78b5c5b484
31 changed files with 6345 additions and 438 deletions

View File

@ -4,6 +4,7 @@
*/
#include "platform_api_vmcore.h"
#include "platform_api_extension.h"
#ifndef SGX_DISABLE_WASI
@ -91,7 +92,7 @@ swap16(uint8 *pData)
*(pData + 1) = value;
}
static uint32
uint32
htonl(uint32 value)
{
uint32 ret;
@ -104,13 +105,13 @@ htonl(uint32 value)
return value;
}
static uint32
uint32
ntohl(uint32 value)
{
return htonl(value);
}
static uint16
uint16
htons(uint16 value)
{
uint16 ret;
@ -131,57 +132,96 @@ ntohs(uint16 value)
/* Coming from musl, under MIT license */
static int
__inet_aton(const char *s0, struct in_addr *dest)
hexval(unsigned c)
{
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;
if (c - '0' < 10)
return c - '0';
c |= 32;
if (c - 'a' < 6)
return c - 'a' + 10;
return -1;
}
/* Coming from musl, under MIT license */
static int
inet_addr(const char *p)
inet_pton(int af, const char *restrict s, void *restrict a0)
{
struct in_addr a;
if (!__inet_aton(p, &a))
uint16_t ip[8];
unsigned char *a = a0;
int i, j, v, d, brk = -1, need_v4 = 0;
if (af == AF_INET) {
for (i = 0; i < 4; i++) {
for (v = j = 0; j < 3 && isdigit(s[j]); j++)
v = 10 * v + s[j] - '0';
if (j == 0 || (j > 1 && s[0] == '0') || v > 255)
return 0;
a[i] = v;
if (s[j] == 0 && i == 3)
return 1;
if (s[j] != '.')
return 0;
s += j + 1;
}
return 0;
}
else if (af != AF_INET6) {
errno = EAFNOSUPPORT;
return -1;
return a.s_addr;
}
if (*s == ':' && *++s != ':')
return 0;
for (i = 0;; i++) {
if (s[0] == ':' && brk < 0) {
brk = i;
ip[i & 7] = 0;
if (!*++s)
break;
if (i == 7)
return 0;
continue;
}
for (v = j = 0; j < 4 && (d = hexval(s[j])) >= 0; j++)
v = 16 * v + d;
if (j == 0)
return 0;
ip[i & 7] = v;
if (!s[j] && (brk >= 0 || i == 7))
break;
if (i == 7)
return 0;
if (s[j] != ':') {
if (s[j] != '.' || (i < 6 && brk < 0))
return 0;
need_v4 = 1;
i++;
break;
}
s += j + 1;
}
if (brk >= 0) {
memmove(ip + brk + 7 - i, ip + brk, 2 * (i + 1 - brk));
for (j = 0; j < 7 - i; j++)
ip[brk + j] = 0;
}
for (j = 0; j < 8; j++) {
*a++ = ip[j] >> 8;
*a++ = ip[j];
}
if (need_v4 && inet_pton(AF_INET, (void *)s, a - 4) <= 0)
return 0;
return 1;
}
static int
inet_network(const char *p)
inet_addr(const char *p)
{
return ntohl(inet_addr(p));
struct in_addr a;
if (!inet_pton(AF_INET, p, &a))
return -1;
return a.s_addr;
}
/** In-enclave implementation of POSIX functions end **/
@ -527,21 +567,30 @@ os_socket_connect(bh_socket_t socket, const char *addr, int port)
}
int
os_socket_create(bh_socket_t *sock, int tcp_or_udp)
os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
{
int af;
if (!sock) {
return BHT_ERROR;
}
if (1 == tcp_or_udp) {
if (ocall_socket(sock, AF_INET, SOCK_STREAM, IPPROTO_TCP)
!= SGX_SUCCESS) {
if (is_ipv4) {
af = AF_INET;
}
else {
errno = ENOSYS;
return BHT_ERROR;
}
if (is_tcp) {
if (ocall_socket(sock, af, 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) {
else {
if (ocall_socket(sock, af, SOCK_DGRAM, 0) != SGX_SUCCESS) {
TRACE_OCALL_FAIL();
return -1;
}
@ -556,12 +605,26 @@ os_socket_create(bh_socket_t *sock, int tcp_or_udp)
}
int
os_socket_inet_network(const char *cp, uint32 *out)
os_socket_inet_network(bool is_ipv4, const char *cp, bh_ip_addr_buffer_t *out)
{
if (!cp)
return BHT_ERROR;
*out = inet_network(cp);
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;
}
@ -598,6 +661,15 @@ os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
return ret;
}
int
os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
bh_sockaddr_t *src_addr)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
{
@ -614,10 +686,354 @@ os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
return ret;
}
int
os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
int flags, const bh_sockaddr_t *dest_addr)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_shutdown(bh_socket_t socket)
{
return shutdown(socket, O_RDWR);
}
int
os_socket_addr_resolve(const char *host, const char *service,
uint8_t *hint_is_tcp, uint8_t *hint_is_ipv4,
bh_addr_info_t *addr_info, size_t addr_info_size,
size_t *max_info_size)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32 time_s)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32 *time_s)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32 time_s)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32 *time_s)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool *is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_ip_add_membership(bh_socket_t socket,
bh_ip_addr_buffer_t *imr_multiaddr,
uint32_t imr_interface, bool is_ipv6)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_ip_drop_membership(bh_socket_t socket,
bh_ip_addr_buffer_t *imr_multiaddr,
uint32_t imr_interface, bool is_ipv6)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_ipv6_only(bh_socket_t socket, bool option)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_ipv6_only(bh_socket_t socket, bool *option)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_set_broadcast(bh_socket_t socket, bool is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
int
os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled)
{
errno = ENOSYS;
return BHT_ERROR;
}
#endif

View File

@ -46,7 +46,8 @@ extern "C" {
#define SHUT_RDWR 2
/* Address families. */
#define AF_INET 2 /* IP protocol family. */
#define AF_INET 2 /* IP protocol family. */
#define AF_INET6 10 /* IP version 6. */
/* Standard well-defined IP protocols. */
#define IPPROTO_TCP 6 /* Transmission Control Protocol. */
@ -95,6 +96,15 @@ struct sockaddr {
char sa_data[14]; /* Address data. */
};
uint32_t
ntohl(uint32_t value);
uint32_t
htonl(uint32_t value);
uint16_t
htons(uint16_t value);
int
socket(int domain, int type, int protocol);