From: Remi Gacogne Date: Wed, 6 Jul 2016 16:12:08 +0000 (+0200) Subject: auth: Wait for the connection to the carbon server to be established X-Git-Tag: auth-4.0.1~17^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F4126%2Fhead;p=thirdparty%2Fpdns.git auth: Wait for the connection to the carbon server to be established Doing a non-blocking `connect()` immediately followed by a `write()` cause the `write()` to fail with `ENOTCONN` on FreeBSD. This commit instead wait for the `connect()` operation to finish using `poll()` with a short timeout if it returned `EINPROGRESS`, so that either we have a connected socket to write to, or we fail. --- diff --git a/pdns/auth-carbon.cc b/pdns/auth-carbon.cc index c721cc0155..17a43b365d 100644 --- a/pdns/auth-carbon.cc +++ b/pdns/auth-carbon.cc @@ -46,11 +46,12 @@ try for (const auto& carbonServer : carbonServers) { ComboAddress remote(carbonServer, 2003); - Socket s(remote.sin4.sin_family, SOCK_STREAM); - s.setNonBlocking(); - s.connect(remote); // we do the connect so the attempt happens while we gather stats try { + Socket s(remote.sin4.sin_family, SOCK_STREAM); + s.setNonBlocking(); + s.connect(remote, 2); + writen2WithTimeout(s.getHandle(), msg.c_str(), msg.length(), 2); } catch (runtime_error &e){ L< 0) { + /* if a timeout is provided, we wait until the connection has been established */ + int res = waitForRWData(d_socket, false, timeout, 0); + if (res == 0) { + throw NetworkError("timeout while connecting to "+ep.toStringWithPort()); + } else if (res < 0) { + throw NetworkError("while waiting to connect to "+ep.toStringWithPort()+": "+string(strerror(errno))); + } + } + } + else { + throw NetworkError("While connecting to "+ep.toStringWithPort()+": "+string(strerror(errno))); + } + } }