Skip to content

Commit f967734

Browse files
authored
Fix bind() calls to receive the correct size of sockaddr structure (#1490)
For some implementations (e.g. Mac OS) `bind()` requires the length to be exactly equal to either `sockaddr_in` or `sockaddr_in6` structure. Because we always used `sizeof(struct sockaddr_storage)`, `bind()` was returning errors. In this change we fix the behavior. See StackOverflow [1] for details. [1] https://stackoverflow.com/questions/73707162/socket-bind-failed-with-invalid-argument-error-for-program-running-on-macos
1 parent 4de5b52 commit f967734

File tree

4 files changed

+22
-13
lines changed

4 files changed

+22
-13
lines changed

core/shared/platform/common/posix/posix_socket.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
#include <netinet/in.h>
1313

1414
static bool
15-
textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr *out)
15+
textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr *out,
16+
socklen_t *out_len)
1617
{
1718
struct sockaddr_in *v4;
1819
struct sockaddr_in6 *v6;
@@ -23,13 +24,15 @@ textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr *out)
2324
if (inet_pton(AF_INET, textual, &v4->sin_addr.s_addr) == 1) {
2425
v4->sin_family = AF_INET;
2526
v4->sin_port = htons(port);
27+
*out_len = sizeof(struct sockaddr_in);
2628
return true;
2729
}
2830

2931
v6 = (struct sockaddr_in6 *)out;
3032
if (inet_pton(AF_INET6, textual, &v6->sin6_addr.s6_addr) == 1) {
3133
v6->sin6_family = AF_INET6;
3234
v6->sin6_port = htons(port);
35+
*out_len = sizeof(struct sockaddr_in6);
3336
return true;
3437
}
3538

@@ -129,7 +132,7 @@ os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
129132
int
130133
os_socket_bind(bh_socket_t socket, const char *host, int *port)
131134
{
132-
struct sockaddr_storage addr;
135+
struct sockaddr_storage addr = { 0 };
133136
struct linger ling;
134137
socklen_t socklen;
135138
int ret;
@@ -150,11 +153,12 @@ os_socket_bind(bh_socket_t socket, const char *host, int *port)
150153
goto fail;
151154
}
152155

153-
if (!textual_addr_to_sockaddr(host, *port, (struct sockaddr *)&addr)) {
156+
if (!textual_addr_to_sockaddr(host, *port, (struct sockaddr *)&addr,
157+
&socklen)) {
154158
goto fail;
155159
}
156160

157-
ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr));
161+
ret = bind(socket, (struct sockaddr *)&addr, socklen);
158162
if (ret < 0) {
159163
goto fail;
160164
}
@@ -220,10 +224,11 @@ int
220224
os_socket_connect(bh_socket_t socket, const char *addr, int port)
221225
{
222226
struct sockaddr_storage addr_in = { 0 };
223-
socklen_t addr_len = sizeof(struct sockaddr_storage);
227+
socklen_t addr_len;
224228
int ret = 0;
225229

226-
if (!textual_addr_to_sockaddr(addr, port, (struct sockaddr *)&addr_in)) {
230+
if (!textual_addr_to_sockaddr(addr, port, (struct sockaddr *)&addr_in,
231+
&addr_len)) {
227232
return BHT_ERROR;
228233
}
229234

@@ -245,7 +250,7 @@ int
245250
os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
246251
bh_sockaddr_t *src_addr)
247252
{
248-
struct sockaddr_storage sock_addr = {};
253+
struct sockaddr_storage sock_addr = { 0 };
249254
socklen_t socklen = sizeof(sock_addr);
250255
int ret;
251256

@@ -274,7 +279,7 @@ int
274279
os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
275280
int flags, const bh_sockaddr_t *dest_addr)
276281
{
277-
struct sockaddr_storage sock_addr = {};
282+
struct sockaddr_storage sock_addr = { 0 };
278283
socklen_t socklen = 0;
279284

280285
bh_sockaddr_to_sockaddr(dest_addr, &sock_addr, &socklen);

samples/socket-api/wasm-src/tcp_client.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,12 @@ main(int argc, char *argv[])
4545

4646
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
4747
af = AF_INET6;
48+
len = sizeof(struct sockaddr_in6);
4849
init_sockaddr_inet6((struct sockaddr_in6 *)&server_address);
4950
}
5051
else {
5152
af = AF_INET;
53+
len = sizeof(struct sockaddr_in);
5254
init_sockaddr_inet((struct sockaddr_in *)&server_address);
5355
}
5456

@@ -60,9 +62,7 @@ main(int argc, char *argv[])
6062
}
6163

6264
printf("[Client] Connect socket\n");
63-
if (connect(socket_fd, (struct sockaddr *)&server_address,
64-
sizeof(server_address))
65-
== -1) {
65+
if (connect(socket_fd, (struct sockaddr *)&server_address, len) == -1) {
6666
perror("Connect failed");
6767
close(socket_fd);
6868
return EXIT_FAILURE;

samples/socket-api/wasm-src/tcp_server.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,12 @@ main(int argc, char *argv[])
7373

7474
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
7575
af = AF_INET6;
76+
addrlen = sizeof(struct sockaddr_in6);
7677
init_sockaddr_inet6((struct sockaddr_in6 *)&addr);
7778
}
7879
else {
7980
af = AF_INET;
81+
addrlen = sizeof(struct sockaddr_in6);
8082
init_sockaddr_inet((struct sockaddr_in *)&addr);
8183
}
8284

@@ -88,7 +90,6 @@ main(int argc, char *argv[])
8890
}
8991

9092
printf("[Server] Bind socket\n");
91-
addrlen = sizeof(addr);
9293
if (bind(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) {
9394
perror("Bind failed");
9495
goto fail;
@@ -102,6 +103,7 @@ main(int argc, char *argv[])
102103

103104
printf("[Server] Wait for clients to connect ..\n");
104105
while (connections < WORKER_NUM) {
106+
addrlen = sizeof(struct sockaddr);
105107
client_sock_fds[connections] =
106108
accept(socket_fd, (struct sockaddr *)&addr, (socklen_t *)&addrlen);
107109
if (client_sock_fds[connections] < 0) {

samples/socket-api/wasm-src/udp_server.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ main(int argc, char *argv[])
4848

4949
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
5050
af = AF_INET6;
51+
addrlen = sizeof(struct sockaddr_in6);
5152
init_sockaddr_inet6((struct sockaddr_in6 *)&addr);
5253
}
5354
else {
5455
af = AF_INET;
56+
addrlen = sizeof(struct sockaddr_in);
5557
init_sockaddr_inet((struct sockaddr_in *)&addr);
5658
}
5759

@@ -63,14 +65,14 @@ main(int argc, char *argv[])
6365
}
6466

6567
printf("[Server] Bind socket\n");
66-
addrlen = sizeof(addr);
6768
if (bind(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) {
6869
perror("Bind failed");
6970
goto fail;
7071
}
7172

7273
printf("[Server] Wait for clients to connect ..\n");
7374
while (connections < MAX_CONNECTIONS_COUNT) {
75+
addrlen = sizeof(addr);
7476
int ret = recvfrom(socket_fd, buffer, sizeof(buffer), 0,
7577
(struct sockaddr *)&addr, &addrlen);
7678
if (ret < 0) {

0 commit comments

Comments
 (0)