Skip to content

Commit

Permalink
implement basic TCP/UDP client support (WebAssembly#477)
Browse files Browse the repository at this point in the history
* implement basic TCP/UDP client support

This implements `socket`, `connect`, `recv`, `send`, etc. in terms of
`wasi-sockets` for the `wasm32-wasip2` target.

I've introduced a new public header file: `__wasi_snapshot.h`, which will define
a preprocessor symbol `__wasilibc_use_wasip2` if using the `wasm32-wasip2`
version of the header, in which case we provide features only available for that
target.

Co-authored-by: Dave Bakker <[email protected]>
Signed-off-by: Joel Dice <[email protected]>

* fix grammar in __wasi_snapshot.h comment

Co-authored-by: Dan Gohman <[email protected]>
Signed-off-by: Joel Dice <[email protected]>

---------

Signed-off-by: Joel Dice <[email protected]>
Co-authored-by: Dave Bakker <[email protected]>
Co-authored-by: Dan Gohman <[email protected]>
  • Loading branch information
3 people authored Mar 13, 2024
1 parent a963040 commit 684f155
Show file tree
Hide file tree
Showing 17 changed files with 1,377 additions and 14 deletions.
19 changes: 18 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,25 @@ ifeq ($(WASI_SNAPSHOT), p1)
# this list.
LIBC_BOTTOM_HALF_OMIT_SOURCES := \
$(LIBC_BOTTOM_HALF_SOURCES)/wasip2.c \
$(LIBC_BOTTOM_HALF_SOURCES)/descriptor_table.c
$(LIBC_BOTTOM_HALF_SOURCES)/descriptor_table.c \
$(LIBC_BOTTOM_HALF_SOURCES)/connect.c \
$(LIBC_BOTTOM_HALF_SOURCES)/socket.c \
$(LIBC_BOTTOM_HALF_SOURCES)/send.c \
$(LIBC_BOTTOM_HALF_SOURCES)/recv.c \
$(LIBC_BOTTOM_HALF_SOURCES)/sockets_utils.c
LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_OMIT_SOURCES),$(LIBC_BOTTOM_HALF_ALL_SOURCES))
# Omit p2-specific headers from include-all.c test.
INCLUDE_ALL_CLAUSES := -not -name wasip2.h -not -name descriptor_table.h
endif

ifeq ($(WASI_SNAPSHOT), p2)
# Omit source files not relevant to WASIp2.
LIBC_BOTTOM_HALF_OMIT_SOURCES := \
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/send.c \
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/recv.c
LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_OMIT_SOURCES),$(LIBC_BOTTOM_HALF_ALL_SOURCES))
endif

# FIXME(https://reviews.llvm.org/D85567) - due to a bug in LLD the weak
# references to a function defined in `chdir.c` only work if `chdir.c` is at the
# end of the archive, but once that LLD review lands and propagates into LLVM
Expand Down Expand Up @@ -687,6 +700,10 @@ include_dirs:

# Remove selected header files.
$(RM) $(patsubst %,$(SYSROOT_INC)/%,$(MUSL_OMIT_HEADERS))
ifeq ($(WASI_SNAPSHOT), p2)
printf '#ifndef __wasilibc_use_wasip2\n#define __wasilibc_use_wasip2\n#endif\n' \
> "$(SYSROOT_INC)/__wasi_snapshot.h"
endif

