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:
@ -292,16 +292,29 @@ os_sem_unlink(const char *name);
|
||||
* need to implement these APIs
|
||||
*/
|
||||
|
||||
typedef union {
|
||||
uint32 ipv4;
|
||||
uint16 ipv6[8];
|
||||
uint8 data[1];
|
||||
} bh_ip_addr_buffer_t;
|
||||
|
||||
typedef struct {
|
||||
bh_ip_addr_buffer_t addr_bufer;
|
||||
uint16 port;
|
||||
bool is_ipv4;
|
||||
} bh_sockaddr_t;
|
||||
|
||||
/**
|
||||
* Create a socket
|
||||
*
|
||||
* @param sock [OUTPUT] the pointer of socket
|
||||
* @param tcp_or_udp 1 for tcp, 0 for udp
|
||||
* @param is_ipv4 true for IPv4, false for IPv6
|
||||
* @param is_tcp true for tcp, false for udp
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Assign the address and port to the socket
|
||||
@ -380,6 +393,22 @@ os_socket_connect(bh_socket_t socket, const char *addr, int port);
|
||||
int
|
||||
os_socket_recv(bh_socket_t socket, void *buf, unsigned int len);
|
||||
|
||||
/**
|
||||
* Blocking receive message from a socket.
|
||||
*
|
||||
* @param socket the socket to send message
|
||||
* @param buf the buffer to store the data
|
||||
* @param len length of the buffer, this API does not guarantee that
|
||||
* [len] bytes are received
|
||||
* @param flags control the operation
|
||||
* @param src_addr source address
|
||||
*
|
||||
* @return number of bytes sent if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
|
||||
bh_sockaddr_t *src_addr);
|
||||
|
||||
/**
|
||||
* Blocking send message on a socket
|
||||
*
|
||||
@ -392,6 +421,21 @@ os_socket_recv(bh_socket_t socket, void *buf, unsigned int len);
|
||||
int
|
||||
os_socket_send(bh_socket_t socket, const void *buf, unsigned int len);
|
||||
|
||||
/**
|
||||
* Blocking send message on a socket to the target address
|
||||
*
|
||||
* @param socket the socket to send message
|
||||
* @param buf the buffer of data to be sent
|
||||
* @param len length of the buffer
|
||||
* @param flags control the operation
|
||||
* @param dest_addr target address
|
||||
*
|
||||
* @return number of bytes sent if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
|
||||
int flags, const bh_sockaddr_t *dest_addr);
|
||||
|
||||
/**
|
||||
* Close a socket
|
||||
*
|
||||
@ -416,13 +460,522 @@ os_socket_shutdown(bh_socket_t socket);
|
||||
* converts cp into a number in host byte order suitable for use as
|
||||
* an Internet network address
|
||||
*
|
||||
* @param cp a string in IPv4 numbers-and-dots notation
|
||||
* @param is_ipv4 a flag that indicates whether the string is an IPv4 or
|
||||
* IPv6 address
|
||||
*
|
||||
* @return On success, the converted address is returned.
|
||||
* @param cp a string in IPv4 numbers-and-dots notation or IPv6
|
||||
* numbers-and-colons notation
|
||||
*
|
||||
* @param out an output buffer to store binary address
|
||||
*
|
||||
* @return On success, the function returns 0.
|
||||
* If the input is invalid, -1 is returned
|
||||
*/
|
||||
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);
|
||||
|
||||
typedef struct {
|
||||
bh_sockaddr_t sockaddr;
|
||||
uint8_t is_tcp;
|
||||
} bh_addr_info_t;
|
||||
|
||||
/**
|
||||
* Resolve a host a hostname and a service to one or more IP addresses
|
||||
*
|
||||
* @param host a host to resolve
|
||||
*
|
||||
* @param service a service to find a port for
|
||||
*
|
||||
* @param hint_is_tcp an optional flag that determines a preferred socket type
|
||||
(TCP or UDP).
|
||||
*
|
||||
* @param hint_is_ipv4 an optional flag that determines a preferred address
|
||||
family (IPv4 or IPv6)
|
||||
*
|
||||
* @param addr_info a buffer for resolved addresses
|
||||
*
|
||||
* @param addr_info_size a size of the buffer for resolved addresses
|
||||
|
||||
* @param max_info_size a maximum number of addresses available (can be bigger
|
||||
or smaller than buffer size)
|
||||
|
||||
* @return On success, the function returns 0; otherwise, it returns -1
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Returns an binary address and a port of the local socket
|
||||
*
|
||||
* @param socket the local socket
|
||||
*
|
||||
* @param sockaddr a buffer for storing the address
|
||||
*
|
||||
* @return On success, returns 0; otherwise, it returns -1.
|
||||
*/
|
||||
int
|
||||
os_socket_addr_local(bh_socket_t socket, bh_sockaddr_t *sockaddr);
|
||||
|
||||
/**
|
||||
* Returns an binary address and a port of the remote socket
|
||||
*
|
||||
* @param socket the remote socket
|
||||
*
|
||||
* @param sockaddr a buffer for storing the address
|
||||
*
|
||||
* @return On success, returns 0; otherwise, it returns -1.
|
||||
*/
|
||||
int
|
||||
os_socket_addr_remote(bh_socket_t socket, bh_sockaddr_t *sockaddr);
|
||||
|
||||
/**
|
||||
* Set the maximum send buffer size.
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param bufsiz requested kernel buffer size
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_send_buf_size(bh_socket_t socket, size_t bufsiz);
|
||||
|
||||
/**
|
||||
* Get the maximum send buffer size.
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param bufsiz the returned kernel buffer size
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_send_buf_size(bh_socket_t socket, size_t *bufsiz);
|
||||
|
||||
/**
|
||||
* Set the maximum receive buffer size.
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param bufsiz requested kernel buffer size
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_recv_buf_size(bh_socket_t socket, size_t bufsiz);
|
||||
|
||||
/**
|
||||
* Get the maximum receive buffer size.
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param bufsiz the returned kernel buffer size
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_recv_buf_size(bh_socket_t socket, size_t *bufsiz);
|
||||
|
||||
/**
|
||||
* Enable sending of keep-alive messages on connection-oriented sockets
|
||||
*
|
||||
* @param socket the socket to set the flag
|
||||
* @param is_enabled 1 to enable or 0 to disable
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_keep_alive(bh_socket_t socket, bool is_enabled);
|
||||
|
||||
/**
|
||||
* Get if sending of keep-alive messages on connection-oriented sockets is
|
||||
* enabled
|
||||
*
|
||||
* @param socket the socket to check
|
||||
* @param is_enabled 1 if enabled or 0 if disabled
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_keep_alive(bh_socket_t socket, bool *is_enabled);
|
||||
|
||||
/**
|
||||
* Set the send timeout until reporting an error
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param time_us microseconds until timeout
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_send_timeout(bh_socket_t socket, uint64 timeout_us);
|
||||
|
||||
/**
|
||||
* Get the send timeout until reporting an error
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param time_us the returned microseconds until timeout
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_send_timeout(bh_socket_t socket, uint64 *timeout_us);
|
||||
|
||||
/**
|
||||
* Set the recv timeout until reporting an error
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param time_us microseconds until timeout
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_recv_timeout(bh_socket_t socket, uint64 timeout_us);
|
||||
|
||||
/**
|
||||
* Get the recv timeout until reporting an error
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param time_us the returned microseconds until timeout
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_recv_timeout(bh_socket_t socket, uint64 *timeout_us);
|
||||
|
||||
/**
|
||||
* Enable re-use of local addresses
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param is_enabled 1 to enable or 0 to disable
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_reuse_addr(bh_socket_t socket, bool is_enabled);
|
||||
|
||||
/**
|
||||
* Get whether re-use of local addresses is enabled
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param is_enabled 1 for enabled or 0 for disabled
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_reuse_addr(bh_socket_t socket, bool *is_enabled);
|
||||
|
||||
/**
|
||||
* Enable re-use of local ports
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param is_enabled 1 to enable or 0 to disable
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_reuse_port(bh_socket_t socket, bool is_enabled);
|
||||
|
||||
/**
|
||||
* Get whether re-use of local ports is enabled
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param is_enabled 1 for enabled or 0 for disabled
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_reuse_port(bh_socket_t socket, bool *is_enabled);
|
||||
|
||||
/**
|
||||
* Set the linger options for the given socket
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param is_enabled whether linger is enabled
|
||||
* @param linger_s linger time (seconds)
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_linger(bh_socket_t socket, bool is_enabled, int linger_s);
|
||||
|
||||
/**
|
||||
* Get the linger options for the given socket
|
||||
*
|
||||
* @param socket the socket to get
|
||||
* @param is_enabled whether linger is enabled
|
||||
* @param linger_s linger time (seconds)
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_linger(bh_socket_t socket, bool *is_enabled, int *linger_s);
|
||||
|
||||
/**
|
||||
* Set no delay TCP
|
||||
* If set, disable the Nagle algorithm.
|
||||
* This means that segments are always sent as soon as possible,
|
||||
* even if there is only a small amount of data
|
||||
*
|
||||
* @param socket the socket to set the flag
|
||||
* @param is_enabled 1 to enable or 0 to disable
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_tcp_no_delay(bh_socket_t socket, bool is_enabled);
|
||||
|
||||
/**
|
||||
* Get no delay TCP
|
||||
* If set, disable the Nagle algorithm.
|
||||
* This means that segments are always sent as soon as possible,
|
||||
* even if there is only a small amount of data
|
||||
*
|
||||
* @param socket the socket to check
|
||||
* @param is_enabled 1 if enabled or 0 if disabled
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_tcp_no_delay(bh_socket_t socket, bool *is_enabled);
|
||||
|
||||
/**
|
||||
* Enable/Disable tcp quickack mode
|
||||
* In quickack mode, acks are sent immediately, rather than delayed if needed in
|
||||
* accordance to normal TCP operation
|
||||
*
|
||||
* @param socket the socket to set the flag
|
||||
* @param is_enabled 1 to enable or 0 to disable
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_tcp_quick_ack(bh_socket_t socket, bool is_enabled);
|
||||
|
||||
/**
|
||||
* Enable/Disable tcp quickack mode
|
||||
* In quickack mode, acks are sent immediately, rather than delayed if needed in
|
||||
* accordance to normal TCP operation
|
||||
*
|
||||
* @param socket the socket to check
|
||||
* @param is_enabled 1 if enabled or 0 if disabled
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_tcp_quick_ack(bh_socket_t socket, bool *is_enabled);
|
||||
|
||||
/**
|
||||
* Set the time the connection needs to remain idle before sending keepalive
|
||||
* probes
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param time_s seconds until keepalive probes are sent
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_tcp_keep_idle(bh_socket_t socket, uint32_t time_s);
|
||||
|
||||
/**
|
||||
* Gets the time the connection needs to remain idle before sending keepalive
|
||||
* probes
|
||||
*
|
||||
* @param socket the socket to check
|
||||
* @param time_s seconds until keepalive probes are sent
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_tcp_keep_idle(bh_socket_t socket, uint32_t *time_s);
|
||||
|
||||
/**
|
||||
* Set the time between individual keepalive probes
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param time_us seconds between individual keepalive probes
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_tcp_keep_intvl(bh_socket_t socket, uint32_t time_s);
|
||||
|
||||
/**
|
||||
* Get the time between individual keepalive probes
|
||||
*
|
||||
* @param socket the socket to get
|
||||
* @param time_s seconds between individual keepalive probes
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_tcp_keep_intvl(bh_socket_t socket, uint32_t *time_s);
|
||||
|
||||
/**
|
||||
* Set use of TCP Fast Open
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param is_enabled 1 to enable or 0 to disable
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_tcp_fastopen_connect(bh_socket_t socket, bool is_enabled);
|
||||
|
||||
/**
|
||||
* Get whether use of TCP Fast Open is enabled
|
||||
*
|
||||
* @param socket the socket to get
|
||||
* @param is_enabled 1 to enabled or 0 to disabled
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_tcp_fastopen_connect(bh_socket_t socket, bool *is_enabled);
|
||||
|
||||
/**
|
||||
* Set enable or disable IPv4 or IPv6 multicast loopback.
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param ipv6 true to set ipv6 loopback or false for ipv4
|
||||
* @param is_enabled 1 to enable or 0 to disable
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_ip_multicast_loop(bh_socket_t socket, bool ipv6, bool is_enabled);
|
||||
|
||||
/**
|
||||
* Get enable or disable IPv4 or IPv6 multicast loopback.
|
||||
*
|
||||
* @param socket the socket to check
|
||||
* @param ipv6 true to set ipv6 loopback or false for ipv4
|
||||
* @param is_enabled 1 for enabled or 0 for disabled
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_ip_multicast_loop(bh_socket_t socket, bool ipv6,
|
||||
bool *is_enabled);
|
||||
|
||||
/**
|
||||
* Add membership to a group
|
||||
*
|
||||
* @param socket the socket to add membership to
|
||||
* @param imr_multiaddr the group multicast address (IPv4 or IPv6)
|
||||
* @param imr_interface the interface to join on
|
||||
* @param is_ipv6 whether the imr_multiaddr is IPv4 or IPv6 (true for IPv6)
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Drop membership of a group
|
||||
*
|
||||
* @param socket the socket to drop membership to
|
||||
* @param imr_multiaddr the group multicast address (IPv4 or IPv6)
|
||||
* @param imr_interface the interface to join on
|
||||
* @param is_ipv6 whether the imr_multiaddr is IPv4 or IPv6 (true for IPv6)
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Set the current time-to-live field that is
|
||||
* used in every packet sent from this socket.
|
||||
* @param socket the socket to set the flag
|
||||
* @param ttl_s time to live (seconds)
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_ip_ttl(bh_socket_t socket, uint8_t ttl_s);
|
||||
|
||||
/**
|
||||
* Retrieve the current time-to-live field that is
|
||||
* used in every packet sent from this socket.
|
||||
* @param socket the socket to set the flag
|
||||
* @param ttl_s time to live (seconds)
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_ip_ttl(bh_socket_t socket, uint8_t *ttl_s);
|
||||
|
||||
/**
|
||||
* Set the time-to-live value of outgoing multicast
|
||||
* packets for this socket
|
||||
* @param socket the socket to set the flag
|
||||
* @param ttl_s time to live (seconds)
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_ip_multicast_ttl(bh_socket_t socket, uint8_t ttl_s);
|
||||
|
||||
/**
|
||||
* Read the time-to-live value of outgoing multicast
|
||||
* packets for this socket
|
||||
* @param socket the socket to set the flag
|
||||
* @param ttl_s time to live (seconds)
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_ip_multicast_ttl(bh_socket_t socket, uint8_t *ttl_s);
|
||||
|
||||
/**
|
||||
* Restrict to sending and receiving IPv6 packets only
|
||||
*
|
||||
* @param socket the socket to set
|
||||
* @param is_enabled 1 to enable or 0 to disable
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_ipv6_only(bh_socket_t socket, bool is_enabled);
|
||||
|
||||
/**
|
||||
* Get whether only sending and receiving IPv6 packets
|
||||
*
|
||||
* @param socket the socket to check
|
||||
* @param is_enabled 1 for enabled or 0 for disabled
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_ipv6_only(bh_socket_t socket, bool *is_enabled);
|
||||
|
||||
/**
|
||||
* Set whether broadcast is enabled
|
||||
* When enabled, datagram sockets are allowed
|
||||
* to send packets to a broadcast address.
|
||||
*
|
||||
* @param socket the socket to set the flag
|
||||
* @param is_enabled 1 to enable or 0 to disable
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_set_broadcast(bh_socket_t socket, bool is_enabled);
|
||||
|
||||
/**
|
||||
* Get whether broadcast is enabled
|
||||
* When enabled, datagram sockets are allowed
|
||||
* to send packets to a broadcast address.
|
||||
*
|
||||
* @param socket the socket to check
|
||||
* @param is_enabled 1 if enabled or 0 if disabled
|
||||
*
|
||||
* @return 0 if success, -1 otherwise
|
||||
*/
|
||||
int
|
||||
os_socket_get_broadcast(bh_socket_t socket, bool *is_enabled);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user