[mdns] connection test: don't wait if connect() succeeds immediately

This commit is contained in:
ejurgensen 2018-09-10 19:42:04 +02:00
parent 475c598d0e
commit 2c1f2f1b15

View File

@ -499,34 +499,40 @@ connection_test(int family, const char *address, const char *address_log, int po
ret = getaddrinfo(address, strport, &hints, &ai); ret = getaddrinfo(address, strport, &hints, &ai);
if (ret < 0) if (ret < 0)
{ {
DPRINTF(E_DBG, L_MDNS, "Connection test to %s:%d failed with getaddrinfo error: %s\n", address_log, port, gai_strerror(ret)); DPRINTF(E_WARN, L_MDNS, "Connection test to %s:%d failed with getaddrinfo error: %s\n", address_log, port, gai_strerror(ret));
return -1; return -1;
} }
sock = socket(ai->ai_family, ai->ai_socktype | SOCK_NONBLOCK, ai->ai_protocol); sock = socket(ai->ai_family, ai->ai_socktype | SOCK_NONBLOCK, ai->ai_protocol);
if (sock < 0) if (sock < 0)
{ {
DPRINTF(E_DBG, L_MDNS, "Connection test to %s:%d failed with socket error: %s\n", address_log, port, strerror(errno)); 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; goto out_free_ai;
} }
ret = connect(sock, ai->ai_addr, ai->ai_addrlen); ret = connect(sock, ai->ai_addr, ai->ai_addrlen);
if (ret < 0 && errno != EALREADY && errno != EINPROGRESS) if (ret < 0 && errno != EINPROGRESS)
{ {
DPRINTF(E_DBG, L_MDNS, "Connection test to %s:%d failed with connect error: %s\n", address_log, port, strerror(errno)); DPRINTF(E_WARN, L_MDNS, "Connection test to %s:%d failed with connect error: %s\n", address_log, port, strerror(errno));
goto out_close_socket; goto out_close_socket;
} }
// We often need to wait for the connection. On Linux this seems always to be
// the case, but FreeBSD connect() sometimes returns immediate success.
if (ret != 0)
{
FD_ZERO(&fdset); FD_ZERO(&fdset);
FD_SET(sock, &fdset); FD_SET(sock, &fdset);
ret = select(sock + 1, NULL, &fdset, NULL, &timeout); ret = select(sock + 1, NULL, &fdset, NULL, &timeout);
if (ret != 1) if (ret < 0)
{ {
if (errno == EINPROGRESS) DPRINTF(E_WARN, L_MDNS, "Connection test to %s:%d failed with select error: %s\n", address_log, port, strerror(errno));
DPRINTF(E_DBG, L_MDNS, "Connection test to %s:%d timed out (limit is %d seconds)\n", address_log, port, MDNS_CONNECT_TEST_TIMEOUT); goto out_close_socket;
else }
DPRINTF(E_DBG, L_MDNS, "Connection test to %s:%d failed with select error: %s\n", address_log, port, strerror(errno)); else if (ret == 0)
{
DPRINTF(E_WARN, L_MDNS, "Connection test to %s:%d timed out (limit is %d seconds)\n", address_log, port, MDNS_CONNECT_TEST_TIMEOUT);
goto out_close_socket; goto out_close_socket;
} }
@ -534,15 +540,15 @@ connection_test(int family, const char *address, const char *address_log, int po
ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len); ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len);
if (ret < 0) if (ret < 0)
{ {
DPRINTF(E_DBG, L_MDNS, "Connection test to %s:%d failed with getsockopt error: %s\n", address_log, port, strerror(errno)); DPRINTF(E_WARN, L_MDNS, "Connection test to %s:%d failed with getsockopt error: %s\n", address_log, port, strerror(errno));
goto out_close_socket; goto out_close_socket;
} }
else if (error)
if (error)
{ {
DPRINTF(E_DBG, L_MDNS, "Connection test to %s:%d failed with getsockopt return: %s\n", address_log, port, strerror(error)); DPRINTF(E_WARN, L_MDNS, "Connection test to %s:%d failed with getsockopt return: %s\n", address_log, port, strerror(error));
goto out_close_socket; goto out_close_socket;
} }
}
DPRINTF(E_DBG, L_MDNS, "Connection test to %s:%d completed successfully\n", address_log, port); DPRINTF(E_DBG, L_MDNS, "Connection test to %s:%d completed successfully\n", address_log, port);