startup_files: include_dirs $(LIBC_BOTTOM_HALF_CRT_OBJS)
#
Expand Down
1 change: 1 addition & 0 deletions expected/wasm32-wasip1-threads/include-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include <__typedef_suseconds_t.h>
#include <__typedef_time_t.h>
#include <__typedef_uid_t.h>
#include <__wasi_snapshot.h>
#include <alloca.h>
#include <ar.h>
#include <arpa/ftp.h>
Expand Down
1 change: 1 addition & 0 deletions expected/wasm32-wasip1/include-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include <__typedef_suseconds_t.h>
#include <__typedef_time_t.h>
#include <__typedef_uid_t.h>
#include <__wasi_snapshot.h>
#include <alloca.h>
#include <ar.h>
#include <arpa/ftp.h>
Expand Down
16 changes: 16 additions & 0 deletions expected/wasm32-wasip2/defined-symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,18 @@ __wasi_sock_accept
__wasi_sock_recv
__wasi_sock_send
__wasi_sock_shutdown
__wasi_sockets_utils__any_addr
__wasi_sockets_utils__borrow_network
__wasi_sockets_utils__create_streams
__wasi_sockets_utils__drop_streams
__wasi_sockets_utils__map_error
__wasi_sockets_utils__output_addr_validate
__wasi_sockets_utils__output_addr_write
__wasi_sockets_utils__parse_address
__wasi_sockets_utils__posix_family
__wasi_sockets_utils__stream
__wasi_sockets_utils__tcp_bind
__wasi_sockets_utils__udp_bind
__wasilibc_access
__wasilibc_cwd
__wasilibc_deinitialize_environ
Expand Down Expand Up @@ -470,6 +482,7 @@ confstr
conj
conjf
conjl
connect
copysign
copysignf
copysignl
Expand Down Expand Up @@ -1047,6 +1060,7 @@ realloc
reallocarray
realpath
recv
recvfrom
regcomp
regerror
regexec
Expand Down Expand Up @@ -1088,6 +1102,7 @@ seed48
seekdir
select
send
sendto
setbuf
setbuffer
setenv
Expand All @@ -1112,6 +1127,7 @@ sinhl
sinl
sleep
snprintf
socket
sprintf
sqrt
sqrtf
Expand Down
1 change: 1 addition & 0 deletions expected/wasm32-wasip2/include-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include <__typedef_suseconds_t.h>
#include <__typedef_time_t.h>
#include <__typedef_uid_t.h>
#include <__wasi_snapshot.h>
#include <alloca.h>
#include <ar.h>
#include <arpa/ftp.h>
Expand Down
24 changes: 20 additions & 4 deletions expected/wasm32-wasip2/predefined-macros.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1162,10 +1162,12 @@
#define MOREDATA 2
#define MSG_ANY 0x02
#define MSG_BAND 0x04
#define MSG_DONTWAIT 0x0040
#define MSG_HIPRI 0x01
#define MSG_PEEK __WASI_RIFLAGS_RECV_PEEK
#define MSG_TRUNC __WASI_ROFLAGS_RECV_DATA_TRUNCATED
#define MSG_WAITALL __WASI_RIFLAGS_RECV_WAITALL
#define MSG_NOSIGNAL 0x4000
#define MSG_PEEK 0x0002
#define MSG_TRUNC 0x0020
#define MSG_WAITALL 0x0100
#define MUXID_ALL (-1)
#define M_1_PI 0.31830988618379067154
#define M_2_PI 0.63661977236758134308
Expand Down Expand Up @@ -1701,9 +1703,22 @@
#define SOCK_DGRAM __WASI_FILETYPE_SOCKET_DGRAM
#define SOCK_NONBLOCK (0x00004000)
#define SOCK_STREAM __WASI_FILETYPE_SOCKET_STREAM
#define SOL_IP 0
#define SOL_IPV6 41
#define SOL_SOCKET 0x7fffffff
#define SOL_TCP 6
#define SOL_UDP 17
#define SOMAXCONN 128
#define SO_ACCEPTCONN 30
#define SO_DOMAIN 39
#define SO_ERROR 4
#define SO_KEEPALIVE 9
#define SO_PROTOCOL 38
#define SO_RCVBUF 8
#define SO_RCVTIMEO 66
#define SO_REUSEADDR 2
#define SO_SNDBUF 7
#define SO_SNDTIMEO 67
#define SO_TYPE 3
#define SSIZE_MAX LONG_MAX
#define STATUS ns_o_status
Expand Down Expand Up @@ -3110,7 +3125,7 @@
#define __tg_real_remquo(x,y,z) (__RETCAST_2(x, y)( __FLT(x) && __FLT(y) ? remquof(x, y, z) : __LDBL((x)+(y)) ? remquol(x, y, z) : remquo(x, y, z) ))
#define __tm_gmtoff tm_gmtoff
#define __tm_zone tm_zone
#define __va_copy(d,s) __builtin_va_copy(d,s)
#define __va_copy(d,s) __builtin_va_copy(d, s)
#define __wasi__ 1
#define __wasi_api_h
#define __wasi_libc_environ_h
Expand Down Expand Up @@ -3179,6 +3194,7 @@
#define __wasilibc___typedef_suseconds_t_h
#define __wasilibc___typedef_time_t_h
#define __wasilibc___typedef_uid_t_h
#define __wasilibc_use_wasip2
#define __wasm 1
#define __wasm32 1
#define __wasm32__ 1
Expand Down
53 changes: 53 additions & 0 deletions libc-bottom-half/headers/private/wasi/sockets_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#ifndef __wasi_sockets_utils_h
#define __wasi_sockets_utils_h

