From 671809420f0adca93f3686af46711fece8f16160 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 6 Jul 2016 18:12:08 +0200 Subject: [PATCH] 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. --- pdns/auth-carbon.cc | 7 ++++--- pdns/sstuff.hh | 20 +++++++++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) 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))); + } + } } -- 2.47.2