[misc] Use fcntl+O_NONBLOCK when binding instead of socket+SOCK_NONBLOCK

socket() with SOCK_NONBLOCK (O_NONBLOCK) seems not to be possible on MacOS, it
yields 'Protocol wrong type for socket'. Switch to using fcntl() and O_NONBLOCK
instead, hopefully works better cross-platform.

Closes #1644
This commit is contained in:
ejurgensen
2023-08-31 17:16:22 +02:00
parent 9d092c983b
commit 54c2667aea
5 changed files with 63 additions and 20 deletions

View File

@@ -35,6 +35,7 @@
#include <arpa/inet.h>
#include <net/if.h>
#include <unistd.h>
#include <fcntl.h>
#include <event2/event.h>
@@ -584,6 +585,7 @@ connection_test(int family, const char *address, const char *address_log, int po
fd_set fdset;
struct timeval timeout = { MDNS_CONNECT_TEST_TIMEOUT, 0 };
socklen_t len;
int flags;
int error;
int retval;
int ret;
@@ -603,13 +605,29 @@ connection_test(int family, const char *address, const char *address_log, int po
return -1;
}
sock = socket(ai->ai_family, ai->ai_socktype | SOCK_NONBLOCK, ai->ai_protocol);
sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sock < 0)
{
DPRINTF(E_WARN, L_MDNS, "Connection test to %s:%d failed with socket error: %s\n", address_log, port, strerror(errno));
goto out_free_ai;
}
// For Linux we could just give SOCK_NONBLOCK to socket(), but that won't work
// with MacOS, so we have to use fcntl()
flags = fcntl(sock, F_GETFL, 0);
if (flags < 0)
{
DPRINTF(E_WARN, L_MDNS, "Connection test to %s:%d failed with fcntl get flags error: %s\n", address_log, port, strerror(errno));
goto out_close_socket;
}
ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
if (ret < 0)
{
DPRINTF(E_WARN, L_MDNS, "Connection test to %s:%d failed with fcntl set flags error: %s\n", address_log, port, strerror(errno));
goto out_close_socket;
}
ret = connect(sock, ai->ai_addr, ai->ai_addrlen);
if (ret < 0 && errno != EINPROGRESS)
{