summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket')
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h999
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake9
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c1009
-rwxr-xr-xfluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/build.sh25
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/nslookup.c49
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/tcp_udp.c193
6 files changed, 2284 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h
new file mode 100644
index 000000000..c9a07eb72
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/inc/wasi_socket_ext.h
@@ -0,0 +1,999 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _WASI_SOCKET_EXT_H_
+#define _WASI_SOCKET_EXT_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+/*Be a part of <wasi/api.h>*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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
+ Example:
+ IP Address: 127.0.0.1
+ Structure: {n0: 127, n1: 0, n2: 0, n3: 1}
+*/
+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; /* host byte order */
+} __wasi_addr_ip4_port_t;
+
+/*
+ n0:n1:n2:n3:h0:h1:h2:h3, each 16bit value uses host byte order
+ Example (little-endian system)
+ IP Address fe80::3ba2:893b:4be0:e3dd
+ Structure: {
+ n0: 0xfe80, n1:0x0, n2: 0x0, n3: 0x0,
+ h0: 0x3ba2, h1: 0x893b, h2: 0x4be0, h3: 0xe3dd
+ }
+*/
+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; /* host byte order */
+} __wasi_addr_ip6_port_t;
+
+typedef struct __wasi_addr_ip_t {
+ __wasi_addr_type_t kind;
+ union {
+ __wasi_addr_ip4_t ip4;
+ __wasi_addr_ip6_t ip6;
+ } addr;
+} __wasi_addr_ip_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;
+
+typedef struct __wasi_addr_info_t {
+ __wasi_addr_t addr;
+ __wasi_sock_type_t type;
+} __wasi_addr_info_t;
+
+typedef struct __wasi_addr_info_hints_t {
+ __wasi_sock_type_t type;
+ __wasi_address_family_t family;
+ // this is to workaround lack of optional parameters
+ uint8_t hints_enabled;
+} __wasi_addr_info_hints_t;
+
+#ifdef __wasi__
+/**
+ * Reimplement below POSIX APIs with __wasi_sock_XXX functions.
+ *
+ * Keep sync with
+ * <sys/socket.h>
+ * <sys/types.h>
+ */
+#define SO_REUSEADDR 2
+#define SO_BROADCAST 6
+#define SO_SNDBUF 7
+#define SO_RCVBUF 8
+#define SO_KEEPALIVE 9
+#define SO_LINGER 13
+#define SO_REUSEPORT 15
+#define SO_RCVTIMEO 20
+#define SO_SNDTIMEO 21
+
+#define TCP_NODELAY 1
+#define TCP_KEEPIDLE 4
+#define TCP_KEEPINTVL 5
+#define TCP_QUICKACK 12
+#define TCP_FASTOPEN_CONNECT 30
+
+#define IP_TTL 2
+#define IP_MULTICAST_TTL 33
+#define IP_MULTICAST_LOOP 34
+#define IP_ADD_MEMBERSHIP 35
+#define IP_DROP_MEMBERSHIP 36
+
+#define IPV6_MULTICAST_LOOP 19
+#define IPV6_JOIN_GROUP 20
+#define IPV6_LEAVE_GROUP 21
+#define IPV6_V6ONLY 26
+
+struct addrinfo {
+ int ai_flags; /* Input flags. */
+ int ai_family; /* Protocol family for socket. */
+ int ai_socktype; /* Socket type. */
+ int ai_protocol; /* Protocol for socket. */
+ socklen_t ai_addrlen; /* Length of socket address. */
+ struct sockaddr *ai_addr; /* Socket address for socket. */
+ char *ai_canonname; /* Canonical name for service location. */
+ struct addrinfo *ai_next; /* Pointer to next in list. */
+};
+
+#ifndef __WASI_RIGHTS_SOCK_ACCEPT
+int
+accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
+#endif
+
+int
+bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+
+int
+connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
+
+int
+listen(int sockfd, int backlog);
+
+ssize_t
+recvmsg(int sockfd, struct msghdr *msg, int flags);
+
+ssize_t
+sendmsg(int sockfd, const struct msghdr *msg, int flags);
+
+ssize_t
+sendto(int sockfd, const void *buf, size_t len, int flags,
+ const struct sockaddr *dest_addr, socklen_t addrlen);
+
+ssize_t
+recvfrom(int sockfd, void *buf, size_t len, int flags,
+ struct sockaddr *src_addr, socklen_t *addrlen);
+
+int
+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);
+
+int
+getsockopt(int sockfd, int level, int optname, void *__restrict optval,
+ socklen_t *__restrict optlen);
+
+int
+setsockopt(int sockfd, int level, int optname, const void *optval,
+ socklen_t optlen);
+
+int
+getaddrinfo(const char *node, const char *service, const struct addrinfo *hints,
+ struct addrinfo **res);
+
+void
+freeaddrinfo(struct addrinfo *res);
+#endif
+
+/**
+ * __wasi_sock_accept was introduced in wasi-sdk v15. To
+ * temporarily maintain backward compatibility with the old
+ * wasi-sdk, we explicitly add that implementation here so it works
+ * with older versions of the SDK.
+ */
+#ifndef __WASI_RIGHTS_SOCK_ACCEPT
+/**
+ * Accept a connection on a socket
+ * Note: This is similar to `accept`
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_accept(int32_t arg0, int32_t arg1,
+ int32_t arg2)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_accept")));
+
+static inline __wasi_errno_t
+__wasi_sock_accept(__wasi_fd_t fd, __wasi_fdflags_t flags, __wasi_fd_t *fd_new)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_accept(
+ (int32_t)fd, (int32_t)flags, (int32_t)fd_new);
+}
+#endif
+
+/**
+ * Returns the local address to which the socket is bound.
+ *
+ * Note: This is similar to `getsockname` in POSIX
+ *
+ * When successful, the contents of the output buffer consist of an IP address,
+ * either IP4 or IP6.
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_addr_local(int32_t arg0, int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_addr_local")));
+
+static inline __wasi_errno_t
+__wasi_sock_addr_local(__wasi_fd_t fd, __wasi_addr_t *addr)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_addr_local(
+ (int32_t)fd, (int32_t)addr);
+}
+
+/**
+ * Returns the remote address to which the socket is connected to.
+ *
+ * Note: This is similar to `getpeername` in POSIX
+ *
+ * When successful, the contents of the output buffer consist of an IP address,
+ * either IP4 or IP6.
+ */
+int32_t
+__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, __wasi_addr_t *addr)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_addr_remote(
+ (int32_t)fd, (int32_t)addr);
+}
+
+/**
+ * Resolve a hostname and a service to one or more IP addresses. Service is
+ * optional and you can pass empty string in most cases, it is used as a hint
+ * for protocol.
+ *
+ * Note: This is similar to `getaddrinfo` in POSIX
+ *
+ * When successful, the contents of the output buffer consist of a sequence of
+ * IPv4 and/or IPv6 addresses. Each address entry consists of a wasi_addr_t
+ * object.
+ *
+ * This function fills the output buffer as much as possible, truncating the
+ * entries that didn't fit into the buffer. A number of available addresses
+ * will be returned through the last parameter.
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_addr_resolve(int32_t arg0, int32_t arg1,
+ int32_t arg2, int32_t arg3,
+ int32_t arg4, int32_t arg5)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_addr_resolve")));
+
+static inline __wasi_errno_t
+__wasi_sock_addr_resolve(const char *host, const char *service,
+ __wasi_addr_info_hints_t *hints,
+ __wasi_addr_info_t *addr_info,
+ __wasi_size_t addr_info_size,
+ __wasi_size_t *max_info_size)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_addr_resolve(
+ (int32_t)host, (int32_t)service, (int32_t)hints, (int32_t)addr_info,
+ (int32_t)addr_info_size, (int32_t)max_info_size);
+}
+
+/**
+ * Bind a socket
+ * Note: This is similar to `bind` in POSIX using PF_INET
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_bind(int32_t arg0, int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_bind")));
+
+static inline __wasi_errno_t
+__wasi_sock_bind(__wasi_fd_t fd, __wasi_addr_t *addr)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_bind(
+ (int32_t)fd, (int32_t)addr);
+}
+
+/**
+ * Send data to a specific target
+ * Note: This is similar to `sendto` in POSIX
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_send_to(int32_t arg0, int32_t arg1,
+ int32_t arg2, int32_t arg3,
+ int32_t arg4, int32_t arg5)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_send_to")));
+
+static inline __wasi_errno_t
+__wasi_sock_send_to(__wasi_fd_t fd, const __wasi_ciovec_t *si_data,
+ uint32_t si_data_len, __wasi_siflags_t si_flags,
+ const __wasi_addr_t *dest_addr, uint32_t *so_data_len)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_send_to(
+ (int32_t)fd, (int32_t)si_data, (int32_t)si_data_len, (int32_t)si_flags,
+ (uint32_t)dest_addr, (uint32_t)so_data_len);
+}
+
+/**
+ * Receives data from a socket
+ * Note: This is similar to `recvfrom` in POSIX
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_recv_from(int32_t arg0, int32_t arg1,
+ int32_t arg2, int32_t arg3,
+ int32_t arg4, int32_t arg5)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_recv_from")));
+
+static inline __wasi_errno_t
+__wasi_sock_recv_from(__wasi_fd_t fd, __wasi_ciovec_t *ri_data,
+ uint32_t ri_data_len, __wasi_riflags_t ri_flags,
+ __wasi_addr_t *src_addr, uint32_t *ro_data_len)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_recv_from(
+ (int32_t)fd, (int32_t)ri_data, (int32_t)ri_data_len, (int32_t)ri_flags,
+ (uint32_t)src_addr, (uint32_t)ro_data_len);
+}
+
+/**
+ * Close a socket (this is an alias for `fd_close`)
+ * Note: This is similar to `close` in POSIX.
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_close(int32_t arg0)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_close")));
+
+static inline __wasi_errno_t
+__wasi_sock_close(__wasi_fd_t fd)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_close(
+ (int32_t)fd);
+}
+
+/**
+ * Initiate a connection on a socket to the specified address
+ * Note: This is similar to `connect` in POSIX
+ */
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_connect(int32_t arg0, int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_connect")));
+
+static inline __wasi_errno_t
+__wasi_sock_connect(__wasi_fd_t fd, __wasi_addr_t *addr)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_connect(
+ (int32_t)fd, (int32_t)addr);
+}
+/**
+ * Retrieve the size of the receive buffer
+ * Note: This is similar to `getsockopt` in POSIX for SO_RCVBUF
+ */
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_recv_buf_size(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_recv_buf_size")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_recv_buf_size(__wasi_fd_t fd, __wasi_size_t *size)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_recv_buf_size((int32_t)fd,
+ (int32_t)size);
+}
+/**
+ * Retrieve status of address reuse on a socket
+ * Note: This is similar to `getsockopt` in POSIX for SO_REUSEADDR
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_reuse_addr(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_reuse_addr")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_reuse_addr(__wasi_fd_t fd, bool *reuse)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_reuse_addr((int32_t)fd,
+ (int32_t)reuse);
+}
+
+/**
+ * Retrieve status of port reuse on a socket
+ * Note: This is similar to `getsockopt` in POSIX for SO_REUSEPORT
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_reuse_port(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_reuse_port")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_reuse_port(__wasi_fd_t fd, bool *reuse)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_reuse_port((int32_t)fd,
+ (int32_t)reuse);
+}
+
+/**
+ * Retrieve the size of the send buffer
+ * Note: This is similar to `getsockopt` in POSIX for SO_SNDBUF
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_send_buf_size(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_send_buf_size")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_send_buf_size(__wasi_fd_t fd, __wasi_size_t *size)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_send_buf_size((int32_t)fd,
+ (int32_t)size);
+}
+
+/**
+ * Listen for connections on a socket
+ * Note: This is similar to `listen`
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_listen(int32_t arg0, int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_listen")));
+
+static inline __wasi_errno_t
+__wasi_sock_listen(__wasi_fd_t fd, __wasi_size_t backlog)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_listen(
+ (int32_t)fd, (int32_t)backlog);
+}
+
+/**
+ * Open a socket
+
+ * The first argument to this function is a handle to an
+ * address pool. The address pool determines what actions can
+ * be performed and at which addresses they can be performed to.
+
+ * The address pool cannot be re-assigned. You will need to close
+ * the socket and open a new one to use a different address pool.
+
+ * Note: This is similar to `socket` in POSIX using PF_INET
+ */
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_open(int32_t arg0, int32_t arg1,
+ int32_t arg2, int32_t arg3)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_open")));
+
+static inline __wasi_errno_t
+__wasi_sock_open(__wasi_fd_t fd, __wasi_address_family_t af,
+ __wasi_sock_type_t socktype, __wasi_fd_t *sockfd)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_open(
+ (int32_t)fd, (int32_t)af, (int32_t)socktype, (int32_t)sockfd);
+}
+
+/**
+ * Set size of receive buffer
+ * Note: This is similar to `setsockopt` in POSIX for SO_RCVBUF
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_recv_buf_size(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_recv_buf_size")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_recv_buf_size(__wasi_fd_t fd, __wasi_size_t size)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_recv_buf_size((int32_t)fd,
+ (int32_t)size);
+}
+
+/**
+ * Enable/disable address reuse on a socket
+ * Note: This is similar to `setsockopt` in POSIX for SO_REUSEADDR
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_reuse_addr(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_reuse_addr")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_reuse_addr(__wasi_fd_t fd, bool reuse)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_reuse_addr((int32_t)fd,
+ (int32_t)reuse);
+}
+
+/**
+ * Enable port reuse on a socket
+ * Note: This is similar to `setsockopt` in POSIX for SO_REUSEPORT
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_reuse_port(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_reuse_port")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_reuse_port(__wasi_fd_t fd, bool reuse)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_reuse_port((int32_t)fd,
+ (int32_t)reuse);
+}
+
+/**
+ * Set size of send buffer
+ * Note: This is similar to `setsockopt` in POSIX for SO_SNDBUF
+ */
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_send_buf_size(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_send_buf_size")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_send_buf_size(__wasi_fd_t fd, __wasi_size_t buf_len)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_send_buf_size(
+ (int32_t)fd, (int32_t)buf_len);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_recv_timeout(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_recv_timeout")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_recv_timeout(__wasi_fd_t fd, uint64_t *timeout_us)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_recv_timeout(
+ (int32_t)fd, (int32_t)timeout_us);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_recv_timeout(int32_t arg0,
+ int64_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_recv_timeout")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_recv_timeout(__wasi_fd_t fd, uint64_t timeout_us)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_recv_timeout(
+ (int32_t)fd, (int64_t)timeout_us);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_send_timeout(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_send_timeout")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_send_timeout(__wasi_fd_t fd, uint64_t *timeout_us)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_send_timeout(
+ (int32_t)fd, (int32_t)timeout_us);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_send_timeout(int32_t arg0,
+ int64_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_send_timeout")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_send_timeout(__wasi_fd_t fd, uint64_t timeout_us)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_send_timeout(
+ (int32_t)fd, (int64_t)timeout_us);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_keep_alive(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_keep_alive")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_keep_alive(__wasi_fd_t fd, bool option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_keep_alive((int32_t)fd,
+ (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_keep_alive(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_keep_alive")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_keep_alive(__wasi_fd_t fd, bool *option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_keep_alive((int32_t)fd,
+ (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_linger(int32_t arg0, int32_t arg1,
+ int32_t arg2)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_linger")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_linger(__wasi_fd_t fd, bool is_enabled, int linger_s)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_set_linger(
+ (int32_t)fd, (int32_t)is_enabled, (int32_t)linger_s);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_linger(int32_t arg0, int32_t arg1,
+ int32_t arg2)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_linger")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_linger(__wasi_fd_t fd, bool *is_enabled, int *linger_s)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_get_linger(
+ (int32_t)fd, (int32_t)is_enabled, (int32_t)linger_s);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_tcp_keep_idle(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_tcp_keep_idle")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_tcp_keep_idle(__wasi_fd_t fd, uint32_t time_s)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_tcp_keep_idle(
+ (int32_t)fd, (int32_t)time_s);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_tcp_keep_idle(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_tcp_keep_idle")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_tcp_keep_idle(__wasi_fd_t fd, uint32_t *time_s)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_tcp_keep_idle(
+ (int32_t)fd, (int32_t)time_s);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_tcp_keep_intvl(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_tcp_keep_intvl")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_tcp_keep_intvl(__wasi_fd_t fd, uint32_t time_s)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_tcp_keep_intvl(
+ (int32_t)fd, (int32_t)time_s);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_tcp_keep_intvl(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_tcp_keep_intvl")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_tcp_keep_intvl(__wasi_fd_t fd, uint32_t *time_s)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_tcp_keep_intvl(
+ (int32_t)fd, (int32_t)time_s);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_tcp_fastopen_connect(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_tcp_fastopen_connect")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_tcp_fastopen_connect(__wasi_fd_t fd, bool option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_tcp_fastopen_connect(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_tcp_fastopen_connect(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_tcp_fastopen_connect")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_tcp_fastopen_connect(__wasi_fd_t fd, bool *option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_tcp_fastopen_connect(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_ip_multicast_loop(int32_t arg0,
+ int32_t arg1,
+ int32_t arg2)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_ip_multicast_loop")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_ip_multicast_loop(__wasi_fd_t fd, bool ipv6, bool option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_ip_multicast_loop(
+ (int32_t)fd, (int32_t)ipv6, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_ip_multicast_loop(int32_t arg0,
+ int32_t arg1,
+ int32_t arg2)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_ip_multicast_loop")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_ip_multicast_loop(__wasi_fd_t fd, bool ipv6, bool *option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_ip_multicast_loop(
+ (int32_t)fd, (int32_t)ipv6, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_ip_multicast_ttl(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_ip_multicast_ttl")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_ip_multicast_ttl(__wasi_fd_t fd, uint8_t option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_ip_multicast_ttl(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_ip_multicast_ttl(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_ip_multicast_ttl")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_ip_multicast_ttl(__wasi_fd_t fd, uint8_t *option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_ip_multicast_ttl(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_ip_add_membership(int32_t arg0,
+ int32_t arg1,
+ int32_t arg2)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_ip_add_membership")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_ip_add_membership(__wasi_fd_t fd,
+ __wasi_addr_ip_t *imr_multiaddr,
+ uint32_t imr_interface)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_ip_add_membership(
+ (int32_t)fd, (int32_t)imr_multiaddr, (int32_t)imr_interface);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_ip_drop_membership(int32_t arg0,
+ int32_t arg1,
+ int32_t arg2)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_ip_drop_membership")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_ip_drop_membership(__wasi_fd_t fd,
+ __wasi_addr_ip_t *imr_multiaddr,
+ uint32_t imr_interface)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_ip_drop_membership(
+ (int32_t)fd, (int32_t)imr_multiaddr, (int32_t)imr_interface);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_broadcast(int32_t arg0, int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_broadcast")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_broadcast(__wasi_fd_t fd, bool option)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_set_broadcast(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_broadcast(int32_t arg0, int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_broadcast")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_broadcast(__wasi_fd_t fd, bool *option)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_get_broadcast(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_tcp_no_delay(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_tcp_no_delay")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_tcp_no_delay(__wasi_fd_t fd, bool option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_tcp_no_delay(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_tcp_no_delay(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_tcp_no_delay")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_tcp_no_delay(__wasi_fd_t fd, bool *option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_tcp_no_delay(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_tcp_quick_ack(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_tcp_quick_ack")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_tcp_quick_ack(__wasi_fd_t fd, bool option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_set_tcp_quick_ack(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_tcp_quick_ack(int32_t arg0,
+ int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_tcp_quick_ack")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_tcp_quick_ack(__wasi_fd_t fd, bool *option)
+{
+ return (__wasi_errno_t)
+ __imported_wasi_snapshot_preview1_sock_get_tcp_quick_ack(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_ip_ttl(int32_t arg0, int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_ip_ttl")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_ip_ttl(__wasi_fd_t fd, uint8_t option)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_set_ip_ttl(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_ip_ttl(int32_t arg0, int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_ip_ttl")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_ip_ttl(__wasi_fd_t fd, uint8_t *option)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_get_ip_ttl(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_set_ipv6_only(int32_t arg0, int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_set_ipv6_only")));
+
+static inline __wasi_errno_t
+__wasi_sock_set_ipv6_only(__wasi_fd_t fd, bool option)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_set_ipv6_only(
+ (int32_t)fd, (int32_t)option);
+}
+
+int32_t
+__imported_wasi_snapshot_preview1_sock_get_ipv6_only(int32_t arg0, int32_t arg1)
+ __attribute__((__import_module__("wasi_snapshot_preview1"),
+ __import_name__("sock_get_ipv6_only")));
+
+static inline __wasi_errno_t
+__wasi_sock_get_ipv6_only(__wasi_fd_t fd, bool *option)
+{
+ return (__wasi_errno_t)__imported_wasi_snapshot_preview1_sock_get_ipv6_only(
+ (int32_t)fd, (int32_t)option);
+}
+/**
+ * TODO: modify recv() and send()
+ * since don't want to re-compile the wasi-libc,
+ * we tend to keep original implentations of recv() and send().
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake
new file mode 100644
index 000000000..209b0c4c9
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/lib_socket_wasi.cmake
@@ -0,0 +1,9 @@
+# Copyright (C) 2019 Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+cmake_minimum_required (VERSION 2.8...3.16)
+
+project(socket_wasi_ext)
+
+add_library(${PROJECT_NAME} STATIC ${CMAKE_CURRENT_LIST_DIR}/src/wasi/wasi_socket_ext.c)
+target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/inc/)
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c
new file mode 100644
index 000000000..defbc6efe
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/src/wasi/wasi_socket_ext.c
@@ -0,0 +1,1009 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <wasi/api.h>
+#include <wasi_socket_ext.h>
+
+#define HANDLE_ERROR(error) \
+ if (error != __WASI_ERRNO_SUCCESS) { \
+ errno = error; \
+ return -1; \
+ }
+
+static void
+ipv4_addr_to_wasi_ip4_addr(uint32_t addr_num, __wasi_addr_ip4_t *out)
+{
+ addr_num = ntohl(addr_num);
+ out->n0 = (addr_num & 0xFF000000) >> 24;
+ out->n1 = (addr_num & 0x00FF0000) >> 16;
+ out->n2 = (addr_num & 0x0000FF00) >> 8;
+ out->n3 = (addr_num & 0x000000FF);
+}
+
+/* addr_num and port are in network order */
+static void
+ipv4_addr_to_wasi_addr(uint32_t addr_num, uint16_t port, __wasi_addr_t *out)
+{
+ out->kind = IPv4;
+ out->addr.ip4.port = ntohs(port);
+ ipv4_addr_to_wasi_ip4_addr(addr_num, &(out->addr.ip4.addr));
+}
+
+static void
+ipv6_addr_to_wasi_ipv6_addr(uint16_t *addr, __wasi_addr_ip6_t *out)
+{
+ out->n0 = ntohs(addr[0]);
+ out->n1 = ntohs(addr[1]);
+ out->n2 = ntohs(addr[2]);
+ out->n3 = ntohs(addr[3]);
+ out->h0 = ntohs(addr[4]);
+ out->h1 = ntohs(addr[5]);
+ out->h2 = ntohs(addr[6]);
+ out->h3 = ntohs(addr[7]);
+}
+
+static void
+ipv6_addr_to_wasi_addr(uint16_t *addr, uint16_t port, __wasi_addr_t *out)
+{
+ out->kind = IPv6;
+ out->addr.ip6.port = ntohs(port);
+ ipv6_addr_to_wasi_ipv6_addr(addr, &(out->addr.ip6.addr));
+}
+
+static __wasi_errno_t
+sockaddr_to_wasi_addr(const struct sockaddr *sock_addr, socklen_t addrlen,
+ __wasi_addr_t *wasi_addr)
+{
+ __wasi_errno_t ret = __WASI_ERRNO_SUCCESS;
+ if (AF_INET == sock_addr->sa_family) {
+ assert(sizeof(struct sockaddr_in) <= addrlen);
+
+ ipv4_addr_to_wasi_addr(
+ ((struct sockaddr_in *)sock_addr)->sin_addr.s_addr,
+ ((struct sockaddr_in *)sock_addr)->sin_port, wasi_addr);
+ }
+ else if (AF_INET6 == sock_addr->sa_family) {
+ assert(sizeof(struct sockaddr_in6) <= addrlen);
+ ipv6_addr_to_wasi_addr(
+ (uint16_t *)((struct sockaddr_in6 *)sock_addr)->sin6_addr.s6_addr,
+ ((struct sockaddr_in6 *)sock_addr)->sin6_port, wasi_addr);
+ }
+ else {
+ ret = __WASI_ERRNO_AFNOSUPPORT;
+ }
+
+ return ret;
+}
+
+static __wasi_errno_t
+wasi_addr_to_sockaddr(const __wasi_addr_t *wasi_addr,
+ struct sockaddr *sock_addr, socklen_t *addrlen)
+{
+ switch (wasi_addr->kind) {
+ case IPv4:
+ {
+ struct sockaddr_in sock_addr_in;
+ uint32_t s_addr;
+
+ memset(&sock_addr_in, 0, sizeof(sock_addr_in));
+
+ 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);
+ sock_addr_in.sin_port = htons(wasi_addr->addr.ip4.port);
+ memcpy(sock_addr, &sock_addr_in, sizeof(sock_addr_in));
+
+ *addrlen = sizeof(sock_addr_in);
+ break;
+ }
+ case IPv6:
+ {
+ struct sockaddr_in6 sock_addr_in6;
+
+ memset(&sock_addr_in6, 0, sizeof(sock_addr_in6));
+
+ uint16_t *addr_buf = (uint16_t *)sock_addr_in6.sin6_addr.s6_addr;
+
+ addr_buf[0] = htons(wasi_addr->addr.ip6.addr.n0);
+ addr_buf[1] = htons(wasi_addr->addr.ip6.addr.n1);
+ addr_buf[2] = htons(wasi_addr->addr.ip6.addr.n2);
+ addr_buf[3] = htons(wasi_addr->addr.ip6.addr.n3);
+ addr_buf[4] = htons(wasi_addr->addr.ip6.addr.h0);
+ addr_buf[5] = htons(wasi_addr->addr.ip6.addr.h1);
+ addr_buf[6] = htons(wasi_addr->addr.ip6.addr.h2);
+ addr_buf[7] = htons(wasi_addr->addr.ip6.addr.h3);
+
+ sock_addr_in6.sin6_family = AF_INET6;
+ sock_addr_in6.sin6_port = htons(wasi_addr->addr.ip6.port);
+ memcpy(sock_addr, &sock_addr_in6, sizeof(sock_addr_in6));
+
+ *addrlen = sizeof(sock_addr_in6);
+ break;
+ }
+ default:
+ return __WASI_ERRNO_AFNOSUPPORT;
+ }
+ return __WASI_ERRNO_SUCCESS;
+}
+
+int
+accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
+{
+ __wasi_addr_t wasi_addr;
+ __wasi_fd_t new_sockfd;
+ __wasi_errno_t error;
+
+ memset(&wasi_addr, 0, sizeof(wasi_addr));
+
+ error = __wasi_sock_accept(sockfd, 0, &new_sockfd);
+ HANDLE_ERROR(error)
+
+ if (getpeername(new_sockfd, addr, addrlen) == -1) {
+ return -1;
+ }
+
+ return new_sockfd;
+}
+
+int
+bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+{
+ __wasi_addr_t wasi_addr;
+ __wasi_errno_t error;
+
+ memset(&wasi_addr, 0, sizeof(wasi_addr));
+
+ error = sockaddr_to_wasi_addr(addr, addrlen, &wasi_addr);
+ HANDLE_ERROR(error)
+
+ error = __wasi_sock_bind(sockfd, &wasi_addr);
+ HANDLE_ERROR(error)
+
+ return __WASI_ERRNO_SUCCESS;
+}
+
+int
+connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
+{
+ __wasi_addr_t wasi_addr;
+ __wasi_errno_t error;
+
+ memset(&wasi_addr, 0, sizeof(wasi_addr));
+
+ if (NULL == addr) {
+ HANDLE_ERROR(__WASI_ERRNO_INVAL)
+ }
+
+ error = sockaddr_to_wasi_addr(addr, addrlen, &wasi_addr);
+ HANDLE_ERROR(error)
+
+ error = __wasi_sock_connect(sockfd, &wasi_addr);
+ HANDLE_ERROR(error)
+
+ return __WASI_ERRNO_SUCCESS;
+}
+
+int
+listen(int sockfd, int backlog)
+{
+ __wasi_errno_t error = __wasi_sock_listen(sockfd, backlog);
+ HANDLE_ERROR(error)
+ return __WASI_ERRNO_SUCCESS;
+}
+
+ssize_t
+recvmsg(int sockfd, struct msghdr *msg, int flags)
+{
+ // Prepare input parameters.
+ __wasi_iovec_t *ri_data = NULL;
+ size_t i = 0;
+ size_t ro_datalen = 0;
+ __wasi_roflags_t ro_flags = 0;
+
+ if (NULL == msg) {
+ HANDLE_ERROR(__WASI_ERRNO_INVAL)
+ }
+
+ // Validate flags.
+ if (flags != 0) {
+ HANDLE_ERROR(__WASI_ERRNO_NOPROTOOPT)
+ }
+
+ // __wasi_ciovec_t -> struct iovec
+ if (!(ri_data = (__wasi_iovec_t *)malloc(sizeof(__wasi_iovec_t)
+ * msg->msg_iovlen))) {
+ HANDLE_ERROR(__WASI_ERRNO_NOMEM)
+ }
+
+ for (i = 0; i < msg->msg_iovlen; i++) {
+ ri_data[i].buf = (uint8_t *)msg->msg_iov[i].iov_base;
+ ri_data[i].buf_len = msg->msg_iov[i].iov_len;
+ }
+
+ // Perform system call.
+ __wasi_errno_t error = __wasi_sock_recv(sockfd, ri_data, msg->msg_iovlen, 0,
+ &ro_datalen, &ro_flags);
+ free(ri_data);
+ HANDLE_ERROR(error)
+
+ return ro_datalen;
+}
+
+ssize_t
+sendmsg(int sockfd, const struct msghdr *msg, int flags)
+{
+ // Prepare input parameters.
+ __wasi_ciovec_t *si_data = NULL;
+ size_t so_datalen = 0;
+ size_t i = 0;
+
+ if (NULL == msg) {
+ HANDLE_ERROR(__WASI_ERRNO_INVAL)
+ }
+
+ // This implementation does not support any flags.
+ if (flags != 0) {
+ HANDLE_ERROR(__WASI_ERRNO_NOPROTOOPT)
+ }
+
+ // struct iovec -> __wasi_ciovec_t
+ if (!(si_data = (__wasi_ciovec_t *)malloc(sizeof(__wasi_ciovec_t)
+ * msg->msg_iovlen))) {
+ HANDLE_ERROR(__WASI_ERRNO_NOMEM)
+ }
+
+ for (i = 0; i < msg->msg_iovlen; i++) {
+ si_data[i].buf = (uint8_t *)msg->msg_iov[i].iov_base;
+ si_data[i].buf_len = msg->msg_iov[i].iov_len;
+ }
+
+ // Perform system call.
+ __wasi_errno_t error =
+ __wasi_sock_send(sockfd, si_data, msg->msg_iovlen, 0, &so_datalen);
+ free(si_data);
+ HANDLE_ERROR(error)
+
+ return so_datalen;
+}
+
+ssize_t
+sendto(int sockfd, const void *buf, size_t len, int flags,
+ const struct sockaddr *dest_addr, socklen_t addrlen)
+{
+ // Prepare input parameters.
+ __wasi_ciovec_t iov = { .buf = (uint8_t *)buf, .buf_len = len };
+ uint32_t so_datalen = 0;
+ __wasi_addr_t wasi_addr;
+ __wasi_errno_t error;
+ size_t si_data_len = 1;
+ __wasi_siflags_t si_flags = 0;
+
+ // This implementation does not support any flags.
+ if (flags != 0) {
+ HANDLE_ERROR(__WASI_ERRNO_NOPROTOOPT)
+ }
+
+ error = sockaddr_to_wasi_addr(dest_addr, addrlen, &wasi_addr);
+ HANDLE_ERROR(error);
+
+ // Perform system call.
+ error = __wasi_sock_send_to(sockfd, &iov, si_data_len, si_flags, &wasi_addr,
+ &so_datalen);
+ HANDLE_ERROR(error)
+
+ return so_datalen;
+}
+
+ssize_t
+recvfrom(int sockfd, void *buf, size_t len, int flags,
+ struct sockaddr *src_addr, socklen_t *addrlen)
+{
+ // Prepare input parameters.
+ __wasi_ciovec_t iov = { .buf = (uint8_t *)buf, .buf_len = len };
+ uint32_t so_datalen = 0;
+ __wasi_addr_t wasi_addr;
+ __wasi_errno_t error;
+ size_t si_data_len = 1;
+ __wasi_siflags_t si_flags = 0;
+
+ // This implementation does not support any flags.
+ if (flags != 0) {
+ HANDLE_ERROR(__WASI_ERRNO_NOPROTOOPT)
+ }
+
+ if (!src_addr) {
+ return recv(sockfd, buf, len, flags);
+ }
+
+ // Perform system call.
+ error = __wasi_sock_recv_from(sockfd, &iov, si_data_len, si_flags,
+ &wasi_addr, &so_datalen);
+ HANDLE_ERROR(error);
+
+ error = wasi_addr_to_sockaddr(&wasi_addr, src_addr, addrlen);
+ HANDLE_ERROR(error);
+
+ return so_datalen;
+}
+
+int
+socket(int domain, int type, int protocol)
+{
+ // the stub of address pool fd
+ __wasi_fd_t poolfd = -1;
+ __wasi_fd_t sockfd;
+ __wasi_errno_t error;
+ __wasi_address_family_t af;
+ __wasi_sock_type_t socktype;
+
+ if (AF_INET == domain) {
+ af = INET4;
+ }
+ else if (AF_INET6 == domain) {
+ af = INET6;
+ }
+ else {
+ return __WASI_ERRNO_NOPROTOOPT;
+ }
+
+ if (SOCK_DGRAM == type) {
+ socktype = SOCKET_DGRAM;
+ }
+ else if (SOCK_STREAM == type) {
+ socktype = SOCKET_STREAM;
+ }
+ else {
+ return __WASI_ERRNO_NOPROTOOPT;
+ }
+
+ error = __wasi_sock_open(poolfd, af, socktype, &sockfd);
+ HANDLE_ERROR(error)
+
+ return sockfd;
+}
+
+int
+getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
+{
+ __wasi_addr_t wasi_addr;
+ __wasi_errno_t error;
+
+ memset(&wasi_addr, 0, sizeof(wasi_addr));
+
+ error = __wasi_sock_addr_local(sockfd, &wasi_addr);
+ HANDLE_ERROR(error)
+
+ error = wasi_addr_to_sockaddr(&wasi_addr, addr, addrlen);
+ HANDLE_ERROR(error)
+
+ return __WASI_ERRNO_SUCCESS;
+}
+
+int
+getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
+{
+ __wasi_addr_t wasi_addr;
+ __wasi_errno_t error;
+
+ memset(&wasi_addr, 0, sizeof(wasi_addr));
+
+ 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;
+}
+
+struct aibuf {
+ struct addrinfo ai;
+ union sa {
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ } sa;
+};
+
+static __wasi_errno_t
+addrinfo_hints_to_wasi_hints(const struct addrinfo *hints,
+ __wasi_addr_info_hints_t *wasi_hints)
+{
+ if (hints) {
+ wasi_hints->hints_enabled = 1;
+
+ switch (hints->ai_family) {
+ case AF_INET:
+ wasi_hints->family = INET4;
+ break;
+ case AF_INET6:
+ wasi_hints->family = INET6;
+ break;
+ default:
+ return __WASI_ERRNO_AFNOSUPPORT;
+ }
+ switch (hints->ai_socktype) {
+ case SOCK_STREAM:
+ wasi_hints->type = SOCKET_STREAM;
+ break;
+ case SOCK_DGRAM:
+ wasi_hints->type = SOCKET_DGRAM;
+ break;
+ default:
+ return __WASI_ERRNO_NOTSUP;
+ }
+
+ if (hints->ai_protocol != 0) {
+ return __WASI_ERRNO_NOTSUP;
+ }
+
+ if (hints->ai_flags != 0) {
+ return __WASI_ERRNO_NOTSUP;
+ }
+ }
+ else {
+ wasi_hints->hints_enabled = 0;
+ }
+
+ return __WASI_ERRNO_SUCCESS;
+}
+
+static __wasi_errno_t
+wasi_addr_info_to_addr_info(const __wasi_addr_info_t *addr_info,
+ struct addrinfo *ai)
+{
+ ai->ai_socktype =
+ addr_info->type == SOCKET_DGRAM ? SOCK_DGRAM : SOCK_STREAM;
+ ai->ai_protocol = 0;
+ ai->ai_canonname = NULL;
+
+ if (addr_info->addr.kind == IPv4) {
+ ai->ai_family = AF_INET;
+ ai->ai_addrlen = sizeof(struct sockaddr_in);
+ }
+ else {
+ ai->ai_family = AF_INET6;
+ ai->ai_addrlen = sizeof(struct sockaddr_in6);
+ }
+
+ return wasi_addr_to_sockaddr(&addr_info->addr, ai->ai_addr,
+ &ai->ai_addrlen); // TODO err handling
+}
+
+int
+getaddrinfo(const char *node, const char *service, const struct addrinfo *hints,
+ struct addrinfo **res)
+{
+ __wasi_addr_info_hints_t wasi_hints;
+ __wasi_addr_info_t *addr_info = NULL;
+ __wasi_size_t addr_info_size, i;
+ __wasi_size_t max_info_size = 16;
+ __wasi_errno_t error;
+ struct aibuf *aibuf_res;
+
+ error = addrinfo_hints_to_wasi_hints(hints, &wasi_hints);
+ HANDLE_ERROR(error)
+
+ do {
+ if (addr_info)
+ free(addr_info);
+
+ addr_info_size = max_info_size;
+ addr_info = (__wasi_addr_info_t *)malloc(addr_info_size
+ * sizeof(__wasi_addr_info_t));
+
+ if (!addr_info) {
+ HANDLE_ERROR(__WASI_ERRNO_NOMEM)
+ }
+
+ error = __wasi_sock_addr_resolve(node, service == NULL ? "" : service,
+ &wasi_hints, addr_info, addr_info_size,
+ &max_info_size);
+ if (error != __WASI_ERRNO_SUCCESS) {
+ free(addr_info);
+ HANDLE_ERROR(error);
+ }
+ } while (max_info_size > addr_info_size);
+
+ if (addr_info_size == 0) {
+ free(addr_info);
+ *res = NULL;
+ return __WASI_ERRNO_SUCCESS;
+ }
+
+ aibuf_res =
+ (struct aibuf *)calloc(1, addr_info_size * sizeof(struct aibuf));
+ if (!aibuf_res) {
+ free(addr_info);
+ HANDLE_ERROR(__WASI_ERRNO_NOMEM)
+ }
+
+ *res = &aibuf_res[0].ai;
+
+ if (addr_info_size) {
+ addr_info_size = max_info_size;
+ }
+
+ for (i = 0; i < addr_info_size; i++) {
+ struct addrinfo *ai = &aibuf_res[i].ai;
+ ai->ai_addr = (struct sockaddr *)&aibuf_res[i].sa;
+
+ error = wasi_addr_info_to_addr_info(&addr_info[i], ai);
+ if (error != __WASI_ERRNO_SUCCESS) {
+ free(addr_info);
+ free(aibuf_res);
+ HANDLE_ERROR(error)
+ }
+ ai->ai_next = i == addr_info_size - 1 ? NULL : &aibuf_res[i + 1].ai;
+ }
+
+ free(addr_info);
+
+ return __WASI_ERRNO_SUCCESS;
+}
+
+void
+freeaddrinfo(struct addrinfo *res)
+{
+ /* res is a pointer to a first field in the first element
+ * of aibuf array allocated in getaddrinfo, therefore this call
+ * frees the memory of the entire array. */
+ free(res);
+}
+
+static struct timeval
+time_us_to_timeval(uint64_t time_us)
+{
+ struct timeval tv;
+ tv.tv_sec = time_us / 1000000UL;
+ tv.tv_usec = time_us % 1000000UL;
+ return tv;
+}
+
+static uint64_t
+timeval_to_time_us(struct timeval tv)
+{
+ return (tv.tv_sec * 1000000UL) + tv.tv_usec;
+}
+
+static int
+get_sol_socket_option(int sockfd, int optname, void *__restrict optval,
+ socklen_t *__restrict optlen)
+{
+ __wasi_errno_t error;
+ uint64_t timeout_us;
+ bool is_linger_enabled;
+ int linger_s;
+
+ switch (optname) {
+ case SO_RCVTIMEO:
+ assert(*optlen == sizeof(struct timeval));
+ error = __wasi_sock_get_recv_timeout(sockfd, &timeout_us);
+ HANDLE_ERROR(error);
+ *(struct timeval *)optval = time_us_to_timeval(timeout_us);
+ return error;
+ case SO_SNDTIMEO:
+ assert(*optlen == sizeof(struct timeval));
+ error = __wasi_sock_get_send_timeout(sockfd, &timeout_us);
+ HANDLE_ERROR(error);
+ *(struct timeval *)optval = time_us_to_timeval(timeout_us);
+ return error;
+ case SO_SNDBUF:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_send_buf_size(sockfd, (size_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case SO_RCVBUF:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_recv_buf_size(sockfd, (size_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case SO_KEEPALIVE:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_keep_alive(sockfd, (bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case SO_REUSEADDR:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_reuse_addr(sockfd, (bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case SO_REUSEPORT:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_reuse_port(sockfd, (bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case SO_LINGER:
+ assert(*optlen == sizeof(struct linger));
+ error =
+ __wasi_sock_get_linger(sockfd, &is_linger_enabled, &linger_s);
+ HANDLE_ERROR(error);
+ ((struct linger *)optval)->l_onoff = (int)is_linger_enabled;
+ ((struct linger *)optval)->l_linger = linger_s;
+ return error;
+ case SO_BROADCAST:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_broadcast(sockfd, (bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ default:
+ error = __WASI_ERRNO_NOTSUP;
+ HANDLE_ERROR(error);
+ return error;
+ }
+}
+
+static int
+get_ipproto_tcp_option(int sockfd, int optname, void *__restrict optval,
+ socklen_t *__restrict optlen)
+{
+ __wasi_errno_t error;
+ switch (optname) {
+ case TCP_KEEPIDLE:
+ assert(*optlen == sizeof(uint32_t));
+ error = __wasi_sock_get_tcp_keep_idle(sockfd, (uint32_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case TCP_KEEPINTVL:
+ assert(*optlen == sizeof(uint32_t));
+ error = __wasi_sock_get_tcp_keep_intvl(sockfd, (uint32_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case TCP_FASTOPEN_CONNECT:
+ assert(*optlen == sizeof(int));
+ error =
+ __wasi_sock_get_tcp_fastopen_connect(sockfd, (bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case TCP_NODELAY:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_tcp_no_delay(sockfd, (bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case TCP_QUICKACK:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_tcp_quick_ack(sockfd, (bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ default:
+ error = __WASI_ERRNO_NOTSUP;
+ HANDLE_ERROR(error);
+ return error;
+ }
+}
+
+static int
+get_ipproto_ip_option(int sockfd, int optname, void *__restrict optval,
+ socklen_t *__restrict optlen)
+{
+ __wasi_errno_t error;
+
+ switch (optname) {
+ case IP_MULTICAST_LOOP:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_ip_multicast_loop(sockfd, false,
+ (bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case IP_TTL:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_ip_ttl(sockfd, (uint8_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case IP_MULTICAST_TTL:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_ip_multicast_ttl(sockfd, (uint8_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ default:
+ error = __WASI_ERRNO_NOTSUP;
+ HANDLE_ERROR(error);
+ return error;
+ }
+}
+
+static int
+get_ipproto_ipv6_option(int sockfd, int optname, void *__restrict optval,
+ socklen_t *__restrict optlen)
+{
+ __wasi_errno_t error;
+
+ switch (optname) {
+ case IPV6_V6ONLY:
+ assert(*optlen == sizeof(int));
+ error = __wasi_sock_get_ipv6_only(sockfd, (bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case IPV6_MULTICAST_LOOP:
+ assert(*optlen == sizeof(int));
+ error =
+ __wasi_sock_get_ip_multicast_loop(sockfd, true, (bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ default:
+ error = __WASI_ERRNO_NOTSUP;
+ HANDLE_ERROR(error);
+ return error;
+ }
+}
+
+int
+getsockopt(int sockfd, int level, int optname, void *__restrict optval,
+ socklen_t *__restrict optlen)
+{
+ __wasi_errno_t error;
+
+ switch (level) {
+ case SOL_SOCKET:
+ return get_sol_socket_option(sockfd, optname, optval, optlen);
+ case IPPROTO_TCP:
+ return get_ipproto_tcp_option(sockfd, optname, optval, optlen);
+ case IPPROTO_IP:
+ return get_ipproto_ip_option(sockfd, optname, optval, optlen);
+ case IPPROTO_IPV6:
+ return get_ipproto_ipv6_option(sockfd, optname, optval, optlen);
+ default:
+ error = __WASI_ERRNO_NOTSUP;
+ HANDLE_ERROR(error);
+ return error;
+ }
+}
+
+static int
+set_sol_socket_option(int sockfd, int optname, const void *optval,
+ socklen_t optlen)
+{
+ __wasi_errno_t error;
+ uint64_t timeout_us;
+
+ switch (optname) {
+ case SO_RCVTIMEO:
+ {
+ assert(optlen == sizeof(struct timeval));
+ timeout_us = timeval_to_time_us(*(struct timeval *)optval);
+ error = __wasi_sock_set_recv_timeout(sockfd, timeout_us);
+ HANDLE_ERROR(error);
+ return error;
+ }
+ case SO_SNDTIMEO:
+ {
+ assert(optlen == sizeof(struct timeval));
+ timeout_us = timeval_to_time_us(*(struct timeval *)optval);
+ error = __wasi_sock_set_send_timeout(sockfd, timeout_us);
+ HANDLE_ERROR(error);
+ return error;
+ }
+ case SO_SNDBUF:
+ {
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_send_buf_size(sockfd, *(size_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ }
+ case SO_RCVBUF:
+ {
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_recv_buf_size(sockfd, *(size_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ }
+ case SO_KEEPALIVE:
+ {
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_keep_alive(sockfd, *(bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ }
+ case SO_REUSEADDR:
+ {
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_reuse_addr(sockfd, *(bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ }
+ case SO_REUSEPORT:
+ {
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_reuse_port(sockfd, *(bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ }
+ case SO_LINGER:
+ {
+ assert(optlen == sizeof(struct linger));
+ struct linger *linger_opt = ((struct linger *)optval);
+ error = __wasi_sock_set_linger(sockfd, (bool)linger_opt->l_onoff,
+ linger_opt->l_linger);
+ HANDLE_ERROR(error);
+ return error;
+ }
+ case SO_BROADCAST:
+ {
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_broadcast(sockfd, *(bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ }
+ default:
+ {
+ error = __WASI_ERRNO_NOTSUP;
+ HANDLE_ERROR(error);
+ return error;
+ }
+ }
+}
+
+static int
+set_ipproto_tcp_option(int sockfd, int optname, const void *optval,
+ socklen_t optlen)
+{
+ __wasi_errno_t error;
+
+ switch (optname) {
+ case TCP_NODELAY:
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_tcp_no_delay(sockfd, *(bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case TCP_KEEPIDLE:
+ assert(optlen == sizeof(uint32_t));
+ error = __wasi_sock_set_tcp_keep_idle(sockfd, *(uint32_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case TCP_KEEPINTVL:
+ assert(optlen == sizeof(uint32_t));
+ error = __wasi_sock_set_tcp_keep_intvl(sockfd, *(uint32_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case TCP_FASTOPEN_CONNECT:
+ assert(optlen == sizeof(int));
+ error =
+ __wasi_sock_set_tcp_fastopen_connect(sockfd, *(bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case TCP_QUICKACK:
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_tcp_quick_ack(sockfd, *(bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ default:
+ error = __WASI_ERRNO_NOTSUP;
+ HANDLE_ERROR(error);
+ return error;
+ }
+}
+
+static int
+set_ipproto_ip_option(int sockfd, int optname, const void *optval,
+ socklen_t optlen)
+{
+ __wasi_errno_t error;
+ __wasi_addr_ip_t imr_multiaddr;
+ struct ip_mreq *ip_mreq_opt;
+
+ switch (optname) {
+ case IP_MULTICAST_LOOP:
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_ip_multicast_loop(sockfd, false,
+ *(bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case IP_ADD_MEMBERSHIP:
+ assert(optlen == sizeof(struct ip_mreq));
+ ip_mreq_opt = (struct ip_mreq *)optval;
+ imr_multiaddr.kind = IPv4;
+ ipv4_addr_to_wasi_ip4_addr(ip_mreq_opt->imr_multiaddr.s_addr,
+ &imr_multiaddr.addr.ip4);
+ error = __wasi_sock_set_ip_add_membership(
+ sockfd, &imr_multiaddr, ip_mreq_opt->imr_interface.s_addr);
+ HANDLE_ERROR(error);
+ return error;
+ case IP_DROP_MEMBERSHIP:
+ assert(optlen == sizeof(struct ip_mreq));
+ ip_mreq_opt = (struct ip_mreq *)optval;
+ imr_multiaddr.kind = IPv4;
+ ipv4_addr_to_wasi_ip4_addr(ip_mreq_opt->imr_multiaddr.s_addr,
+ &imr_multiaddr.addr.ip4);
+ error = __wasi_sock_set_ip_drop_membership(
+ sockfd, &imr_multiaddr, ip_mreq_opt->imr_interface.s_addr);
+ HANDLE_ERROR(error);
+ return error;
+ case IP_TTL:
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_ip_ttl(sockfd, *(uint8_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case IP_MULTICAST_TTL:
+ assert(optlen == sizeof(int));
+ error =
+ __wasi_sock_set_ip_multicast_ttl(sockfd, *(uint8_t *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ default:
+ error = __WASI_ERRNO_NOTSUP;
+ HANDLE_ERROR(error);
+ return error;
+ }
+}
+
+static int
+set_ipproto_ipv6_option(int sockfd, int optname, const void *optval,
+ socklen_t optlen)
+{
+ __wasi_errno_t error;
+ struct ipv6_mreq *ipv6_mreq_opt;
+ __wasi_addr_ip_t imr_multiaddr;
+
+ switch (optname) {
+ case IPV6_V6ONLY:
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_ipv6_only(sockfd, *(bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case IPV6_MULTICAST_LOOP:
+ assert(optlen == sizeof(int));
+ error = __wasi_sock_set_ip_multicast_loop(sockfd, true,
+ *(bool *)optval);
+ HANDLE_ERROR(error);
+ return error;
+ case IPV6_JOIN_GROUP:
+ assert(optlen == sizeof(struct ipv6_mreq));
+ ipv6_mreq_opt = (struct ipv6_mreq *)optval;
+ imr_multiaddr.kind = IPv6;
+ ipv6_addr_to_wasi_ipv6_addr(
+ (uint16_t *)ipv6_mreq_opt->ipv6mr_multiaddr.s6_addr,
+ &imr_multiaddr.addr.ip6);
+ error = __wasi_sock_set_ip_add_membership(
+ sockfd, &imr_multiaddr, ipv6_mreq_opt->ipv6mr_interface);
+ HANDLE_ERROR(error);
+ return error;
+ case IPV6_LEAVE_GROUP:
+ assert(optlen == sizeof(struct ipv6_mreq));
+ ipv6_mreq_opt = (struct ipv6_mreq *)optval;
+ imr_multiaddr.kind = IPv6;
+ ipv6_addr_to_wasi_ipv6_addr(
+ (uint16_t *)ipv6_mreq_opt->ipv6mr_multiaddr.s6_addr,
+ &imr_multiaddr.addr.ip6);
+ error = __wasi_sock_set_ip_drop_membership(
+ sockfd, &imr_multiaddr, ipv6_mreq_opt->ipv6mr_interface);
+ HANDLE_ERROR(error);
+ return error;
+ default:
+ error = __WASI_ERRNO_NOTSUP;
+ HANDLE_ERROR(error);
+ return error;
+ }
+}
+
+int
+setsockopt(int sockfd, int level, int optname, const void *optval,
+ socklen_t optlen)
+{
+ __wasi_errno_t error;
+
+ switch (level) {
+ case SOL_SOCKET:
+ return set_sol_socket_option(sockfd, optname, optval, optlen);
+ case IPPROTO_TCP:
+ return set_ipproto_tcp_option(sockfd, optname, optval, optlen);
+ case IPPROTO_IP:
+ return set_ipproto_ip_option(sockfd, optname, optval, optlen);
+ case IPPROTO_IPV6:
+ return set_ipproto_ipv6_option(sockfd, optname, optval, optlen);
+ default:
+ error = __WASI_ERRNO_NOTSUP;
+ HANDLE_ERROR(error);
+ return error;
+ }
+}
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/build.sh b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/build.sh
new file mode 100755
index 000000000..24f5ee676
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/build.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+set -eo pipefail
+CC="${CC:=/opt/wasi-sdk/bin/clang}"
+files=("tcp_udp.c" "nslookup.c")
+
+for file in "${files[@]}"
+do
+ echo $file
+ $CC \
+ --target=wasm32-wasi-threads \
+ -I../inc \
+ ../src/wasi/wasi_socket_ext.c -pthread -ftls-model=local-exec \
+ -Wl,--allow-undefined \
+ -Wl,--strip-all,--no-entry \
+ -Wl,--export=__heap_base \
+ -Wl,--export=__data_end \
+ -Wl,--shared-memory,--max-memory=10485760 \
+ -Wl,--export=malloc \
+ -Wl,--export=free \
+ -o "${file%.*}.wasm" "$file"
+done \ No newline at end of file
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/nslookup.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/nslookup.c
new file mode 100644
index 000000000..37150f1eb
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/nslookup.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include <assert.h>
+#include <string.h>
+#ifdef __wasi__
+#include <wasi/api.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <wasi_socket_ext.h>
+#else
+#include <netdb.h>
+#endif
+
+void
+test_nslookup(int af)
+{
+ struct addrinfo *res;
+ int count = 0;
+ struct addrinfo hints;
+ char *url = "google-public-dns-a.google.com";
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = af;
+ hints.ai_socktype = SOCK_STREAM;
+ int ret = getaddrinfo(url, 0, &hints, &res);
+ assert(ret == 0);
+ struct addrinfo *address = res;
+ while (address) {
+ assert(address->ai_family == af);
+ assert(address->ai_socktype == SOCK_STREAM);
+ count++;
+ address = address->ai_next;
+ }
+
+ assert(count > 0);
+ freeaddrinfo(res);
+}
+
+int
+main()
+{
+ test_nslookup(AF_INET); /* for ipv4 */
+ test_nslookup(AF_INET6); /* for ipv6 */
+
+ return 0;
+}
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/tcp_udp.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/tcp_udp.c
new file mode 100644
index 000000000..49231de89
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/iwasm/libraries/lib-socket/test/tcp_udp.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#ifdef __wasi__
+#include <wasi/api.h>
+#include <sys/socket.h>
+#include <wasi_socket_ext.h>
+#endif
+#include <arpa/inet.h>
+#include <pthread.h>
+#define SERVER_MSG "Message from server."
+#define PORT 8989
+pthread_mutex_t mut;
+pthread_cond_t cond;
+int server_init_complete = 0;
+char buffer[sizeof(SERVER_MSG) + 1];
+
+struct socket_info {
+ union {
+ struct sockaddr_in addr_ipv4;
+ struct sockaddr_in6 addr_ipv6;
+ } addr;
+ int sock;
+};
+
+struct thread_args {
+ int family;
+ int protocol;
+};
+
+struct socket_info
+init_socket_addr(int family, int protocol)
+{
+ int sock = socket(family, protocol, 0);
+ assert(sock != -1);
+
+ struct socket_info info;
+ if (family == AF_INET) {
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(PORT);
+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ info.addr.addr_ipv4 = addr;
+ }
+ else if (family == AF_INET6) {
+ struct sockaddr_in6 addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = htons(PORT);
+ addr.sin6_addr = in6addr_loopback;
+ info.addr.addr_ipv6 = addr;
+ }
+ info.sock = sock;
+ return info;
+}
+
+void
+assert_thread_args(struct thread_args *args)
+{
+ assert(args->family == AF_INET || args->family == AF_INET6);
+ assert(args->protocol == SOCK_STREAM || args->protocol == SOCK_DGRAM);
+}
+
+void *
+server(void *arg)
+{
+ server_init_complete = 0;
+ struct thread_args *args = (struct thread_args *)arg;
+ assert_thread_args(args);
+
+ struct socket_info init_server_sock =
+ init_socket_addr(args->family, args->protocol);
+
+ int server_sock = init_server_sock.sock;
+ socklen_t addr_size;
+ struct sockaddr_storage client_addr;
+ strcpy(buffer, SERVER_MSG);
+
+ struct sockaddr *server_addr = (struct sockaddr *)&init_server_sock.addr;
+ int ret = bind(server_sock, server_addr,
+ args->family == AF_INET ? sizeof(struct sockaddr_in)
+ : sizeof(struct sockaddr_in6));
+ assert(ret == 0);
+
+ (args->protocol == SOCK_STREAM) && listen(server_sock, 1);
+ pthread_mutex_lock(&mut);
+ server_init_complete = 1;
+ pthread_mutex_unlock(&mut);
+ pthread_cond_signal(&cond);
+
+ addr_size = sizeof(client_addr);
+ if (args->protocol == SOCK_STREAM) {
+ int client_sock =
+ accept(server_sock, (struct sockaddr *)&client_addr, &addr_size);
+ assert(client_sock >= 0);
+ sendto(client_sock, buffer, strlen(buffer), 0,
+ (struct sockaddr *)&client_addr, addr_size);
+
+ assert(close(client_sock) == 0);
+ }
+ else {
+ recvfrom(server_sock, buffer, sizeof(buffer), 0,
+ (struct sockaddr *)&client_addr, &addr_size);
+ sendto(server_sock, buffer, strlen(buffer), 0,
+ (struct sockaddr *)&client_addr, addr_size);
+
+ assert(close(server_sock) == 0);
+ }
+
+ return NULL;
+}
+
+void *
+client(void *arg)
+{
+ struct thread_args *args = (struct thread_args *)arg;
+ assert_thread_args(args);
+
+ pthread_mutex_lock(&mut);
+
+ while (server_init_complete == 0) {
+ pthread_cond_wait(&cond, &mut);
+ }
+
+ struct socket_info init_client_sock =
+ init_socket_addr(args->family, args->protocol);
+ int sock = init_client_sock.sock;
+ pthread_mutex_unlock(&mut);
+
+ if (args->family == AF_INET) {
+ struct sockaddr_in addr = init_client_sock.addr.addr_ipv4;
+ if (args->protocol == SOCK_STREAM) {
+ assert(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != -1);
+ }
+ else {
+ assert(sendto(sock, buffer, strlen(buffer), 0,
+ (struct sockaddr *)&addr, sizeof(addr))
+ != -1);
+ }
+ }
+ else {
+ struct sockaddr_in6 addr = init_client_sock.addr.addr_ipv6;
+ if (args->protocol == SOCK_STREAM) {
+ assert(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) != -1);
+ }
+ else {
+ assert(sendto(sock, buffer, strlen(buffer), 0,
+ (struct sockaddr *)&addr, sizeof(addr))
+ != -1);
+ }
+ }
+
+ recv(sock, buffer, sizeof(buffer), 0);
+ assert(strcmp(buffer, SERVER_MSG) == 0);
+ assert(close(sock) == 0);
+ return NULL;
+}
+
+void
+test_protocol(int family, int protocol)
+{
+ pthread_t server_thread, client_thread;
+ assert(pthread_cond_init(&cond, NULL) == 0);
+ assert(pthread_mutex_init(&mut, NULL) == 0);
+
+ struct thread_args args = { family, protocol };
+ assert(pthread_create(&server_thread, NULL, server, (void *)&args) == 0);
+ assert(pthread_create(&client_thread, NULL, client, (void *)&args) == 0);
+ assert(pthread_join(server_thread, NULL) == 0);
+ assert(pthread_join(client_thread, NULL) == 0);
+
+ assert(pthread_mutex_destroy(&mut) == 0);
+ assert(pthread_cond_destroy(&cond) == 0);
+}
+
+int
+main(int argc, char **argv)
+{
+ /* test tcp with ipv4 and ipv6 */
+ test_protocol(AF_INET, SOCK_STREAM);
+ test_protocol(AF_INET6, SOCK_STREAM);
+
+ /* test udp with ipv4 and ipv6 */
+ test_protocol(AF_INET, SOCK_DGRAM);
+ test_protocol(AF_INET6, SOCK_DGRAM);
+
+ return 0;
+} \ No newline at end of file