From: Remi Gacogne Date: Tue, 25 Jun 2019 08:42:59 +0000 (+0200) Subject: dnsdist: Fix handling of backend connection failing over TCP X-Git-Tag: dnsdist-1.4.0-rc1~90^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F7979%2Fhead;p=thirdparty%2Fpdns.git dnsdist: Fix handling of backend connection failing over TCP - The creation of the Socket object can throw if we run out of file descriptors ; - Catch exceptions thrown from setupTCPDownstream() earlier, we don't care why it failed later, only that it did. --- diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 8419011661..405a9125d5 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -71,8 +71,8 @@ static std::unique_ptr setupTCPDownstream(shared_ptr& d do { vinfolog("TCP connecting to downstream %s (%d)", ds->remote.toStringWithPort(), downstreamFailures); - result = std::unique_ptr(new Socket(ds->remote.sin4.sin_family, SOCK_STREAM, 0)); try { + result = std::unique_ptr(new Socket(ds->remote.sin4.sin_family, SOCK_STREAM, 0)); if (!IsAnyAddress(ds->sourceAddr)) { SSetsockopt(result->getHandle(), SOL_SOCKET, SO_REUSEADDR, 1); #ifdef IP_BIND_ADDRESS_NO_PORT @@ -750,24 +750,24 @@ static void sendQueryToBackend(std::shared_ptr& stat return; } - while (state->d_downstreamFailures < state->d_ds->retries) - { - state->d_downstreamConnection = getConnectionToDownstream(ds, state->d_downstreamFailures, now); - - if (!state->d_downstreamConnection) { - ++ds->tcpGaveUp; - ++state->d_ci.cs->tcpGaveUp; - vinfolog("Downstream connection to %s failed %d times in a row, giving up.", ds->getName(), state->d_downstreamFailures); - return; + if (state->d_downstreamFailures < state->d_ds->retries) { + try { + state->d_downstreamConnection = getConnectionToDownstream(ds, state->d_downstreamFailures, now); } + catch (const std::runtime_error& e) { + state->d_downstreamConnection.reset(); + } + } - handleDownstreamIO(state, now); + if (!state->d_downstreamConnection) { + ++ds->tcpGaveUp; + ++state->d_ci.cs->tcpGaveUp; + vinfolog("Downstream connection to %s failed %d times in a row, giving up.", ds->getName(), state->d_downstreamFailures); return; } - ++ds->tcpGaveUp; - ++state->d_ci.cs->tcpGaveUp; - vinfolog("Downstream connection to %s failed %u times in a row, giving up.", ds->getName(), state->d_downstreamFailures); + handleDownstreamIO(state, now); + return; } static void handleQuery(std::shared_ptr& state, struct timeval& now)