mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-09 13:16:26 +00:00
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
This commit is contained in:
parent
4de5b52ba0
commit
f96773410a
|
@ -12,7 +12,8 @@
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr *out)
|
textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr *out,
|
||||||
|
socklen_t *out_len)
|
||||||
{
|
{
|
||||||
struct sockaddr_in *v4;
|
struct sockaddr_in *v4;
|
||||||
struct sockaddr_in6 *v6;
|
struct sockaddr_in6 *v6;
|
||||||
|
@ -23,6 +24,7 @@ textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr *out)
|
||||||
if (inet_pton(AF_INET, textual, &v4->sin_addr.s_addr) == 1) {
|
if (inet_pton(AF_INET, textual, &v4->sin_addr.s_addr) == 1) {
|
||||||
v4->sin_family = AF_INET;
|
v4->sin_family = AF_INET;
|
||||||
v4->sin_port = htons(port);
|
v4->sin_port = htons(port);
|
||||||
|
*out_len = sizeof(struct sockaddr_in);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +32,7 @@ textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr *out)
|
||||||
if (inet_pton(AF_INET6, textual, &v6->sin6_addr.s6_addr) == 1) {
|
if (inet_pton(AF_INET6, textual, &v6->sin6_addr.s6_addr) == 1) {
|
||||||
v6->sin6_family = AF_INET6;
|
v6->sin6_family = AF_INET6;
|
||||||
v6->sin6_port = htons(port);
|
v6->sin6_port = htons(port);
|
||||||
|
*out_len = sizeof(struct sockaddr_in6);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +132,7 @@ os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
|
||||||
int
|
int
|
||||||
os_socket_bind(bh_socket_t socket, const char *host, int *port)
|
os_socket_bind(bh_socket_t socket, const char *host, int *port)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr = { 0 };
|
||||||
struct linger ling;
|
struct linger ling;
|
||||||
socklen_t socklen;
|
socklen_t socklen;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -150,11 +153,12 @@ os_socket_bind(bh_socket_t socket, const char *host, int *port)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!textual_addr_to_sockaddr(host, *port, (struct sockaddr *)&addr)) {
|
if (!textual_addr_to_sockaddr(host, *port, (struct sockaddr *)&addr,
|
||||||
|
&socklen)) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr));
|
ret = bind(socket, (struct sockaddr *)&addr, socklen);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -220,10 +224,11 @@ int
|
||||||
os_socket_connect(bh_socket_t socket, const char *addr, int port)
|
os_socket_connect(bh_socket_t socket, const char *addr, int port)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage addr_in = { 0 };
|
struct sockaddr_storage addr_in = { 0 };
|
||||||
socklen_t addr_len = sizeof(struct sockaddr_storage);
|
socklen_t addr_len;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!textual_addr_to_sockaddr(addr, port, (struct sockaddr *)&addr_in)) {
|
if (!textual_addr_to_sockaddr(addr, port, (struct sockaddr *)&addr_in,
|
||||||
|
&addr_len)) {
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +250,7 @@ int
|
||||||
os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
|
os_socket_recv_from(bh_socket_t socket, void *buf, unsigned int len, int flags,
|
||||||
bh_sockaddr_t *src_addr)
|
bh_sockaddr_t *src_addr)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage sock_addr = {};
|
struct sockaddr_storage sock_addr = { 0 };
|
||||||
socklen_t socklen = sizeof(sock_addr);
|
socklen_t socklen = sizeof(sock_addr);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -274,7 +279,7 @@ int
|
||||||
os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
|
os_socket_send_to(bh_socket_t socket, const void *buf, unsigned int len,
|
||||||
int flags, const bh_sockaddr_t *dest_addr)
|
int flags, const bh_sockaddr_t *dest_addr)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage sock_addr = {};
|
struct sockaddr_storage sock_addr = { 0 };
|
||||||
socklen_t socklen = 0;
|
socklen_t socklen = 0;
|
||||||
|
|
||||||
bh_sockaddr_to_sockaddr(dest_addr, &sock_addr, &socklen);
|
bh_sockaddr_to_sockaddr(dest_addr, &sock_addr, &socklen);
|
||||||
|
|
|
@ -45,10 +45,12 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
|
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
|
||||||
af = AF_INET6;
|
af = AF_INET6;
|
||||||
|
len = sizeof(struct sockaddr_in6);
|
||||||
init_sockaddr_inet6((struct sockaddr_in6 *)&server_address);
|
init_sockaddr_inet6((struct sockaddr_in6 *)&server_address);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
af = AF_INET;
|
af = AF_INET;
|
||||||
|
len = sizeof(struct sockaddr_in);
|
||||||
init_sockaddr_inet((struct sockaddr_in *)&server_address);
|
init_sockaddr_inet((struct sockaddr_in *)&server_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,9 +62,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[Client] Connect socket\n");
|
printf("[Client] Connect socket\n");
|
||||||
if (connect(socket_fd, (struct sockaddr *)&server_address,
|
if (connect(socket_fd, (struct sockaddr *)&server_address, len) == -1) {
|
||||||
sizeof(server_address))
|
|
||||||
== -1) {
|
|
||||||
perror("Connect failed");
|
perror("Connect failed");
|
||||||
close(socket_fd);
|
close(socket_fd);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
|
@ -73,10 +73,12 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
|
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
|
||||||
af = AF_INET6;
|
af = AF_INET6;
|
||||||
|
addrlen = sizeof(struct sockaddr_in6);
|
||||||
init_sockaddr_inet6((struct sockaddr_in6 *)&addr);
|
init_sockaddr_inet6((struct sockaddr_in6 *)&addr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
af = AF_INET;
|
af = AF_INET;
|
||||||
|
addrlen = sizeof(struct sockaddr_in6);
|
||||||
init_sockaddr_inet((struct sockaddr_in *)&addr);
|
init_sockaddr_inet((struct sockaddr_in *)&addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +90,6 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[Server] Bind socket\n");
|
printf("[Server] Bind socket\n");
|
||||||
addrlen = sizeof(addr);
|
|
||||||
if (bind(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) {
|
if (bind(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) {
|
||||||
perror("Bind failed");
|
perror("Bind failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -102,6 +103,7 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
printf("[Server] Wait for clients to connect ..\n");
|
printf("[Server] Wait for clients to connect ..\n");
|
||||||
while (connections < WORKER_NUM) {
|
while (connections < WORKER_NUM) {
|
||||||
|
addrlen = sizeof(struct sockaddr);
|
||||||
client_sock_fds[connections] =
|
client_sock_fds[connections] =
|
||||||
accept(socket_fd, (struct sockaddr *)&addr, (socklen_t *)&addrlen);
|
accept(socket_fd, (struct sockaddr *)&addr, (socklen_t *)&addrlen);
|
||||||
if (client_sock_fds[connections] < 0) {
|
if (client_sock_fds[connections] < 0) {
|
||||||
|
|
|
@ -48,10 +48,12 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
|
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
|
||||||
af = AF_INET6;
|
af = AF_INET6;
|
||||||
|
addrlen = sizeof(struct sockaddr_in6);
|
||||||
init_sockaddr_inet6((struct sockaddr_in6 *)&addr);
|
init_sockaddr_inet6((struct sockaddr_in6 *)&addr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
af = AF_INET;
|
af = AF_INET;
|
||||||
|
addrlen = sizeof(struct sockaddr_in);
|
||||||
init_sockaddr_inet((struct sockaddr_in *)&addr);
|
init_sockaddr_inet((struct sockaddr_in *)&addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +65,6 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[Server] Bind socket\n");
|
printf("[Server] Bind socket\n");
|
||||||
addrlen = sizeof(addr);
|
|
||||||
if (bind(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) {
|
if (bind(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) {
|
||||||
perror("Bind failed");
|
perror("Bind failed");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -71,6 +72,7 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
printf("[Server] Wait for clients to connect ..\n");
|
printf("[Server] Wait for clients to connect ..\n");
|
||||||
while (connections < MAX_CONNECTIONS_COUNT) {
|
while (connections < MAX_CONNECTIONS_COUNT) {
|
||||||
|
addrlen = sizeof(addr);
|
||||||
int ret = recvfrom(socket_fd, buffer, sizeof(buffer), 0,
|
int ret = recvfrom(socket_fd, buffer, sizeof(buffer), 0,
|
||||||
(struct sockaddr *)&addr, &addrlen);
|
(struct sockaddr *)&addr, &addrlen);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user