Skip to content

Commit 684f155

Browse files
dicejbadeendsunfishcode
authored
implement basic TCP/UDP client support (#477)
* 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 <github@davebakker.io> Signed-off-by: Joel Dice <joel.dice@fermyon.com> * fix grammar in __wasi_snapshot.h comment Co-authored-by: Dan Gohman <dev@sunfishcode.online> Signed-off-by: Joel Dice <joel.dice@fermyon.com> --------- Signed-off-by: Joel Dice <joel.dice@fermyon.com> Co-authored-by: Dave Bakker <github@davebakker.io> Co-authored-by: Dan Gohman <dev@sunfishcode.online>
1 parent a963040 commit 684f155

17 files changed

Lines changed: 1377 additions & 14 deletions

File tree

Makefile

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,25 @@ ifeq ($(WASI_SNAPSHOT), p1)
8181
# this list.
8282
LIBC_BOTTOM_HALF_OMIT_SOURCES := \
8383
$(LIBC_BOTTOM_HALF_SOURCES)/wasip2.c \
84-
$(LIBC_BOTTOM_HALF_SOURCES)/descriptor_table.c
84+
$(LIBC_BOTTOM_HALF_SOURCES)/descriptor_table.c \
85+
$(LIBC_BOTTOM_HALF_SOURCES)/connect.c \
86+
$(LIBC_BOTTOM_HALF_SOURCES)/socket.c \
87+
$(LIBC_BOTTOM_HALF_SOURCES)/send.c \
88+
$(LIBC_BOTTOM_HALF_SOURCES)/recv.c \
89+
$(LIBC_BOTTOM_HALF_SOURCES)/sockets_utils.c
8590
LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_OMIT_SOURCES),$(LIBC_BOTTOM_HALF_ALL_SOURCES))
8691
# Omit p2-specific headers from include-all.c test.
8792
INCLUDE_ALL_CLAUSES := -not -name wasip2.h -not -name descriptor_table.h
8893
endif
8994

95+
ifeq ($(WASI_SNAPSHOT), p2)
96+
# Omit source files not relevant to WASIp2.
97+
LIBC_BOTTOM_HALF_OMIT_SOURCES := \
98+
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/send.c \
99+
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/recv.c
100+
LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_OMIT_SOURCES),$(LIBC_BOTTOM_HALF_ALL_SOURCES))
101+
endif
102+
90103
# FIXME(https://reviews.llvm.org/D85567) - due to a bug in LLD the weak
91104
# references to a function defined in `chdir.c` only work if `chdir.c` is at the
92105
# end of the archive, but once that LLD review lands and propagates into LLVM
@@ -687,6 +700,10 @@ include_dirs:
687700

688701
# Remove selected header files.
689702
$(RM) $(patsubst %,$(SYSROOT_INC)/%,$(MUSL_OMIT_HEADERS))
703+
ifeq ($(WASI_SNAPSHOT), p2)
704+
printf '#ifndef __wasilibc_use_wasip2\n#define __wasilibc_use_wasip2\n#endif\n' \
705+
> "$(SYSROOT_INC)/__wasi_snapshot.h"
706+
endif
690707

691708
startup_files: include_dirs $(LIBC_BOTTOM_HALF_CRT_OBJS)
692709
#

expected/wasm32-wasip1-threads/include-all.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include <__typedef_suseconds_t.h>
6161
#include <__typedef_time_t.h>
6262
#include <__typedef_uid_t.h>
63+
#include <__wasi_snapshot.h>
6364
#include <alloca.h>
6465
#include <ar.h>
6566
#include <arpa/ftp.h>

expected/wasm32-wasip1/include-all.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include <__typedef_suseconds_t.h>
6161
#include <__typedef_time_t.h>
6262
#include <__typedef_uid_t.h>
63+
#include <__wasi_snapshot.h>
6364
#include <alloca.h>
6465
#include <ar.h>
6566
#include <arpa/ftp.h>

