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:
Marcin Kolny
2022-09-16 04:09:03 +01:00
committed by GitHub
parent 4de5b52ba0
commit f96773410a
4 changed files with 22 additions and 13 deletions

View File

@ -45,10 +45,12 @@ main(int argc, char *argv[])
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
af = AF_INET6;
len = sizeof(struct sockaddr_in6);
init_sockaddr_inet6((struct sockaddr_in6 *)&server_address);
}
else {
af = AF_INET;
len = sizeof(struct sockaddr_in);
init_sockaddr_inet((struct sockaddr_in *)&server_address);
}
@ -60,9 +62,7 @@ main(int argc, char *argv[])
}
printf("[Client] Connect socket\n");
if (connect(socket_fd, (struct sockaddr *)&server_address,
sizeof(server_address))
== -1) {
if (connect(socket_fd, (struct sockaddr *)&server_address, len) == -1) {
perror("Connect failed");
close(socket_fd);
return EXIT_FAILURE;

View File

@ -73,10 +73,12 @@ main(int argc, char *argv[])
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
af = AF_INET6;
addrlen = sizeof(struct sockaddr_in6);
init_sockaddr_inet6((struct sockaddr_in6 *)&addr);
}
else {
af = AF_INET;
addrlen = sizeof(struct sockaddr_in6);
init_sockaddr_inet((struct sockaddr_in *)&addr);
}
@ -88,7 +90,6 @@ main(int argc, char *argv[])
}
printf("[Server] Bind socket\n");
addrlen = sizeof(addr);
if (bind(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) {
perror("Bind failed");
goto fail;
@ -102,6 +103,7 @@ main(int argc, char *argv[])
printf("[Server] Wait for clients to connect ..\n");
while (connections < WORKER_NUM) {
addrlen = sizeof(struct sockaddr);
client_sock_fds[connections] =
accept(socket_fd, (struct sockaddr *)&addr, (socklen_t *)&addrlen);
if (client_sock_fds[connections] < 0) {

View File

@ -48,10 +48,12 @@ main(int argc, char *argv[])
if (argc > 1 && strcmp(argv[1], "inet6") == 0) {
af = AF_INET6;
addrlen = sizeof(struct sockaddr_in6);
init_sockaddr_inet6((struct sockaddr_in6 *)&addr);
}
else {
af = AF_INET;
addrlen = sizeof(struct sockaddr_in);
init_sockaddr_inet((struct sockaddr_in *)&addr);
}
@ -63,7 +65,6 @@ main(int argc, char *argv[])
}
printf("[Server] Bind socket\n");
addrlen = sizeof(addr);
if (bind(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) {
perror("Bind failed");
goto fail;
@ -71,6 +72,7 @@ main(int argc, char *argv[])
printf("[Server] Wait for clients to connect ..\n");
while (connections < MAX_CONNECTIONS_COUNT) {
addrlen = sizeof(addr);
int ret = recvfrom(socket_fd, buffer, sizeof(buffer), 0,
(struct sockaddr *)&addr, &addrlen);
if (ret < 0) {