From feff1cded5ac7128a1df719c4a2a8393370a40ab Mon Sep 17 00:00:00 2001 From: Subodh Iyengar Date: Thu, 2 Mar 2017 09:00:14 -0800 Subject: [PATCH] Add a method to AsyncSSLSocket to supply connect timeouts Summary: The current method to supply connect timeouts to AsyncSSLSocket is to supply only the max connect + ssl connect time. However in some cases when connect time is known, it is desirable to supply it so that if connect does not succeed in connect time we can error out quicker and retry. This adds a new method for connect time in addition to the total Connect time. An alternative to this would be to create a AsyncSocket, connect it and then pass it's fd to AsyncSSLSocket, however that approach does not work well when TFO is being used, because TFO State is a part of the AsyncSocket's state and that is not encapsulated with the fd transfer. We could move the state around, but that is error prone, and this is much simpler and isolated to AsyncSSLSocket. Reviewed By: knekritz Differential Revision: D4626924 fbshipit-source-id: d802d035efbced68873ab59314d9f0e661e5509b --- folly/io/async/AsyncSSLSocket.cpp | 30 +++++++++++++++++++++--------- folly/io/async/AsyncSSLSocket.h | 23 +++++++++++++++++++++++ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/folly/io/async/AsyncSSLSocket.cpp b/folly/io/async/AsyncSSLSocket.cpp index 074d1ac3..7c72a584 100644 --- a/folly/io/async/AsyncSSLSocket.cpp +++ b/folly/io/async/AsyncSSLSocket.cpp @@ -645,19 +645,31 @@ void AsyncSSLSocket::cacheLocalPeerAddr() { } } -void AsyncSSLSocket::connect(ConnectCallback* callback, - const folly::SocketAddress& address, - int timeout, - const OptionMap &options, - const folly::SocketAddress& bindAddr) - noexcept { +void AsyncSSLSocket::connect( + ConnectCallback* callback, + const folly::SocketAddress& address, + int timeout, + const OptionMap& options, + const folly::SocketAddress& bindAddr) noexcept { + auto timeoutChrono = std::chrono::milliseconds(timeout); + connect(callback, address, timeoutChrono, timeoutChrono, options, bindAddr); +} + +void AsyncSSLSocket::connect( + ConnectCallback* callback, + const folly::SocketAddress& address, + std::chrono::milliseconds connectTimeout, + std::chrono::milliseconds totalConnectTimeout, + const OptionMap& options, + const folly::SocketAddress& bindAddr) noexcept { assert(!server_); assert(state_ == StateEnum::UNINIT); assert(sslState_ == STATE_UNINIT); noTransparentTls_ = true; - AsyncSSLSocketConnector *connector = - new AsyncSSLSocketConnector(this, callback, timeout); - AsyncSocket::connect(connector, address, timeout, options, bindAddr); + AsyncSSLSocketConnector* connector = + new AsyncSSLSocketConnector(this, callback, totalConnectTimeout.count()); + AsyncSocket::connect( + connector, address, connectTimeout.count(), options, bindAddr); } bool AsyncSSLSocket::needsPeerVerification() const { diff --git a/folly/io/async/AsyncSSLSocket.h b/folly/io/async/AsyncSSLSocket.h index fe8cbdd3..4edbec58 100644 --- a/folly/io/async/AsyncSSLSocket.h +++ b/folly/io/async/AsyncSSLSocket.h @@ -316,6 +316,29 @@ class AsyncSSLSocket : public virtual AsyncSocket { const folly::SocketAddress& bindAddr = anyAddress()) noexcept override; + /** + * A variant of connect that allows the caller to specify + * the timeout for the regular connect and the ssl connect + * separately. + * connectTimeout is specified as the time to establish a TCP + * connection. + * totalConnectTimeout defines the + * time it takes from starting the TCP connection to the time + * the ssl connection is established. The reason the timeout is + * defined this way is because user's rarely need to specify the SSL + * timeout independently of the connect timeout. It allows us to + * bound the time for a connect and SSL connection in + * a finer grained manner than if timeout was just defined + * independently for SSL. + */ + virtual void connect( + ConnectCallback* callback, + const folly::SocketAddress& address, + std::chrono::milliseconds connectTimeout, + std::chrono::milliseconds totalConnectTimeout, + const OptionMap& options = emptyOptionMap, + const folly::SocketAddress& bindAddr = anyAddress()) noexcept; + using AsyncSocket::connect; /** -- 2.34.1