expected/wasm32-wasip2/defined-symbols.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,18 @@ __wasi_sock_accept
300300
__wasi_sock_recv
301301
__wasi_sock_send
302302
__wasi_sock_shutdown
303+
__wasi_sockets_utils__any_addr
304+
__wasi_sockets_utils__borrow_network
305+
__wasi_sockets_utils__create_streams
306+
__wasi_sockets_utils__drop_streams
307+
__wasi_sockets_utils__map_error
308+
__wasi_sockets_utils__output_addr_validate
309+
__wasi_sockets_utils__output_addr_write
310+
__wasi_sockets_utils__parse_address
311+
__wasi_sockets_utils__posix_family
312+
__wasi_sockets_utils__stream
313+
__wasi_sockets_utils__tcp_bind
314+
__wasi_sockets_utils__udp_bind
303315
__wasilibc_access
304316
__wasilibc_cwd
305317
__wasilibc_deinitialize_environ
@@ -470,6 +482,7 @@ confstr
470482
conj
471483
conjf
472484
conjl
485+
connect
473486
copysign
474487
copysignf
475488
copysignl
@@ -1047,6 +1060,7 @@ realloc
10471060
reallocarray
10481061
realpath
10491062
recv
1063+
recvfrom
10501064
regcomp
10511065
regerror
10521066
regexec
@@ -1088,6 +1102,7 @@ seed48
10881102
seekdir
10891103
select
10901104
send
1105+
sendto
10911106
setbuf
10921107
setbuffer
10931108
setenv
@@ -1112,6 +1127,7 @@ sinhl
11121127
sinl
11131128
sleep
11141129
snprintf
1130+
socket
11151131
sprintf
11161132
sqrt
11171133
sqrtf

expected/wasm32-wasip2/include-all.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include <__typedef_suseconds_t.h>
6161
#include <__typedef_time_t.h>
6262
#include <__typedef_uid_t.h>
63+
#include <__wasi_snapshot.h>
6364
#include <alloca.h>
6465
#include <ar.h>
6566
#include <arpa/ftp.h>

expected/wasm32-wasip2/predefined-macros.txt

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,10 +1162,12 @@
11621162
#define MOREDATA 2
11631163
#define MSG_ANY 0x02
11641164
#define MSG_BAND 0x04
1165+
#define MSG_DONTWAIT 0x0040
11651166
#define MSG_HIPRI 0x01
1166-
#define MSG_PEEK __WASI_RIFLAGS_RECV_PEEK
1167-
#define MSG_TRUNC __WASI_ROFLAGS_RECV_DATA_TRUNCATED
1168-
#define MSG_WAITALL __WASI_RIFLAGS_RECV_WAITALL
1167+
#define MSG_NOSIGNAL 0x4000
1168+
#define MSG_PEEK 0x0002
1169+
#define MSG_TRUNC 0x0020
1170+
#define MSG_WAITALL 0x0100
11691171
#define MUXID_ALL (-1)
11701172
#define M_1_PI 0.31830988618379067154
11711173
#define M_2_PI 0.63661977236758134308
@@ -1701,9 +1703,22 @@
17011703
#define SOCK_DGRAM __WASI_FILETYPE_SOCKET_DGRAM
17021704
#define SOCK_NONBLOCK (0x00004000)
17031705
#define SOCK_STREAM __WASI_FILETYPE_SOCKET_STREAM
1706+
#define SOL_IP 0
1707+
#define SOL_IPV6 41
17041708
#define SOL_SOCKET 0x7fffffff
17051709
#define SOL_TCP 6
17061710
#define SOL_UDP 17
1711+
#define SOMAXCONN 128
1712+
#define SO_ACCEPTCONN 30
1713+
#define SO_DOMAIN 39
1714+
#define SO_ERROR 4
1715+
#define SO_KEEPALIVE 9
1716+
#define SO_PROTOCOL 38
1717+
#define SO_RCVBUF 8
1718+
#define SO_RCVTIMEO 66
1719+
#define SO_REUSEADDR 2
1720+
#define SO_SNDBUF 7
1721+
#define SO_SNDTIMEO 67
17071722
#define SO_TYPE 3
17081723
#define SSIZE_MAX LONG_MAX
17091724
#define STATUS ns_o_status
@@ -3110,7 +3125,7 @@
31103125
#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) ))
31113126
#define __tm_gmtoff tm_gmtoff
31123127
#define __tm_zone tm_zone
3113-
#define __va_copy(d,s) __builtin_va_copy(d,s)
3128+
#define __va_copy(d,s) __builtin_va_copy(d, s)
31143129
#define __wasi__ 1
31153130
#define __wasi_api_h
31163131
#define __wasi_libc_environ_h
@@ -3179,6 +3194,7 @@
31793194
#define __wasilibc___typedef_suseconds_t_h
31803195
#define __wasilibc___typedef_time_t_h
31813196
#define __wasilibc___typedef_uid_t_h
3197+
#define __wasilibc_use_wasip2
31823198
#define __wasm 1
31833199
#define __wasm32 1
31843200
#define __wasm32__ 1
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#ifndef __wasi_sockets_utils_h
2+
#define __wasi_sockets_utils_h
3+
4+
#include <netinet/in.h>
5+
6+
#include <wasi/descriptor_table.h>
7+
8+
typedef struct {
9+
enum {
10+
OUTPUT_SOCKADDR_NULL,
11+
OUTPUT_SOCKADDR_V4,
12+
OUTPUT_SOCKADDR_V6,
13+
} tag;
14+
union {
15+
struct {
16+
int dummy;
17+
} null;
18+
struct {
19+
struct sockaddr_in *addr;
20+
socklen_t *addrlen;
21+
} v4;
22+
struct {
23+
struct sockaddr_in6 *addr;
24+
socklen_t *addrlen;
25+
} v6;
26+
};
27+
} output_sockaddr_t;
28+
29+
network_borrow_network_t __wasi_sockets_utils__borrow_network();
30+
int __wasi_sockets_utils__map_error(network_error_code_t wasi_error);
31+
bool __wasi_sockets_utils__parse_address(
32+
network_ip_address_family_t expected_family,
33+
const struct sockaddr *address, socklen_t len,
34+
network_ip_socket_address_t *result, int *error);
35+
bool __wasi_sockets_utils__output_addr_validate(
36+
network_ip_address_family_t expected_family, struct sockaddr *addr,
37+
socklen_t *addrlen, output_sockaddr_t *result);
38+
void __wasi_sockets_utils__output_addr_write(
39+
const network_ip_socket_address_t input, output_sockaddr_t *output);
40+
int __wasi_sockets_utils__posix_family(network_ip_address_family_t wasi_family);
41+
network_ip_socket_address_t
42+
__wasi_sockets_utils__any_addr(network_ip_address_family_t family);
43+
int __wasi_sockets_utils__tcp_bind(tcp_socket_t *socket,
44+
network_ip_socket_address_t *address);
45+
int __wasi_sockets_utils__udp_bind(udp_socket_t *socket,
46+
network_ip_socket_address_t *address);
47+
bool __wasi_sockets_utils__stream(udp_socket_t *socket,
48+
network_ip_socket_address_t *remote_address,
49+
udp_socket_streams_t *result,
50+
network_error_code_t *error);
51+
void __wasi_sockets_utils__drop_streams(udp_socket_streams_t streams);
52+
53+
#endif