#include <netinet/in.h>

#include <wasi/descriptor_table.h>

typedef struct {
enum {
OUTPUT_SOCKADDR_NULL,
OUTPUT_SOCKADDR_V4,
OUTPUT_SOCKADDR_V6,
} tag;
union {
struct {
int dummy;
} null;
struct {
struct sockaddr_in *addr;
socklen_t *addrlen;
} v4;
struct {
struct sockaddr_in6 *addr;
socklen_t *addrlen;
} v6;
};
} output_sockaddr_t;

network_borrow_network_t __wasi_sockets_utils__borrow_network();
int __wasi_sockets_utils__map_error(network_error_code_t wasi_error);
bool __wasi_sockets_utils__parse_address(
network_ip_address_family_t expected_family,
const struct sockaddr *address, socklen_t len,
network_ip_socket_address_t *result, int *error);
bool __wasi_sockets_utils__output_addr_validate(
network_ip_address_family_t expected_family, struct sockaddr *addr,
socklen_t *addrlen, output_sockaddr_t *result);
void __wasi_sockets_utils__output_addr_write(
const network_ip_socket_address_t input, output_sockaddr_t *output);
int __wasi_sockets_utils__posix_family(network_ip_address_family_t wasi_family);
network_ip_socket_address_t
__wasi_sockets_utils__any_addr(network_ip_address_family_t family);
int __wasi_sockets_utils__tcp_bind(tcp_socket_t *socket,
network_ip_socket_address_t *address);
int __wasi_sockets_utils__udp_bind(udp_socket_t *socket,
network_ip_socket_address_t *address);
bool __wasi_sockets_utils__stream(udp_socket_t *socket,
network_ip_socket_address_t *remote_address,
udp_socket_streams_t *result,
network_error_code_t *error);
void __wasi_sockets_utils__drop_streams(udp_socket_streams_t streams);

#endif
34 changes: 34 additions & 0 deletions libc-bottom-half/headers/public/__header_sys_socket.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef __wasilibc___header_sys_socket_h
#define __wasilibc___header_sys_socket_h

#include <__wasi_snapshot.h>
#include <__struct_msghdr.h>
#include <__struct_sockaddr.h>
#include <__struct_sockaddr_storage.h>
Expand All @@ -11,9 +12,42 @@
#define SHUT_WR __WASI_SDFLAGS_WR
#define SHUT_RDWR (SHUT_RD | SHUT_WR)

#ifdef __wasilibc_use_wasip2
#define MSG_DONTWAIT 0x0040
#define MSG_NOSIGNAL 0x4000
#define MSG_PEEK 0x0002
#define MSG_WAITALL 0x0100
#define MSG_TRUNC 0x0020

#define SOL_IP 0
#define SOL_TCP 6
#define SOL_UDP 17
#define SOL_IPV6 41

#define SOMAXCONN 128

#define SO_REUSEADDR 2
#define SO_ERROR 4
#define SO_SNDBUF 7
#define SO_RCVBUF 8
#define SO_KEEPALIVE 9
#define SO_ACCEPTCONN 30
#define SO_PROTOCOL 38
#define SO_DOMAIN 39

#if __LONG_MAX == 0x7fffffff
#define SO_RCVTIMEO 66
#define SO_SNDTIMEO 67
#else
#define SO_RCVTIMEO 20
#define SO_SNDTIMEO 21
#endif

#else // __wasilibc_use_wasip2
#define MSG_PEEK __WASI_RIFLAGS_RECV_PEEK
#define MSG_WAITALL __WASI_RIFLAGS_RECV_WAITALL
#define MSG_TRUNC __WASI_ROFLAGS_RECV_DATA_TRUNCATED
#endif // __wasilibc_use_wasip2

#define SOCK_DGRAM __WASI_FILETYPE_SOCKET_DGRAM
#define SOCK_STREAM __WASI_FILETYPE_SOCKET_STREAM
Expand Down
5 changes: 5 additions & 0 deletions libc-bottom-half/headers/public/__wasi_snapshot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* This file is (practically) empty by default. The Makefile will replace it
with a non-empty version that defines `__wasilibc_use_wasip2` if targeting
`wasm32-wasip2`.
*/

Loading

0 comments on commit 684f155

Please sign in to comment.