diff options
Diffstat (limited to 'net')
22 files changed, 424 insertions, 181 deletions
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc index 9590877..c6433af 100644 --- a/net/http/http_proxy_client_socket_pool_unittest.cc +++ b/net/http/http_proxy_client_socket_pool_unittest.cc @@ -192,10 +192,12 @@ class HttpProxyClientSocketPoolTest scoped_refptr<TransportSocketParams> CreateHttpProxyParams() const { if (GetParam().proxy_type != HTTP) return NULL; - return new TransportSocketParams(HostPortPair(kHttpProxyHost, 80), - false, - false, - OnHostResolutionCallback()); + return new TransportSocketParams( + HostPortPair(kHttpProxyHost, 80), + false, + false, + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT); } scoped_refptr<SSLSocketParams> CreateHttpsProxyParams() const { @@ -206,7 +208,8 @@ class HttpProxyClientSocketPoolTest HostPortPair(kHttpsProxyHost, 443), false, false, - OnHostResolutionCallback()), + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT), NULL, NULL, HostPortPair(kHttpsProxyHost, 443), diff --git a/net/net.gypi b/net/net.gypi index f309dd8..1f60118 100644 --- a/net/net.gypi +++ b/net/net.gypi @@ -980,7 +980,6 @@ 'socket/tcp_listen_socket.h', 'socket/tcp_server_socket.cc', 'socket/tcp_server_socket.h', - 'socket/tcp_socket.cc', 'socket/tcp_socket.h', 'socket/tcp_socket_libevent.cc', 'socket/tcp_socket_libevent.h', diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc index 08fc487..a11965c 100644 --- a/net/socket/client_socket_pool_manager.cc +++ b/net/socket/client_socket_pool_manager.cc @@ -84,7 +84,6 @@ int InitSocketPoolHelper(const GURL& request_url, HttpNetworkSession::SocketPoolType socket_pool_type, const OnHostResolutionCallback& resolution_callback, const CompletionCallback& callback) { - scoped_refptr<TransportSocketParams> tcp_params; scoped_refptr<HttpProxySocketParams> http_proxy_params; scoped_refptr<SOCKSSocketParams> socks_params; scoped_ptr<HostPortPair> proxy_host_port; @@ -155,19 +154,16 @@ int InitSocketPoolHelper(const GURL& request_url, } bool ignore_limits = (request_load_flags & LOAD_IGNORE_LIMITS) != 0; - if (proxy_info.is_direct()) { - tcp_params = new TransportSocketParams(origin_host_port, - disable_resolver_cache, - ignore_limits, - resolution_callback); - } else { + if (!proxy_info.is_direct()) { ProxyServer proxy_server = proxy_info.proxy_server(); proxy_host_port.reset(new HostPortPair(proxy_server.host_port_pair())); scoped_refptr<TransportSocketParams> proxy_tcp_params( - new TransportSocketParams(*proxy_host_port, - disable_resolver_cache, - ignore_limits, - resolution_callback)); + new TransportSocketParams( + *proxy_host_port, + disable_resolver_cache, + ignore_limits, + resolution_callback, + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); if (proxy_info.is_http() || proxy_info.is_https()) { std::string user_agent; @@ -175,6 +171,15 @@ int InitSocketPoolHelper(const GURL& request_url, &user_agent); scoped_refptr<SSLSocketParams> ssl_params; if (proxy_info.is_https()) { + // TODO (jri): Enable a finch trial to use + // COMBINE_CONNECT_AND_WRITE_DESIRED for SSL sockets. + proxy_tcp_params = + new TransportSocketParams( + *proxy_host_port, + disable_resolver_cache, + ignore_limits, + resolution_callback, + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT); // Set ssl_params, and unset proxy_tcp_params ssl_params = new SSLSocketParams(proxy_tcp_params, NULL, @@ -221,8 +226,21 @@ int InitSocketPoolHelper(const GURL& request_url, // Deal with SSL - which layers on top of any given proxy. if (using_ssl) { + scoped_refptr<TransportSocketParams> ssl_tcp_params; + if (proxy_info.is_direct()) { + // Setup TCP params if non-proxied SSL connection. + // TODO (jri): Enable a finch trial to use + // COMBINE_CONNECT_AND_WRITE_DESIRED for SSL sockets. + ssl_tcp_params = + new TransportSocketParams( + origin_host_port, + disable_resolver_cache, + ignore_limits, + resolution_callback, + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT); + } scoped_refptr<SSLSocketParams> ssl_params = - new SSLSocketParams(tcp_params, + new SSLSocketParams(ssl_tcp_params, socks_params, http_proxy_params, origin_host_port, @@ -281,7 +299,13 @@ int InitSocketPoolHelper(const GURL& request_url, } DCHECK(proxy_info.is_direct()); - + scoped_refptr<TransportSocketParams> tcp_params = + new TransportSocketParams( + origin_host_port, + disable_resolver_cache, + ignore_limits, + resolution_callback, + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT); TransportClientSocketPool* pool = session->GetTransportSocketPool(socket_pool_type); if (num_preconnect_streams) { diff --git a/net/socket/deterministic_socket_data_unittest.cc b/net/socket/deterministic_socket_data_unittest.cc index dc1c42c..9a2d833 100644 --- a/net/socket/deterministic_socket_data_unittest.cc +++ b/net/socket/deterministic_socket_data_unittest.cc @@ -71,10 +71,12 @@ DeterministicSocketDataTest::DeterministicSocketDataTest() read_buf_(NULL), connect_data_(SYNCHRONOUS, OK), endpoint_("www.google.com", 443), - tcp_params_(new TransportSocketParams(endpoint_, - false, - false, - OnHostResolutionCallback())), + tcp_params_(new TransportSocketParams( + endpoint_, + false, + false, + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)), histograms_(std::string()), socket_pool_(10, 10, &histograms_, &socket_factory_) {} diff --git a/net/socket/socks_client_socket_pool_unittest.cc b/net/socket/socks_client_socket_pool_unittest.cc index b2b8655..ec2230c 100644 --- a/net/socket/socks_client_socket_pool_unittest.cc +++ b/net/socket/socks_client_socket_pool_unittest.cc @@ -44,8 +44,8 @@ void TestLoadTimingInfo(const ClientSocketHandle& handle) { scoped_refptr<TransportSocketParams> CreateProxyHostParams() { return new TransportSocketParams( - HostPortPair("proxy", 80), false, false, - OnHostResolutionCallback()); + HostPortPair("proxy", 80), false, false, OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT); } scoped_refptr<SOCKSSocketParams> CreateSOCKSv4Params() { diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc index c05ac6c..54b4ee1 100644 --- a/net/socket/ssl_client_socket_pool_unittest.cc +++ b/net/socket/ssl_client_socket_pool_unittest.cc @@ -87,20 +87,24 @@ class SSLClientSocketPoolTest HttpAuthHandlerFactory::CreateDefault(&host_resolver_)), session_(CreateNetworkSession()), direct_transport_socket_params_( - new TransportSocketParams(HostPortPair("host", 443), - false, - false, - OnHostResolutionCallback())), + new TransportSocketParams( + HostPortPair("host", 443), + false, + false, + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)), transport_histograms_("MockTCP"), transport_socket_pool_(kMaxSockets, kMaxSocketsPerGroup, &transport_histograms_, &socket_factory_), proxy_transport_socket_params_( - new TransportSocketParams(HostPortPair("proxy", 443), - false, - false, - OnHostResolutionCallback())), + new TransportSocketParams( + HostPortPair("proxy", 443), + false, + false, + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)), socks_socket_params_( new SOCKSSocketParams(proxy_transport_socket_params_, true, diff --git a/net/socket/stream_socket.h b/net/socket/stream_socket.h index 7208810..7631e12 100644 --- a/net/socket/stream_socket.h +++ b/net/socket/stream_socket.h @@ -75,10 +75,15 @@ class NET_EXPORT_PRIVATE StreamSocket : public Socket { // Write() methods had been called, not the underlying transport's. virtual bool WasEverUsed() const = 0; + // TODO(jri): Clean up -- remove this method. // Returns true if the underlying transport socket is using TCP FastOpen. // TCP FastOpen is an experiment with sending data in the TCP SYN packet. virtual bool UsingTCPFastOpen() const = 0; + // TODO(jri): Clean up -- rename to a more general EnableAutoConnectOnWrite. + // Enables use of TCP FastOpen for the underlying transport socket. + virtual void EnableTCPFastOpenIfSupported() {} + // Returns true if NPN was negotiated during the connection of this socket. virtual bool WasNpnNegotiated() const = 0; diff --git a/net/socket/tcp_client_socket.cc b/net/socket/tcp_client_socket.cc index 53d8d1f..a16e11e 100644 --- a/net/socket/tcp_client_socket.cc +++ b/net/socket/tcp_client_socket.cc @@ -225,6 +225,10 @@ bool TCPClientSocket::UsingTCPFastOpen() const { return socket_->UsingTCPFastOpen(); } +void TCPClientSocket::EnableTCPFastOpenIfSupported() { + socket_->EnableTCPFastOpenIfSupported(); +} + bool TCPClientSocket::WasNpnNegotiated() const { return false; } diff --git a/net/socket/tcp_client_socket.h b/net/socket/tcp_client_socket.h index 970da2a..9322624 100644 --- a/net/socket/tcp_client_socket.h +++ b/net/socket/tcp_client_socket.h @@ -49,6 +49,7 @@ class NET_EXPORT TCPClientSocket : public StreamSocket { virtual void SetOmniboxSpeculation() OVERRIDE; virtual bool WasEverUsed() const OVERRIDE; virtual bool UsingTCPFastOpen() const OVERRIDE; + virtual void EnableTCPFastOpenIfSupported() OVERRIDE; virtual bool WasNpnNegotiated() const OVERRIDE; virtual NextProto GetNegotiatedProtocol() const OVERRIDE; virtual bool GetSSLInfo(SSLInfo* ssl_info) OVERRIDE; diff --git a/net/socket/tcp_socket.cc b/net/socket/tcp_socket.cc deleted file mode 100644 index 842cc06..0000000 --- a/net/socket/tcp_socket.cc +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "net/socket/tcp_socket.h" - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/location.h" -#include "base/memory/ref_counted.h" -#include "base/threading/worker_pool.h" - -namespace net { - -namespace { - -bool g_tcp_fastopen_enabled = false; - -#if defined(OS_LINUX) || defined(OS_ANDROID) - -typedef base::RefCountedData<bool> SharedBoolean; - -// Checks to see if the system supports TCP FastOpen. Notably, it requires -// kernel support. Additionally, this checks system configuration to ensure that -// it's enabled. -void SystemSupportsTCPFastOpen(scoped_refptr<SharedBoolean> supported) { - supported->data = false; - static const base::FilePath::CharType kTCPFastOpenProcFilePath[] = - "/proc/sys/net/ipv4/tcp_fastopen"; - std::string system_enabled_tcp_fastopen; - if (!base::ReadFileToString(base::FilePath(kTCPFastOpenProcFilePath), - &system_enabled_tcp_fastopen)) { - return; - } - - // As per http://lxr.linux.no/linux+v3.7.7/include/net/tcp.h#L225 - // TFO_CLIENT_ENABLE is the LSB - if (system_enabled_tcp_fastopen.empty() || - (system_enabled_tcp_fastopen[0] & 0x1) == 0) { - return; - } - - supported->data = true; -} - -void EnableCallback(scoped_refptr<SharedBoolean> supported) { - g_tcp_fastopen_enabled = supported->data; -} - -// This is asynchronous because it needs to do file IO, and it isn't allowed to -// do that on the IO thread. -void EnableFastOpenIfSupported() { - scoped_refptr<SharedBoolean> supported = new SharedBoolean; - base::WorkerPool::PostTaskAndReply( - FROM_HERE, - base::Bind(SystemSupportsTCPFastOpen, supported), - base::Bind(EnableCallback, supported), - false); -} - -#else - -void EnableFastOpenIfSupported() { - g_tcp_fastopen_enabled = false; -} - -#endif - -} // namespace - -void SetTCPFastOpenEnabled(bool value) { - if (value) { - EnableFastOpenIfSupported(); - } else { - g_tcp_fastopen_enabled = false; - } -} - -bool IsTCPFastOpenEnabled() { - return g_tcp_fastopen_enabled; -} - -} // namespace net diff --git a/net/socket/tcp_socket.h b/net/socket/tcp_socket.h index 8b36fad..04fd7d2 100644 --- a/net/socket/tcp_socket.h +++ b/net/socket/tcp_socket.h @@ -16,13 +16,6 @@ namespace net { -// Enable/disable experimental TCP FastOpen option. -// Not thread safe. Must be called during initialization/startup only. -NET_EXPORT void SetTCPFastOpenEnabled(bool value); - -// Check if the TCP FastOpen option is enabled. -bool IsTCPFastOpenEnabled(); - // TCPSocket provides a platform-independent interface for TCP sockets. // // It is recommended to use TCPClientSocket/TCPServerSocket instead of this @@ -35,6 +28,17 @@ typedef TCPSocketWin TCPSocket; typedef TCPSocketLibevent TCPSocket; #endif +// Check if TCP FastOpen is supported by the OS. +bool IsTCPFastOpenSupported(); + +// Check if TCP FastOpen is enabled by the user. +bool IsTCPFastOpenUserEnabled(); + +// Checks if TCP FastOpen is supported by the kernel. Also enables TFO for all +// connections if indicated by user. +// Not thread safe. Must be called during initialization/startup only. +NET_EXPORT void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled); + } // namespace net #endif // NET_SOCKET_TCP_SOCKET_H_ diff --git a/net/socket/tcp_socket_libevent.cc b/net/socket/tcp_socket_libevent.cc index 426c8b0..f39611b 100644 --- a/net/socket/tcp_socket_libevent.cc +++ b/net/socket/tcp_socket_libevent.cc @@ -13,6 +13,8 @@ #include "base/metrics/histogram.h" #include "base/metrics/stats_counters.h" #include "base/posix/eintr_wrapper.h" +#include "base/task_runner_util.h" +#include "base/threading/worker_pool.h" #include "net/base/address_list.h" #include "net/base/connection_type_histograms.h" #include "net/base/io_buffer.h" @@ -32,6 +34,12 @@ namespace net { namespace { +// True if OS supports TCP FastOpen. +bool g_tcp_fastopen_supported = false; +// True if TCP FastOpen is user-enabled for all connections. +// TODO(jri): Change global variable to param in HttpNetworkSession::Params. +bool g_tcp_fastopen_user_enabled = false; + // SetTCPNoDelay turns on/off buffering in the kernel. By default, TCP sockets // will wait up to 200ms for more data to complete a packet before transmitting. // After calling this function, the kernel will not wait. See TCP_NODELAY in @@ -69,13 +77,58 @@ bool SetTCPKeepAlive(int fd, bool enable, int delay) { return true; } +#if defined(OS_LINUX) || defined(OS_ANDROID) +// Checks if the kernel supports TCP FastOpen. +bool SystemSupportsTCPFastOpen() { + const base::FilePath::CharType kTCPFastOpenProcFilePath[] = + "/proc/sys/net/ipv4/tcp_fastopen"; + std::string system_supports_tcp_fastopen; + if (!base::ReadFileToString(base::FilePath(kTCPFastOpenProcFilePath), + &system_supports_tcp_fastopen)) { + return false; + } + // The read from /proc should return '1' if TCP FastOpen is enabled in the OS. + if (system_supports_tcp_fastopen.empty() || + (system_supports_tcp_fastopen[0] != '1')) { + return false; + } + return true; +} + +void RegisterTCPFastOpenIntentAndSupport(bool user_enabled, + bool system_supported) { + g_tcp_fastopen_supported = system_supported; + g_tcp_fastopen_user_enabled = user_enabled; +} +#endif + } // namespace //----------------------------------------------------------------------------- +bool IsTCPFastOpenSupported() { + return g_tcp_fastopen_supported; +} + +bool IsTCPFastOpenUserEnabled() { + return g_tcp_fastopen_user_enabled; +} + +// This is asynchronous because it needs to do file IO, and it isn't allowed to +// do that on the IO thread. +void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) { +#if defined(OS_LINUX) || defined(OS_ANDROID) + base::PostTaskAndReplyWithResult( + base::WorkerPool::GetTaskRunner(/*task_is_slow=*/false).get(), + FROM_HERE, + base::Bind(SystemSupportsTCPFastOpen), + base::Bind(RegisterTCPFastOpenIntentAndSupport, user_enabled)); +#endif +} + TCPSocketLibevent::TCPSocketLibevent(NetLog* net_log, const NetLog::Source& source) - : use_tcp_fastopen_(IsTCPFastOpenEnabled()), + : use_tcp_fastopen_(false), tcp_fastopen_connected_(false), fast_open_status_(FAST_OPEN_STATUS_UNKNOWN), logging_multiple_connect_attempts_(false), @@ -369,6 +422,11 @@ bool TCPSocketLibevent::UsingTCPFastOpen() const { return use_tcp_fastopen_; } +void TCPSocketLibevent::EnableTCPFastOpenIfSupported() { + if (IsTCPFastOpenSupported()) + use_tcp_fastopen_ = true; +} + bool TCPSocketLibevent::IsValid() const { return socket_ != NULL && socket_->socket_fd() != kInvalidSocket; } @@ -495,7 +553,7 @@ void TCPSocketLibevent::ReadCompleted(const scoped_refptr<IOBuffer>& buf, const CompletionCallback& callback, int rv) { DCHECK_NE(ERR_IO_PENDING, rv); - // Records fast open status regardless of error in asynchronous case. + // Records TCP FastOpen status regardless of error in asynchronous case. // TODO(rdsmith,jri): Change histogram name to indicate it could be called on // error. RecordFastOpenStatus(); @@ -597,7 +655,7 @@ void TCPSocketLibevent::RecordFastOpenStatus() { bool getsockopt_success(false); bool server_acked_data(false); #if defined(TCP_INFO) - // Probe to see the if the socket used TCP Fast Open. + // Probe to see the if the socket used TCP FastOpen. tcp_info info; socklen_t info_len = sizeof(tcp_info); getsockopt_success = diff --git a/net/socket/tcp_socket_libevent.h b/net/socket/tcp_socket_libevent.h index 0335c9e..89b6a22 100644 --- a/net/socket/tcp_socket_libevent.h +++ b/net/socket/tcp_socket_libevent.h @@ -65,7 +65,10 @@ class NET_EXPORT TCPSocketLibevent { void Close(); + // Setter/Getter methods for TCP FastOpen socket option. bool UsingTCPFastOpen() const; + void EnableTCPFastOpenIfSupported(); + bool IsValid() const; // Marks the start/end of a series of connect attempts for logging purpose. @@ -168,11 +171,10 @@ class NET_EXPORT TCPSocketLibevent { scoped_ptr<SocketLibevent> accept_socket_; // Enables experimental TCP FastOpen option. - const bool use_tcp_fastopen_; + bool use_tcp_fastopen_; // True when TCP FastOpen is in use and we have done the connect. bool tcp_fastopen_connected_; - FastOpenStatus fast_open_status_; bool logging_multiple_connect_attempts_; diff --git a/net/socket/tcp_socket_win.cc b/net/socket/tcp_socket_win.cc index 88db36f..35bfb9b 100644 --- a/net/socket/tcp_socket_win.cc +++ b/net/socket/tcp_socket_win.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "net/socket/tcp_socket.h" #include "net/socket/tcp_socket_win.h" #include <mstcpip.h> @@ -123,6 +124,12 @@ int MapConnectError(int os_error) { //----------------------------------------------------------------------------- +// Nothing to do for Windows since it doesn't support TCP FastOpen. +// TODO(jri): Remove these along with the corresponding global variables. +bool IsTCPFastOpenSupported() { return false; } +bool IsTCPFastOpenUserEnabled() { return false; } +void CheckSupportAndMaybeEnableTCPFastOpen(bool user_enabled) {} + // This class encapsulates all the state that has to be preserved as long as // there is a network IO operation in progress. If the owner TCPSocketWin is // destroyed while an operation is in progress, the Core is detached and it @@ -694,11 +701,6 @@ void TCPSocketWin::Close() { connect_os_error_ = 0; } -bool TCPSocketWin::UsingTCPFastOpen() const { - // Not supported on windows. - return false; -} - void TCPSocketWin::StartLoggingMultipleConnectAttempts( const AddressList& addresses) { if (!logging_multiple_connect_attempts_) { @@ -1021,4 +1023,3 @@ void TCPSocketWin::DidSignalRead() { } } // namespace net - diff --git a/net/socket/tcp_socket_win.h b/net/socket/tcp_socket_win.h index 2ddd538..a5eed419 100644 --- a/net/socket/tcp_socket_win.h +++ b/net/socket/tcp_socket_win.h @@ -75,7 +75,11 @@ class NET_EXPORT TCPSocketWin : NON_EXPORTED_BASE(public base::NonThreadSafe), void Close(); - bool UsingTCPFastOpen() const; + // Setter/Getter methods for TCP FastOpen socket option. + // NOOPs since TCP FastOpen is not implemented in Windows. + bool UsingTCPFastOpen() const { return false; } + void EnableTCPFastOpenIfSupported() {} + bool IsValid() const { return socket_ != INVALID_SOCKET; } // Marks the start/end of a series of connect attempts for logging purpose. @@ -152,4 +156,3 @@ class NET_EXPORT TCPSocketWin : NON_EXPORTED_BASE(public base::NonThreadSafe), } // namespace net #endif // NET_SOCKET_TCP_SOCKET_WIN_H_ - diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc index 7527eca..06202f1 100644 --- a/net/socket/transport_client_socket_pool.cc +++ b/net/socket/transport_client_socket_pool.cc @@ -60,12 +60,21 @@ TransportSocketParams::TransportSocketParams( const HostPortPair& host_port_pair, bool disable_resolver_cache, bool ignore_limits, - const OnHostResolutionCallback& host_resolution_callback) + const OnHostResolutionCallback& host_resolution_callback, + CombineConnectAndWritePolicy combine_connect_and_write_if_supported) : destination_(host_port_pair), ignore_limits_(ignore_limits), - host_resolution_callback_(host_resolution_callback) { + host_resolution_callback_(host_resolution_callback), + combine_connect_and_write_(combine_connect_and_write_if_supported) { if (disable_resolver_cache) destination_.set_allow_cached_response(false); + // combine_connect_and_write currently translates to TCP FastOpen. + // Enable TCP FastOpen if user wants it. + if (combine_connect_and_write_ == COMBINE_CONNECT_AND_WRITE_DEFAULT) { + IsTCPFastOpenUserEnabled() ? combine_connect_and_write_ = + COMBINE_CONNECT_AND_WRITE_DESIRED : + COMBINE_CONNECT_AND_WRITE_PROHIBITED; + } } TransportSocketParams::~TransportSocketParams() {} @@ -261,10 +270,25 @@ int TransportConnectJob::DoTransportConnect() { transport_socket_ = helper_.client_socket_factory()->CreateTransportClientSocket( helper_.addresses(), net_log().net_log(), net_log().source()); - int rv = transport_socket_->Connect(helper_.on_io_complete()); - if (rv == ERR_IO_PENDING && + + // If the list contains IPv6 and IPv4 addresses, the first address will + // be IPv6, and the IPv4 addresses will be tried as fallback addresses, + // per "Happy Eyeballs" (RFC 6555). + bool try_ipv6_connect_with_ipv4_fallback = helper_.addresses().front().GetFamily() == ADDRESS_FAMILY_IPV6 && - !AddressListOnlyContainsIPv6(helper_.addresses())) { + !AddressListOnlyContainsIPv6(helper_.addresses()); + + // Enable TCP FastOpen if indicated by transport socket params. + // Note: We currently do not turn on TCP FastOpen for destinations where + // we try a TCP connect over IPv6 with fallback to IPv4. + if (!try_ipv6_connect_with_ipv4_fallback && + helper_.params()->combine_connect_and_write() == + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DESIRED) { + transport_socket_->EnableTCPFastOpenIfSupported(); + } + + int rv = transport_socket_->Connect(helper_.on_io_complete()); + if (rv == ERR_IO_PENDING && try_ipv6_connect_with_ipv4_fallback) { fallback_timer_.Start( FROM_HERE, base::TimeDelta::FromMilliseconds( diff --git a/net/socket/transport_client_socket_pool.h b/net/socket/transport_client_socket_pool.h index 003008a..fce5432 100644 --- a/net/socket/transport_client_socket_pool.h +++ b/net/socket/transport_client_socket_pool.h @@ -29,14 +29,30 @@ OnHostResolutionCallback; class NET_EXPORT_PRIVATE TransportSocketParams : public base::RefCounted<TransportSocketParams> { public: + // CombineConnectAndWrite currently translates to using TCP FastOpen. + // TCP FastOpen should not be used if the first write to the socket may + // be non-idempotent, as the underlying socket could retransmit the data + // on failure of the first transmission. + // NOTE: Currently, COMBINE_CONNECT_AND_WRITE_DESIRED is used if the data in + // the write is known to be idempotent, and COMBINE_CONNECT_AND_WRITE_DEFAULT + // is used as a default for other cases (including non-idempotent writes). + enum CombineConnectAndWritePolicy { + COMBINE_CONNECT_AND_WRITE_DEFAULT, // Default policy, implemented in + // TransportSocketParams constructor. + COMBINE_CONNECT_AND_WRITE_DESIRED, // Combine if supported by socket. + COMBINE_CONNECT_AND_WRITE_PROHIBITED // Do not combine. + }; + // |host_resolution_callback| will be invoked after the the hostname is // resolved. If |host_resolution_callback| does not return OK, then the - // connection will be aborted with that value. + // connection will be aborted with that value. |combine_connect_and_write| + // defines the policy for use of TCP FastOpen on this socket. TransportSocketParams( const HostPortPair& host_port_pair, bool disable_resolver_cache, bool ignore_limits, - const OnHostResolutionCallback& host_resolution_callback); + const OnHostResolutionCallback& host_resolution_callback, + CombineConnectAndWritePolicy combine_connect_and_write); const HostResolver::RequestInfo& destination() const { return destination_; } bool ignore_limits() const { return ignore_limits_; } @@ -44,6 +60,10 @@ class NET_EXPORT_PRIVATE TransportSocketParams return host_resolution_callback_; } + CombineConnectAndWritePolicy combine_connect_and_write() const { + return combine_connect_and_write_; + } + private: friend class base::RefCounted<TransportSocketParams>; ~TransportSocketParams(); @@ -51,6 +71,7 @@ class NET_EXPORT_PRIVATE TransportSocketParams HostResolver::RequestInfo destination_; bool ignore_limits_; const OnHostResolutionCallback host_resolution_callback_; + CombineConnectAndWritePolicy combine_connect_and_write_; DISALLOW_COPY_AND_ASSIGN(TransportSocketParams); }; @@ -90,6 +111,7 @@ class NET_EXPORT_PRIVATE TransportConnectJobHelper { State next_state() const { return next_state_; } void set_next_state(State next_state) { next_state_ = next_state; } CompletionCallback on_io_complete() const { return on_io_complete_; } + const TransportSocketParams* params() { return params_.get(); } int DoResolveHost(RequestPriority priority, const BoundNetLog& net_log); int DoResolveHostComplete(int result, const BoundNetLog& net_log); diff --git a/net/socket/transport_client_socket_pool_test_util.cc b/net/socket/transport_client_socket_pool_test_util.cc index a94167c..98a615d 100644 --- a/net/socket/transport_client_socket_pool_test_util.cc +++ b/net/socket/transport_client_socket_pool_test_util.cc @@ -34,7 +34,8 @@ class MockConnectClientSocket : public StreamSocket { MockConnectClientSocket(const AddressList& addrlist, net::NetLog* net_log) : connected_(false), addrlist_(addrlist), - net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {} + net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), + use_tcp_fastopen_(false) {} // StreamSocket implementation. virtual int Connect(const CompletionCallback& callback) OVERRIDE { @@ -63,7 +64,10 @@ class MockConnectClientSocket : public StreamSocket { virtual void SetSubresourceSpeculation() OVERRIDE {} virtual void SetOmniboxSpeculation() OVERRIDE {} virtual bool WasEverUsed() const OVERRIDE { return false; } - virtual bool UsingTCPFastOpen() const OVERRIDE { return false; } + virtual void EnableTCPFastOpenIfSupported() OVERRIDE { + use_tcp_fastopen_ = true; + } + virtual bool UsingTCPFastOpen() const OVERRIDE { return use_tcp_fastopen_; } virtual bool WasNpnNegotiated() const OVERRIDE { return false; } virtual NextProto GetNegotiatedProtocol() const OVERRIDE { return kProtoUnknown; @@ -88,6 +92,7 @@ class MockConnectClientSocket : public StreamSocket { bool connected_; const AddressList addrlist_; BoundNetLog net_log_; + bool use_tcp_fastopen_; DISALLOW_COPY_AND_ASSIGN(MockConnectClientSocket); }; @@ -96,7 +101,8 @@ class MockFailingClientSocket : public StreamSocket { public: MockFailingClientSocket(const AddressList& addrlist, net::NetLog* net_log) : addrlist_(addrlist), - net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)) {} + net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), + use_tcp_fastopen_(false) {} // StreamSocket implementation. virtual int Connect(const CompletionCallback& callback) OVERRIDE { @@ -118,7 +124,10 @@ class MockFailingClientSocket : public StreamSocket { virtual void SetSubresourceSpeculation() OVERRIDE {} virtual void SetOmniboxSpeculation() OVERRIDE {} virtual bool WasEverUsed() const OVERRIDE { return false; } - virtual bool UsingTCPFastOpen() const OVERRIDE { return false; } + virtual void EnableTCPFastOpenIfSupported() OVERRIDE { + use_tcp_fastopen_ = true; + } + virtual bool UsingTCPFastOpen() const OVERRIDE { return use_tcp_fastopen_; } virtual bool WasNpnNegotiated() const OVERRIDE { return false; } virtual NextProto GetNegotiatedProtocol() const OVERRIDE { return kProtoUnknown; @@ -143,6 +152,7 @@ class MockFailingClientSocket : public StreamSocket { private: const AddressList addrlist_; BoundNetLog net_log_; + bool use_tcp_fastopen_; DISALLOW_COPY_AND_ASSIGN(MockFailingClientSocket); }; @@ -158,6 +168,7 @@ class MockTriggerableClientSocket : public StreamSocket { is_connected_(false), addrlist_(addrlist), net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SOCKET)), + use_tcp_fastopen_(false), weak_factory_(this) {} // Call this method to get a closure which will trigger the connect callback @@ -228,7 +239,10 @@ class MockTriggerableClientSocket : public StreamSocket { virtual void SetSubresourceSpeculation() OVERRIDE {} virtual void SetOmniboxSpeculation() OVERRIDE {} virtual bool WasEverUsed() const OVERRIDE { return false; } - virtual bool UsingTCPFastOpen() const OVERRIDE { return false; } + virtual void EnableTCPFastOpenIfSupported() OVERRIDE { + use_tcp_fastopen_ = true; + } + virtual bool UsingTCPFastOpen() const OVERRIDE { return use_tcp_fastopen_; } virtual bool WasNpnNegotiated() const OVERRIDE { return false; } virtual NextProto GetNegotiatedProtocol() const OVERRIDE { return kProtoUnknown; @@ -261,6 +275,7 @@ class MockTriggerableClientSocket : public StreamSocket { const AddressList addrlist_; BoundNetLog net_log_; CompletionCallback callback_; + bool use_tcp_fastopen_; base::WeakPtrFactory<MockTriggerableClientSocket> weak_factory_; diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc index 1cc015a..2a05b44 100644 --- a/net/socket/transport_client_socket_pool_unittest.cc +++ b/net/socket/transport_client_socket_pool_unittest.cc @@ -40,9 +40,12 @@ class TransportClientSocketPoolTest : public testing::Test { : connect_backup_jobs_enabled_( ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(true)), params_( - new TransportSocketParams(HostPortPair("www.google.com", 80), - false, false, - OnHostResolutionCallback())), + new TransportSocketParams( + HostPortPair("www.google.com", 80), + false, + false, + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)), histograms_(new ClientSocketPoolHistograms("TCPUnitTest")), host_resolver_(new MockHostResolver), client_socket_factory_(&net_log_), @@ -59,10 +62,17 @@ class TransportClientSocketPoolTest : public testing::Test { connect_backup_jobs_enabled_); } + scoped_refptr<TransportSocketParams> CreateParamsForTCPFastOpen() { + return new TransportSocketParams(HostPortPair("www.google.com", 80), + false, false, OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DESIRED); + } + int StartRequest(const std::string& group_name, RequestPriority priority) { scoped_refptr<TransportSocketParams> params(new TransportSocketParams( HostPortPair("www.google.com", 80), false, false, - OnHostResolutionCallback())); + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); return test_base_.StartRequestUsingPool( &pool_, group_name, priority, params); } @@ -201,8 +211,8 @@ TEST_F(TransportClientSocketPoolTest, InitHostResolutionFailure) { ClientSocketHandle handle; HostPortPair host_port_pair("unresolvable.host.name", 80); scoped_refptr<TransportSocketParams> dest(new TransportSocketParams( - host_port_pair, false, false, - OnHostResolutionCallback())); + host_port_pair, false, false, OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", dest, kDefaultPriority, callback.callback(), &pool_, BoundNetLog())); @@ -477,7 +487,8 @@ class RequestSocketCallback : public TestCompletionCallbackBase { within_callback_ = true; scoped_refptr<TransportSocketParams> dest(new TransportSocketParams( HostPortPair("www.google.com", 80), false, false, - OnHostResolutionCallback())); + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); int rv = handle_->Init("a", dest, LOWEST, callback(), pool_, BoundNetLog()); EXPECT_EQ(OK, rv); @@ -497,7 +508,8 @@ TEST_F(TransportClientSocketPoolTest, RequestTwice) { RequestSocketCallback callback(&handle, &pool_); scoped_refptr<TransportSocketParams> dest(new TransportSocketParams( HostPortPair("www.google.com", 80), false, false, - OnHostResolutionCallback())); + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); int rv = handle.Init("a", dest, LOWEST, callback.callback(), &pool_, BoundNetLog()); ASSERT_EQ(ERR_IO_PENDING, rv); @@ -964,6 +976,137 @@ TEST_F(TransportClientSocketPoolTest, IPv4HasNoFallback) { EXPECT_EQ(1, client_socket_factory_.allocation_count()); } +// Test that if TCP FastOpen is enabled, it is set on the socket +// when we have only an IPv4 address. +TEST_F(TransportClientSocketPoolTest, TCPFastOpenOnIPv4WithNoFallback) { + // Create a pool without backup jobs. + ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false); + TransportClientSocketPool pool(kMaxSockets, + kMaxSocketsPerGroup, + histograms_.get(), + host_resolver_.get(), + &client_socket_factory_, + NULL); + client_socket_factory_.set_default_client_socket_type( + MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET); + // Resolve an AddressList with only IPv4 addresses. + host_resolver_->rules()->AddIPLiteralRule("*", "1.1.1.1", std::string()); + + TestCompletionCallback callback; + ClientSocketHandle handle; + // Enable TCP FastOpen in TransportSocketParams. + scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen(); + handle.Init("a", params, LOW, callback.callback(), &pool, BoundNetLog()); + EXPECT_EQ(OK, callback.WaitForResult()); + EXPECT_TRUE(handle.socket()->UsingTCPFastOpen()); +} + +// Test that if TCP FastOpen is enabled, it is set on the socket +// when we have only IPv6 addresses. +TEST_F(TransportClientSocketPoolTest, TCPFastOpenOnIPv6WithNoFallback) { + // Create a pool without backup jobs. + ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false); + TransportClientSocketPool pool(kMaxSockets, + kMaxSocketsPerGroup, + histograms_.get(), + host_resolver_.get(), + &client_socket_factory_, + NULL); + client_socket_factory_.set_default_client_socket_type( + MockTransportClientSocketFactory::MOCK_DELAYED_CLIENT_SOCKET); + // Resolve an AddressList with only IPv6 addresses. + host_resolver_->rules() + ->AddIPLiteralRule("*", "2:abcd::3:4:ff,3:abcd::3:4:ff", std::string()); + + TestCompletionCallback callback; + ClientSocketHandle handle; + // Enable TCP FastOpen in TransportSocketParams. + scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen(); + handle.Init("a", params, LOW, callback.callback(), &pool, BoundNetLog()); + EXPECT_EQ(OK, callback.WaitForResult()); + EXPECT_TRUE(handle.socket()->UsingTCPFastOpen()); +} + +// Test that if TCP FastOpen is enabled, it does not do anything when there +// is a IPv6 address with fallback to an IPv4 address. This test tests the case +// when the IPv6 connect fails and the IPv4 one succeeds. +TEST_F(TransportClientSocketPoolTest, + NoTCPFastOpenOnIPv6FailureWithIPv4Fallback) { + // Create a pool without backup jobs. + ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false); + TransportClientSocketPool pool(kMaxSockets, + kMaxSocketsPerGroup, + histograms_.get(), + host_resolver_.get(), + &client_socket_factory_, + NULL); + + MockTransportClientSocketFactory::ClientSocketType case_types[] = { + // This is the IPv6 socket. + MockTransportClientSocketFactory::MOCK_STALLED_CLIENT_SOCKET, + // This is the IPv4 socket. + MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET + }; + client_socket_factory_.set_client_socket_types(case_types, 2); + // Resolve an AddressList with a IPv6 address first and then a IPv4 address. + host_resolver_->rules() + ->AddIPLiteralRule("*", "2:abcd::3:4:ff,2.2.2.2", std::string()); + + TestCompletionCallback callback; + ClientSocketHandle handle; + // Enable TCP FastOpen in TransportSocketParams. + scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen(); + handle.Init("a", params, LOW, callback.callback(), &pool, BoundNetLog()); + EXPECT_EQ(OK, callback.WaitForResult()); + // Verify that the socket used is connected to the fallback IPv4 address. + IPEndPoint endpoint; + handle.socket()->GetLocalAddress(&endpoint); + EXPECT_EQ(kIPv4AddressSize, endpoint.address().size()); + EXPECT_EQ(2, client_socket_factory_.allocation_count()); + // Verify that TCP FastOpen was not turned on for the socket. + EXPECT_FALSE(handle.socket()->UsingTCPFastOpen()); +} + +// Test that if TCP FastOpen is enabled, it does not do anything when there +// is a IPv6 address with fallback to an IPv4 address. This test tests the case +// when the IPv6 connect succeeds. +TEST_F(TransportClientSocketPoolTest, + NoTCPFastOpenOnIPv6SuccessWithIPv4Fallback) { + // Create a pool without backup jobs. + ClientSocketPoolBaseHelper::set_connect_backup_jobs_enabled(false); + TransportClientSocketPool pool(kMaxSockets, + kMaxSocketsPerGroup, + histograms_.get(), + host_resolver_.get(), + &client_socket_factory_, + NULL); + + MockTransportClientSocketFactory::ClientSocketType case_types[] = { + // This is the IPv6 socket. + MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET, + // This is the IPv4 socket. + MockTransportClientSocketFactory::MOCK_PENDING_CLIENT_SOCKET + }; + client_socket_factory_.set_client_socket_types(case_types, 2); + // Resolve an AddressList with a IPv6 address first and then a IPv4 address. + host_resolver_->rules() + ->AddIPLiteralRule("*", "2:abcd::3:4:ff,2.2.2.2", std::string()); + + TestCompletionCallback callback; + ClientSocketHandle handle; + // Enable TCP FastOpen in TransportSocketParams. + scoped_refptr<TransportSocketParams> params = CreateParamsForTCPFastOpen(); + handle.Init("a", params, LOW, callback.callback(), &pool, BoundNetLog()); + EXPECT_EQ(OK, callback.WaitForResult()); + // Verify that the socket used is connected to the IPv6 address. + IPEndPoint endpoint; + handle.socket()->GetLocalAddress(&endpoint); + EXPECT_EQ(kIPv6AddressSize, endpoint.address().size()); + EXPECT_EQ(1, client_socket_factory_.allocation_count()); + // Verify that TCP FastOpen was not turned on for the socket. + EXPECT_FALSE(handle.socket()->UsingTCPFastOpen()); +} + } // namespace } // namespace net diff --git a/net/socket/websocket_transport_client_socket_pool_unittest.cc b/net/socket/websocket_transport_client_socket_pool_unittest.cc index 38ad6f0..bfb2090 100644 --- a/net/socket/websocket_transport_client_socket_pool_unittest.cc +++ b/net/socket/websocket_transport_client_socket_pool_unittest.cc @@ -51,10 +51,12 @@ void RunLoopForTimePeriod(base::TimeDelta period) { class WebSocketTransportClientSocketPoolTest : public testing::Test { protected: WebSocketTransportClientSocketPoolTest() - : params_(new TransportSocketParams(HostPortPair("www.google.com", 80), - false, - false, - OnHostResolutionCallback())), + : params_(new TransportSocketParams( + HostPortPair("www.google.com", 80), + false, + false, + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)), histograms_(new ClientSocketPoolHistograms("TCPUnitTest")), host_resolver_(new MockHostResolver), client_socket_factory_(&net_log_), @@ -72,10 +74,12 @@ class WebSocketTransportClientSocketPoolTest : public testing::Test { int StartRequest(const std::string& group_name, RequestPriority priority) { scoped_refptr<TransportSocketParams> params( - new TransportSocketParams(HostPortPair("www.google.com", 80), - false, - false, - OnHostResolutionCallback())); + new TransportSocketParams( + HostPortPair("www.google.com", 80), + false, + false, + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); return test_base_.StartRequestUsingPool( &pool_, group_name, priority, params); } @@ -148,7 +152,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, InitHostResolutionFailure) { ClientSocketHandle handle; HostPortPair host_port_pair("unresolvable.host.name", 80); scoped_refptr<TransportSocketParams> dest(new TransportSocketParams( - host_port_pair, false, false, OnHostResolutionCallback())); + host_port_pair, false, false, OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); EXPECT_EQ(ERR_IO_PENDING, handle.Init("a", dest, @@ -398,10 +403,12 @@ class RequestSocketCallback : public TestCompletionCallbackBase { } within_callback_ = true; scoped_refptr<TransportSocketParams> dest( - new TransportSocketParams(HostPortPair("www.google.com", 80), - false, - false, - OnHostResolutionCallback())); + new TransportSocketParams( + HostPortPair("www.google.com", 80), + false, + false, + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); int rv = handle_->Init("a", dest, LOWEST, callback(), pool_, BoundNetLog()); EXPECT_EQ(OK, rv); @@ -420,10 +427,12 @@ TEST_F(WebSocketTransportClientSocketPoolTest, RequestTwice) { ClientSocketHandle handle; RequestSocketCallback callback(&handle, &pool_); scoped_refptr<TransportSocketParams> dest( - new TransportSocketParams(HostPortPair("www.google.com", 80), - false, - false, - OnHostResolutionCallback())); + new TransportSocketParams( + HostPortPair("www.google.com", 80), + false, + false, + OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); int rv = handle.Init( "a", dest, LOWEST, callback.callback(), &pool_, BoundNetLog()); ASSERT_EQ(ERR_IO_PENDING, rv); diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc index ac52ccc..938f6e5 100644 --- a/net/spdy/spdy_session_unittest.cc +++ b/net/spdy/spdy_session_unittest.cc @@ -3139,8 +3139,9 @@ TEST_P(SpdySessionTest, CloseOneIdleConnection) { TestCompletionCallback callback2; HostPortPair host_port2("2.com", 80); scoped_refptr<TransportSocketParams> params2( - new TransportSocketParams(host_port2, false, false, - OnHostResolutionCallback())); + new TransportSocketParams( + host_port2, false, false, OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); EXPECT_EQ(ERR_IO_PENDING, connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY, @@ -3218,8 +3219,9 @@ TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) { TestCompletionCallback callback3; HostPortPair host_port3("3.com", 80); scoped_refptr<TransportSocketParams> params3( - new TransportSocketParams(host_port3, false, false, - OnHostResolutionCallback())); + new TransportSocketParams( + host_port3, false, false, OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle); EXPECT_EQ(ERR_IO_PENDING, connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY, @@ -3307,8 +3309,9 @@ TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) { TestCompletionCallback callback2; HostPortPair host_port2("2.com", 80); scoped_refptr<TransportSocketParams> params2( - new TransportSocketParams(host_port2, false, false, - OnHostResolutionCallback())); + new TransportSocketParams( + host_port2, false, false, OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); EXPECT_EQ(ERR_IO_PENDING, connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY, diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc index 73d0afc..99c0747 100644 --- a/net/spdy/spdy_test_util_common.cc +++ b/net/spdy/spdy_test_util_common.cc @@ -523,8 +523,8 @@ base::WeakPtr<SpdySession> CreateSpdySessionHelper( scoped_refptr<TransportSocketParams> transport_params( new TransportSocketParams( - key.host_port_pair(), false, false, - OnHostResolutionCallback())); + key.host_port_pair(), false, false, OnHostResolutionCallback(), + TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); TestCompletionCallback callback; |