libc-bottom-half/headers/public/__header_sys_socket.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef __wasilibc___header_sys_socket_h
22
#define __wasilibc___header_sys_socket_h
33

4+
#include <__wasi_snapshot.h>
45
#include <__struct_msghdr.h>
56
#include <__struct_sockaddr.h>
67
#include <__struct_sockaddr_storage.h>
@@ -11,9 +12,42 @@
1112
#define SHUT_WR __WASI_SDFLAGS_WR
1213
#define SHUT_RDWR (SHUT_RD | SHUT_WR)
1314

15+
#ifdef __wasilibc_use_wasip2
16+
#define MSG_DONTWAIT 0x0040
17+
#define MSG_NOSIGNAL 0x4000
18+
#define MSG_PEEK 0x0002
19+
#define MSG_WAITALL 0x0100
20+
#define MSG_TRUNC 0x0020
21+
22+
#define SOL_IP 0
23+
#define SOL_TCP 6
24+
#define SOL_UDP 17
25+
#define SOL_IPV6 41
26+
27+
#define SOMAXCONN 128
28+
29+
#define SO_REUSEADDR 2
30+
#define SO_ERROR 4
31+
#define SO_SNDBUF 7
32+
#define SO_RCVBUF 8
33+
#define SO_KEEPALIVE 9
34+
#define SO_ACCEPTCONN 30
35+
#define SO_PROTOCOL 38
36+
#define SO_DOMAIN 39
37+
38+
#if __LONG_MAX == 0x7fffffff
39+
#define SO_RCVTIMEO 66
40+
#define SO_SNDTIMEO 67
41+
#else
42+
#define SO_RCVTIMEO 20
43+
#define SO_SNDTIMEO 21
44+
#endif
45+
46+
#else // __wasilibc_use_wasip2
1447
#define MSG_PEEK __WASI_RIFLAGS_RECV_PEEK
1548
#define MSG_WAITALL __WASI_RIFLAGS_RECV_WAITALL
1649
#define MSG_TRUNC __WASI_ROFLAGS_RECV_DATA_TRUNCATED
50+
#endif // __wasilibc_use_wasip2
1751

1852
#define SOCK_DGRAM __WASI_FILETYPE_SOCKET_DGRAM
1953
#define SOCK_STREAM __WASI_FILETYPE_SOCKET_STREAM
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/* This file is (practically) empty by default. The Makefile will replace it
2+
with a non-empty version that defines `__wasilibc_use_wasip2` if targeting
3+
`wasm32-wasip2`.
4+
*/
5+

0 commit comments

Comments
 (0)