diff --git a/doc/xml/release/2023/2.48.xml b/doc/xml/release/2023/2.48.xml index 468bcf217..e8f7b6179 100644 --- a/doc/xml/release/2023/2.48.xml +++ b/doc/xml/release/2023/2.48.xml @@ -1,6 +1,25 @@ + + + + + + + + + + + + + + + + +

Support for dual stack connections.

+
+ diff --git a/src/common/io/socket/client.c b/src/common/io/socket/client.c index 3b8c25f8a..8f75e2ed3 100644 --- a/src/common/io/socket/client.c +++ b/src/common/io/socket/client.c @@ -9,6 +9,7 @@ Socket Client #include #include "common/debug.h" +#include "common/error/retry.h" #include "common/io/client.h" #include "common/io/socket/address.h" #include "common/io/socket/client.h" @@ -72,8 +73,13 @@ sckClientOpen(THIS_VOID) MEM_CONTEXT_TEMP_BEGIN() { + Wait *const wait = waitNew(this->timeoutConnect); + ErrorRetry *const errRetry = errRetryNew(); bool retry; - Wait *wait = waitNew(this->timeoutConnect); + + // Get an address list for the host + const AddressInfo *const addrInfo = addrInfoNew(this->host, this->port); + unsigned int addrInfoIdx = 0; do { @@ -83,8 +89,8 @@ sckClientOpen(THIS_VOID) TRY_BEGIN() { - // Get an address for the host. We are only going to try the first address returned. - const struct addrinfo *const addressFound = addrInfoGet(addrInfoNew(this->host, this->port), 0); + // Get next address for the host + const struct addrinfo *const addressFound = addrInfoGet(addrInfo, addrInfoIdx); // Connect to the host fd = socket(addressFound->ai_family, addressFound->ai_socktype, addressFound->ai_protocol); @@ -106,19 +112,32 @@ sckClientOpen(THIS_VOID) } CATCH_ANY() { - if (fd != -1) - close(fd); + // Close socket + close(fd); - // Retry if wait time has not expired - if (waitMore(wait)) + // Add the error retry info + errRetryAdd(errRetry); + + // Increment address info index and reset if the end has been reached. When the end has been reached sleep for a bit + // to hopefully have better chance at succeeding, otherwise continue right to the next address as long as there is + // some time left. + addrInfoIdx++; + + if (addrInfoIdx >= addrInfoSize(addrInfo)) { - LOG_DEBUG_FMT("retry %s: %s", errorTypeName(errorType()), errorMessage()); - retry = true; - - statInc(SOCKET_STAT_RETRY_STR); + addrInfoIdx = 0; + retry = waitMore(wait); } else - RETHROW(); + retry = waitRemaining(wait) > 0; + + // Error when no retries remain + if (!retry) + THROWP(errRetryType(errRetry), strZ(errRetryMessage(errRetry))); + + // Log retry + LOG_DEBUG_FMT("retry %s: %s", errorTypeName(errorType()), errorMessage()); + statInc(SOCKET_STAT_RETRY_STR); } TRY_END(); } diff --git a/test/src/module/common/ioHttpTest.c b/test/src/module/common/ioHttpTest.c index bc87b5783..a10ba5a0d 100644 --- a/test/src/module/common/ioHttpTest.c +++ b/test/src/module/common/ioHttpTest.c @@ -306,7 +306,8 @@ testRun(void) TEST_ERROR_FMT( httpRequestResponse(httpRequestNewP(client, STRDEF("GET"), STRDEF("/")), false), HostConnectError, - "unable to connect to 'localhost:%u (127.0.0.1)': [111] Connection refused", + "unable to connect to 'localhost:%u (127.0.0.1)': [111] Connection refused\n" + "[RETRY DETAIL OMITTED]", hrnServerPort(0)); HRN_FORK_BEGIN() diff --git a/test/src/module/common/ioTlsTest.c b/test/src/module/common/ioTlsTest.c index 424e00e13..bedd5f054 100644 --- a/test/src/module/common/ioTlsTest.c +++ b/test/src/module/common/ioTlsTest.c @@ -368,7 +368,9 @@ testRun(void) TEST_ASSIGN(client, sckClientNew(STRDEF("localhost"), hrnServerPort(0), 100, 100), "new client"); TEST_ERROR_FMT( - ioClientOpen(client), HostConnectError, "unable to connect to 'localhost:%u (127.0.0.1)': [111] Connection refused", + ioClientOpen(client), HostConnectError, + "unable to connect to 'localhost:%u (127.0.0.1)': [111] Connection refused\n" + "[RETRY DETAIL OMITTED]", hrnServerPort(0)); // This address should not be in use in a test environment -- if it is the test will fail @@ -451,7 +453,9 @@ testRun(void) client, tlsClientNewP(sckClientNew(STRDEF("localhost"), hrnServerPort(0), 100, 100), STRDEF("X"), 100, 100, true), "new client"); TEST_ERROR_FMT( - ioClientOpen(client), HostConnectError, "unable to connect to 'localhost:%u (127.0.0.1)': [111] Connection refused", + ioClientOpen(client), HostConnectError, + "unable to connect to 'localhost:%u (127.0.0.1)': [111] Connection refused\n" + "[RETRY DETAIL OMITTED]", hrnServerPort(0)); // -------------------------------------------------------------------------------------------------------------------------