summaryrefslogtreecommitdiff
path: root/net/socket
diff options
context:
space:
mode:
authorCronet Mainline Eng <cronet-mainline-eng+copybara@google.com>2024-01-02 11:58:25 +0000
committerMohannad Farrag <aymanm@google.com>2024-01-02 12:02:18 +0000
commita593a16fd9fcd0dd4906673341bc921abb285b97 (patch)
tree6bca400c3096478188c12c7bf183d8652e8c8591 /net/socket
parentec3a8e8db24bb3ce4b078106b358ca1c4389c14f (diff)
downloadcronet-a593a16fd9fcd0dd4906673341bc921abb285b97.tar.gz
Import Cronet version 121.0.6103.2
FolderOrigin-RevId: /tmp/copybara-origin/src Change-Id: I690becfaba7ad4293eba08b4f9d1aa7f953fce20
Diffstat (limited to 'net/socket')
-rw-r--r--net/socket/client_socket_pool.cc29
-rw-r--r--net/socket/client_socket_pool.h14
-rw-r--r--net/socket/client_socket_pool_base_unittest.cc41
-rw-r--r--net/socket/client_socket_pool_manager.cc62
-rw-r--r--net/socket/client_socket_pool_manager.h41
-rw-r--r--net/socket/client_socket_pool_manager_impl.cc31
-rw-r--r--net/socket/client_socket_pool_manager_impl.h11
-rw-r--r--net/socket/connect_job.cc6
-rw-r--r--net/socket/connect_job.h9
-rw-r--r--net/socket/connect_job_factory.cc129
-rw-r--r--net/socket/connect_job_factory.h14
-rw-r--r--net/socket/connect_job_factory_unittest.cc116
-rw-r--r--net/socket/connect_job_unittest.cc27
-rw-r--r--net/socket/datagram_socket.h4
-rw-r--r--net/socket/fuzzed_datagram_client_socket.cc4
-rw-r--r--net/socket/fuzzed_datagram_client_socket.h1
-rw-r--r--net/socket/mock_client_socket_pool_manager.cc8
-rw-r--r--net/socket/mock_client_socket_pool_manager.h10
-rw-r--r--net/socket/socket_bio_adapter_unittest.cc9
-rw-r--r--net/socket/socket_test_util.cc6
-rw-r--r--net/socket/socket_test_util.h1
-rw-r--r--net/socket/socks_connect_job_unittest.cc23
-rw-r--r--net/socket/ssl_client_socket.cc63
-rw-r--r--net/socket/ssl_client_socket.h10
-rw-r--r--net/socket/ssl_client_socket_impl.cc15
-rw-r--r--net/socket/ssl_client_socket_unittest.cc279
-rw-r--r--net/socket/ssl_connect_job.cc2
-rw-r--r--net/socket/ssl_connect_job_unittest.cc131
-rw-r--r--net/socket/tcp_client_socket.h2
-rw-r--r--net/socket/transport_client_socket_pool.cc33
-rw-r--r--net/socket/transport_client_socket_pool.h10
-rw-r--r--net/socket/transport_client_socket_pool_unittest.cc229
-rw-r--r--net/socket/transport_connect_job_unittest.cc3
-rw-r--r--net/socket/udp_client_socket.cc74
-rw-r--r--net/socket/udp_client_socket.h2
-rw-r--r--net/socket/udp_server_socket.cc4
-rw-r--r--net/socket/udp_server_socket.h1
-rw-r--r--net/socket/udp_socket_posix.cc28
-rw-r--r--net/socket/udp_socket_posix.h4
-rw-r--r--net/socket/udp_socket_unittest.cc4
-rw-r--r--net/socket/udp_socket_win.cc17
-rw-r--r--net/socket/udp_socket_win.h4
-rw-r--r--net/socket/websocket_transport_client_socket_pool.cc6
-rw-r--r--net/socket/websocket_transport_client_socket_pool.h6
-rw-r--r--net/socket/websocket_transport_client_socket_pool_unittest.cc28
45 files changed, 1064 insertions, 487 deletions
diff --git a/net/socket/client_socket_pool.cc b/net/socket/client_socket_pool.cc
index affbe8a90..3e190ffb2 100644
--- a/net/socket/client_socket_pool.cc
+++ b/net/socket/client_socket_pool.cc
@@ -12,7 +12,7 @@
#include "base/functional/bind.h"
#include "net/base/features.h"
#include "net/base/host_port_pair.h"
-#include "net/base/proxy_server.h"
+#include "net/base/proxy_chain.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/http/http_proxy_connect_job.h"
#include "net/log/net_log_event_type.h"
@@ -61,16 +61,17 @@ OnHostResolutionCallbackResult OnHostResolution(
ClientSocketPool::SocketParams::SocketParams(
std::unique_ptr<SSLConfig> ssl_config_for_origin,
- std::unique_ptr<SSLConfig> ssl_config_for_proxy)
+ std::unique_ptr<SSLConfig> base_ssl_config_for_proxies)
: ssl_config_for_origin_(std::move(ssl_config_for_origin)),
- ssl_config_for_proxy_(std::move(ssl_config_for_proxy)) {}
+ base_ssl_config_for_proxies_(std::move(base_ssl_config_for_proxies)) {}
ClientSocketPool::SocketParams::~SocketParams() = default;
scoped_refptr<ClientSocketPool::SocketParams>
ClientSocketPool::SocketParams::CreateForHttpForTesting() {
- return base::MakeRefCounted<SocketParams>(nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */);
+ return base::MakeRefCounted<SocketParams>(
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr);
}
ClientSocketPool::GroupId::GroupId()
@@ -171,7 +172,7 @@ base::Value::Dict ClientSocketPool::NetLogGroupIdParams(
std::unique_ptr<ConnectJob> ClientSocketPool::CreateConnectJob(
GroupId group_id,
scoped_refptr<SocketParams> socket_params,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
RequestPriority request_priority,
SocketTag socket_tag,
@@ -181,21 +182,23 @@ std::unique_ptr<ConnectJob> ClientSocketPool::CreateConnectJob(
// If applicable, set up a callback to handle checking for H2 IP pooling
// opportunities.
OnHostResolutionCallback resolution_callback;
- if (using_ssl && proxy_server.is_direct()) {
+ if (using_ssl && proxy_chain.is_direct()) {
resolution_callback = base::BindRepeating(
&OnHostResolution, common_connect_job_params_->spdy_session_pool,
// TODO(crbug.com/1206799): Pass along as SchemeHostPort.
SpdySessionKey(HostPortPair::FromSchemeHostPort(group_id.destination()),
- proxy_server, group_id.privacy_mode(),
+ proxy_chain, group_id.privacy_mode(),
SpdySessionKey::IsProxySession::kFalse, socket_tag,
group_id.network_anonymization_key(),
group_id.secure_dns_policy()),
is_for_websockets_);
- } else if (proxy_server.is_https()) {
+ } else if (proxy_chain.proxy_server().is_https()) {
+ // TODO(crbug.com/1491092): Determine how to handle session aliasing for
+ // multi-proxy chains. See comments on https://crrev.com/c/4968319.
resolution_callback = base::BindRepeating(
&OnHostResolution, common_connect_job_params_->spdy_session_pool,
- SpdySessionKey(proxy_server.host_port_pair(), ProxyServer::Direct(),
- group_id.privacy_mode(),
+ SpdySessionKey(proxy_chain.proxy_server().host_port_pair(),
+ ProxyChain::Direct(), group_id.privacy_mode(),
SpdySessionKey::IsProxySession::kTrue, socket_tag,
group_id.network_anonymization_key(),
group_id.secure_dns_policy()),
@@ -203,9 +206,9 @@ std::unique_ptr<ConnectJob> ClientSocketPool::CreateConnectJob(
}
return connect_job_factory_->CreateConnectJob(
- group_id.destination(), proxy_server, proxy_annotation_tag,
+ group_id.destination(), proxy_chain, proxy_annotation_tag,
socket_params->ssl_config_for_origin(),
- socket_params->ssl_config_for_proxy(), is_for_websockets_,
+ socket_params->base_ssl_config_for_proxies(), is_for_websockets_,
group_id.privacy_mode(), resolution_callback, request_priority,
socket_tag, group_id.network_anonymization_key(),
group_id.secure_dns_policy(), common_connect_job_params_, delegate);
diff --git a/net/socket/client_socket_pool.h b/net/socket/client_socket_pool.h
index b63e5dd2b..0d86a9bda 100644
--- a/net/socket/client_socket_pool.h
+++ b/net/socket/client_socket_pool.h
@@ -35,7 +35,7 @@ class HttpAuthController;
class HttpResponseInfo;
class NetLogWithSource;
struct NetworkTrafficAnnotationTag;
-class ProxyServer;
+class ProxyChain;
struct SSLConfig;
class StreamSocket;
@@ -165,12 +165,12 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool {
// For non-SSL requests / non-HTTPS proxies, the corresponding SSLConfig
// argument may be nullptr.
SocketParams(std::unique_ptr<SSLConfig> ssl_config_for_origin,
- std::unique_ptr<SSLConfig> ssl_config_for_proxy);
+ std::unique_ptr<SSLConfig> base_ssl_config_for_proxies);
SocketParams(const SocketParams&) = delete;
SocketParams& operator=(const SocketParams&) = delete;
- // Creates a SocketParams object with none of the fields populated. This
+ // Creates a SocketParams object with none of the fields populated. This
// works for the HTTP case only.
static scoped_refptr<SocketParams> CreateForHttpForTesting();
@@ -178,8 +178,8 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool {
return ssl_config_for_origin_.get();
}
- const SSLConfig* ssl_config_for_proxy() const {
- return ssl_config_for_proxy_.get();
+ const SSLConfig* base_ssl_config_for_proxies() const {
+ return base_ssl_config_for_proxies_.get();
}
private:
@@ -187,7 +187,7 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool {
~SocketParams();
std::unique_ptr<SSLConfig> ssl_config_for_origin_;
- std::unique_ptr<SSLConfig> ssl_config_for_proxy_;
+ std::unique_ptr<SSLConfig> base_ssl_config_for_proxies_;
};
ClientSocketPool(const ClientSocketPool&) = delete;
@@ -355,7 +355,7 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool {
std::unique_ptr<ConnectJob> CreateConnectJob(
GroupId group_id,
scoped_refptr<SocketParams> socket_params,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
RequestPriority request_priority,
SocketTag socket_tag,
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index eeba63b47..63f6dc5af 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -31,7 +31,7 @@
#include "net/base/net_errors.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/privacy_mode.h"
-#include "net/base/proxy_server.h"
+#include "net/base/proxy_chain.h"
#include "net/base/proxy_string_util.h"
#include "net/base/request_priority.h"
#include "net/base/schemeful_site.h"
@@ -543,10 +543,10 @@ class TestConnectJobFactory : public ConnectJobFactory {
std::unique_ptr<ConnectJob> CreateConnectJob(
Endpoint endpoint,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
const SSLConfig* ssl_config_for_origin,
- const SSLConfig* ssl_config_for_proxy,
+ const SSLConfig* base_ssl_configs_for_proxies,
bool force_tunnel,
PrivacyMode privacy_mode,
const OnHostResolutionCallback& resolution_callback,
@@ -633,14 +633,14 @@ class ClientSocketPoolBaseTest : public TestWithTaskEnvironment {
base::TimeDelta unused_idle_socket_timeout,
base::TimeDelta used_idle_socket_timeout,
bool enable_backup_connect_jobs = false,
- ProxyServer proxy_server = ProxyServer::Direct()) {
+ ProxyChain proxy_chain = ProxyChain::Direct()) {
DCHECK(!pool_.get());
std::unique_ptr<TestConnectJobFactory> connect_job_factory =
std::make_unique<TestConnectJobFactory>(&client_socket_factory_);
connect_job_factory_ = connect_job_factory.get();
pool_ = TransportClientSocketPool::CreateForTesting(
max_sockets, max_sockets_per_group, unused_idle_socket_timeout,
- used_idle_socket_timeout, proxy_server, /*is_for_websockets=*/false,
+ used_idle_socket_timeout, proxy_chain, /*is_for_websockets=*/false,
&common_connect_job_params_, std::move(connect_job_factory),
nullptr /* ssl_config_service */, enable_backup_connect_jobs);
}
@@ -695,20 +695,21 @@ class ClientSocketPoolBaseTest : public TestWithTaskEnvironment {
size_t completion_count() const { return test_base_.completion_count(); }
const CommonConnectJobParams common_connect_job_params_{
- nullptr /* client_socket_factory */,
- nullptr /* host_resolver */,
- nullptr /* http_auth_cache */,
- nullptr /* http_auth_handler_factory */,
- nullptr /* spdy_session_pool */,
- nullptr /* quic_supported_versions */,
- nullptr /* quic_stream_factory */,
- nullptr /* proxy_delegate */,
- nullptr /* http_user_agent_settings */,
- nullptr /* ssl_client_context */,
- nullptr /* socket_performance_watcher_factory */,
- nullptr /* network_quality_estimator */,
+ /*client_socket_factory=*/nullptr,
+ /*host_resolver=*/nullptr,
+ /*http_auth_cache=*/nullptr,
+ /*http_auth_handler_factory=*/nullptr,
+ /*spdy_session_pool=*/nullptr,
+ /*quic_supported_versions=*/nullptr,
+ /*quic_stream_factory=*/nullptr,
+ /*proxy_delegate=*/nullptr,
+ /*http_user_agent_settings=*/nullptr,
+ /*ssl_client_context=*/nullptr,
+ /*socket_performance_watcher_factory=*/nullptr,
+ /*network_quality_estimator=*/nullptr,
NetLog::Get(),
- nullptr /* websocket_endpoint_lock_manager */};
+ /*websocket_endpoint_lock_manager=*/nullptr,
+ /*http_server_properties=*/nullptr};
bool connect_backup_jobs_enabled_;
MockClientSocketFactory client_socket_factory_;
RecordingNetLogObserver net_log_observer_;
@@ -5730,7 +5731,7 @@ class ClientSocketPoolBaseRefreshTest
max_sockets, max_sockets_per_group, kUnusedIdleSocketTimeout,
ClientSocketPool::used_idle_socket_timeout(),
enable_backup_connect_jobs,
- PacResultElementToProxyServer("HTTPS myproxy:70"));
+ PacResultElementToProxyChain("HTTPS myproxy:70"));
break;
}
}
@@ -5939,7 +5940,7 @@ TEST_F(ClientSocketPoolBaseTest, RefreshProxyRefreshesAllGroups) {
kUnusedIdleSocketTimeout,
ClientSocketPool::used_idle_socket_timeout(),
false /* no backup connect jobs */,
- PacResultElementToProxyServer("HTTPS myproxy:70"));
+ PacResultElementToProxyChain("HTTPS myproxy:70"));
const ClientSocketPool::GroupId kGroupId1 =
TestGroupId("a", 443, url::kHttpsScheme);
diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc
index 521ebc8f5..6f28558c4 100644
--- a/net/socket/client_socket_pool_manager.cc
+++ b/net/socket/client_socket_pool_manager.cc
@@ -13,6 +13,8 @@
#include "build/build_config.h"
#include "net/base/features.h"
#include "net/base/load_flags.h"
+#include "net/base/proxy_chain.h"
+#include "net/base/proxy_server.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/http/http_stream_factory.h"
#include "net/proxy_resolution/proxy_info.h"
@@ -56,31 +58,31 @@ static_assert(std::size(g_max_sockets_per_group) ==
HttpNetworkSession::NUM_SOCKET_POOL_TYPES,
"max sockets per group length mismatch");
-// The max number of sockets to allow per proxy server. This applies both to
+// The max number of sockets to allow per proxy chain. This applies both to
// http and SOCKS proxies. See http://crbug.com/12066 and
-// http://crbug.com/44501 for details about proxy server connection limits.
-int g_max_sockets_per_proxy_server[] = {
- kDefaultMaxSocketsPerProxyServer, // NORMAL_SOCKET_POOL
- kDefaultMaxSocketsPerProxyServer // WEBSOCKET_SOCKET_POOL
+// http://crbug.com/44501 for details about proxy chain connection limits.
+int g_max_sockets_per_proxy_chain[] = {
+ kDefaultMaxSocketsPerProxyChain, // NORMAL_SOCKET_POOL
+ kDefaultMaxSocketsPerProxyChain // WEBSOCKET_SOCKET_POOL
};
-static_assert(std::size(g_max_sockets_per_proxy_server) ==
+static_assert(std::size(g_max_sockets_per_proxy_chain) ==
HttpNetworkSession::NUM_SOCKET_POOL_TYPES,
- "max sockets per proxy server length mismatch");
+ "max sockets per proxy chain length mismatch");
// TODO(https://crbug.com/921369) In order to resolve longstanding issues
// related to pooling distinguishable sockets together, get rid of SocketParams
// entirely.
scoped_refptr<ClientSocketPool::SocketParams> CreateSocketParams(
const ClientSocketPool::GroupId& group_id,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const SSLConfig& ssl_config_for_origin,
- const SSLConfig& ssl_config_for_proxy) {
+ const SSLConfig& base_ssl_config_for_proxies) {
bool using_ssl = GURL::SchemeIsCryptographic(group_id.destination().scheme());
- bool using_proxy_ssl = proxy_server.is_secure_http_like();
+ bool using_proxy_ssl = proxy_chain.proxy_server().is_secure_http_like();
return base::MakeRefCounted<ClientSocketPool::SocketParams>(
using_ssl ? std::make_unique<SSLConfig>(ssl_config_for_origin) : nullptr,
- using_proxy_ssl ? std::make_unique<SSLConfig>(ssl_config_for_proxy)
+ using_proxy_ssl ? std::make_unique<SSLConfig>(base_ssl_config_for_proxies)
: nullptr);
}
@@ -91,7 +93,7 @@ int InitSocketPoolHelper(
HttpNetworkSession* session,
const ProxyInfo& proxy_info,
const SSLConfig& ssl_config_for_origin,
- const SSLConfig& ssl_config_for_proxy,
+ const SSLConfig& base_ssl_config_for_proxies,
bool is_for_websockets,
PrivacyMode privacy_mode,
NetworkAnonymizationKey network_anonymization_key,
@@ -118,11 +120,11 @@ int InitSocketPoolHelper(
std::move(endpoint), privacy_mode, std::move(network_anonymization_key),
secure_dns_policy);
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
- CreateSocketParams(connection_group, proxy_info.proxy_server(),
- ssl_config_for_origin, ssl_config_for_proxy);
+ CreateSocketParams(connection_group, proxy_info.proxy_chain(),
+ ssl_config_for_origin, base_ssl_config_for_proxies);
ClientSocketPool* pool =
- session->GetSocketPool(socket_pool_type, proxy_info.proxy_server());
+ session->GetSocketPool(socket_pool_type, proxy_info.proxy_chain());
ClientSocketPool::RespectLimits respect_limits =
ClientSocketPool::RespectLimits::ENABLED;
if ((request_load_flags & LOAD_IGNORE_LIMITS) != 0)
@@ -187,28 +189,28 @@ void ClientSocketPoolManager::set_max_sockets_per_group(
DCHECK_GE(g_max_sockets_per_pool[pool_type],
g_max_sockets_per_group[pool_type]);
- DCHECK_GE(g_max_sockets_per_proxy_server[pool_type],
+ DCHECK_GE(g_max_sockets_per_proxy_chain[pool_type],
g_max_sockets_per_group[pool_type]);
}
// static
-int ClientSocketPoolManager::max_sockets_per_proxy_server(
+int ClientSocketPoolManager::max_sockets_per_proxy_chain(
HttpNetworkSession::SocketPoolType pool_type) {
DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
- return g_max_sockets_per_proxy_server[pool_type];
+ return g_max_sockets_per_proxy_chain[pool_type];
}
// static
-void ClientSocketPoolManager::set_max_sockets_per_proxy_server(
+void ClientSocketPoolManager::set_max_sockets_per_proxy_chain(
HttpNetworkSession::SocketPoolType pool_type,
int socket_count) {
DCHECK_LT(0, socket_count);
DCHECK_GT(100, socket_count); // Sanity check.
DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES);
// Assert this case early on. The max number of sockets per group cannot
- // exceed the max number of sockets per proxy server.
+ // exceed the max number of sockets per proxy chain.
DCHECK_LE(g_max_sockets_per_group[pool_type], socket_count);
- g_max_sockets_per_proxy_server[pool_type] = socket_count;
+ g_max_sockets_per_proxy_chain[pool_type] = socket_count;
}
// static
@@ -226,7 +228,7 @@ int InitSocketHandleForHttpRequest(
HttpNetworkSession* session,
const ProxyInfo& proxy_info,
const SSLConfig& ssl_config_for_origin,
- const SSLConfig& ssl_config_for_proxy,
+ const SSLConfig& base_ssl_config_for_proxies,
PrivacyMode privacy_mode,
NetworkAnonymizationKey network_anonymization_key,
SecureDnsPolicy secure_dns_policy,
@@ -238,8 +240,8 @@ int InitSocketHandleForHttpRequest(
DCHECK(socket_handle);
return InitSocketPoolHelper(
std::move(endpoint), request_load_flags, request_priority, session,
- proxy_info, ssl_config_for_origin, ssl_config_for_proxy,
- false /* is_for_websockets */, privacy_mode,
+ proxy_info, ssl_config_for_origin, base_ssl_config_for_proxies,
+ /*is_for_websockets=*/false, privacy_mode,
std::move(network_anonymization_key), secure_dns_policy, socket_tag,
net_log, 0, socket_handle, HttpNetworkSession::NORMAL_SOCKET_POOL,
std::move(callback), proxy_auth_callback);
@@ -252,7 +254,7 @@ int InitSocketHandleForWebSocketRequest(
HttpNetworkSession* session,
const ProxyInfo& proxy_info,
const SSLConfig& ssl_config_for_origin,
- const SSLConfig& ssl_config_for_proxy,
+ const SSLConfig& base_ssl_config_for_proxies,
PrivacyMode privacy_mode,
NetworkAnonymizationKey network_anonymization_key,
const NetLogWithSource& net_log,
@@ -271,8 +273,8 @@ int InitSocketHandleForWebSocketRequest(
return InitSocketPoolHelper(
std::move(endpoint), request_load_flags, request_priority, session,
- proxy_info, ssl_config_for_origin, ssl_config_for_proxy,
- true /* is_for_websockets */, privacy_mode,
+ proxy_info, ssl_config_for_origin, base_ssl_config_for_proxies,
+ /*is_for_websockets=*/true, privacy_mode,
std::move(network_anonymization_key), SecureDnsPolicy::kAllow,
SocketTag(), net_log, 0, socket_handle,
HttpNetworkSession::WEBSOCKET_SOCKET_POOL, std::move(callback),
@@ -286,7 +288,7 @@ int PreconnectSocketsForHttpRequest(
HttpNetworkSession* session,
const ProxyInfo& proxy_info,
const SSLConfig& ssl_config_for_origin,
- const SSLConfig& ssl_config_for_proxy,
+ const SSLConfig& base_ssl_config_for_proxies,
PrivacyMode privacy_mode,
NetworkAnonymizationKey network_anonymization_key,
SecureDnsPolicy secure_dns_policy,
@@ -303,8 +305,8 @@ int PreconnectSocketsForHttpRequest(
return InitSocketPoolHelper(
std::move(endpoint), request_load_flags, request_priority, session,
- proxy_info, ssl_config_for_origin, ssl_config_for_proxy,
- false /* force_tunnel */, privacy_mode,
+ proxy_info, ssl_config_for_origin, base_ssl_config_for_proxies,
+ /*is_for_websockets=*/false, privacy_mode,
std::move(network_anonymization_key), secure_dns_policy, SocketTag(),
net_log, num_preconnect_streams, nullptr,
HttpNetworkSession::NORMAL_SOCKET_POOL, std::move(callback),
diff --git a/net/socket/client_socket_pool_manager.h b/net/socket/client_socket_pool_manager.h
index cb0f0e9ea..fc08f89b0 100644
--- a/net/socket/client_socket_pool_manager.h
+++ b/net/socket/client_socket_pool_manager.h
@@ -24,11 +24,11 @@ class ClientSocketHandle;
class NetLogWithSource;
class NetworkAnonymizationKey;
class ProxyInfo;
-class ProxyServer;
+class ProxyChain;
struct SSLConfig;
-constexpr int kDefaultMaxSocketsPerProxyServer = 32;
+constexpr int kDefaultMaxSocketsPerProxyChain = 32;
class NET_EXPORT_PRIVATE ClientSocketPoolManager {
public:
@@ -49,9 +49,9 @@ class NET_EXPORT_PRIVATE ClientSocketPoolManager {
HttpNetworkSession::SocketPoolType pool_type,
int socket_count);
- static int max_sockets_per_proxy_server(
+ static int max_sockets_per_proxy_chain(
HttpNetworkSession::SocketPoolType pool_type);
- static void set_max_sockets_per_proxy_server(
+ static void set_max_sockets_per_proxy_chain(
HttpNetworkSession::SocketPoolType pool_type,
int socket_count);
@@ -64,9 +64,9 @@ class NET_EXPORT_PRIVATE ClientSocketPoolManager {
const char* net_log_reason_utf8) = 0;
virtual void CloseIdleSockets(const char* net_log_reason_utf8) = 0;
- // Returns the socket pool for the specified ProxyServer (Which may be
- // ProxyServer::Direct()).
- virtual ClientSocketPool* GetSocketPool(const ProxyServer& proxy_server) = 0;
+ // Returns the socket pool for the specified ProxyChain (Which may be
+ // ProxyChain::Direct()).
+ virtual ClientSocketPool* GetSocketPool(const ProxyChain& proxy_chain) = 0;
// Creates a Value summary of the state of the socket pools.
virtual base::Value SocketPoolInfoToValue() const = 0;
@@ -74,11 +74,11 @@ class NET_EXPORT_PRIVATE ClientSocketPoolManager {
// A helper method that uses the passed in proxy information to initialize a
// ClientSocketHandle with the relevant socket pool. Use this method for
-// HTTP/HTTPS requests. |ssl_config_for_origin| is only used if the request
-// uses SSL and |ssl_config_for_proxy| is used if the proxy server is HTTPS.
-// |resolution_callback| will be invoked after the the hostname is
-// resolved. If |resolution_callback| does not return OK, then the
-// connection will be aborted with that value.
+// HTTP/HTTPS requests. `ssl_config_for_origin` is only used if the request
+// uses SSL and `base_ssl_config_for_proxies` is used if the proxy server(s)
+// are HTTPS. `resolution_callback` will be invoked after the the hostname is
+// resolved. If `resolution_callback` does not return OK, then the connection
+// will be aborted with that value.
int InitSocketHandleForHttpRequest(
url::SchemeHostPort endpoint,
int request_load_flags,
@@ -86,7 +86,7 @@ int InitSocketHandleForHttpRequest(
HttpNetworkSession* session,
const ProxyInfo& proxy_info,
const SSLConfig& ssl_config_for_origin,
- const SSLConfig& ssl_config_for_proxy,
+ const SSLConfig& base_ssl_config_for_proxies,
PrivacyMode privacy_mode,
NetworkAnonymizationKey network_anonymization_key,
SecureDnsPolicy secure_dns_policy,
@@ -99,12 +99,11 @@ int InitSocketHandleForHttpRequest(
// A helper method that uses the passed in proxy information to initialize a
// ClientSocketHandle with the relevant socket pool. Use this method for
// HTTP/HTTPS requests for WebSocket handshake.
-// |ssl_config_for_origin| is only used if the request
-// uses SSL and |ssl_config_for_proxy| is used if the proxy server is HTTPS.
-// |resolution_callback| will be invoked after the the hostname is
-// resolved. If |resolution_callback| does not return OK, then the
-// connection will be aborted with that value.
-// This function uses WEBSOCKET_SOCKET_POOL socket pools.
+// `ssl_config_for_origin` is only used if the request uses SSL and
+// `base_ssl_config_for_proxies` is used if the proxy server(s) are HTTPS.
+// `resolution_callback` will be invoked after the the hostname is resolved. If
+// `resolution_callback` does not return OK, then the connection will be aborted
+// with that value. This function uses WEBSOCKET_SOCKET_POOL socket pools.
int InitSocketHandleForWebSocketRequest(
url::SchemeHostPort endpoint,
int request_load_flags,
@@ -112,7 +111,7 @@ int InitSocketHandleForWebSocketRequest(
HttpNetworkSession* session,
const ProxyInfo& proxy_info,
const SSLConfig& ssl_config_for_origin,
- const SSLConfig& ssl_config_for_proxy,
+ const SSLConfig& base_ssl_config_for_proxies,
PrivacyMode privacy_mode,
NetworkAnonymizationKey network_anonymization_key,
const NetLogWithSource& net_log,
@@ -129,7 +128,7 @@ int PreconnectSocketsForHttpRequest(
HttpNetworkSession* session,
const ProxyInfo& proxy_info,
const SSLConfig& ssl_config_for_origin,
- const SSLConfig& ssl_config_for_proxy,
+ const SSLConfig& base_ssl_config_for_proxies,
PrivacyMode privacy_mode,
NetworkAnonymizationKey network_anonymization_key,
SecureDnsPolicy secure_dns_policy,
diff --git a/net/socket/client_socket_pool_manager_impl.cc b/net/socket/client_socket_pool_manager_impl.cc
index 530f49cd2..5af1ffc5b 100644
--- a/net/socket/client_socket_pool_manager_impl.cc
+++ b/net/socket/client_socket_pool_manager_impl.cc
@@ -9,6 +9,7 @@
#include "base/check_op.h"
#include "base/values.h"
+#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/proxy_string_util.h"
#include "net/http/http_network_session.h"
@@ -57,40 +58,40 @@ void ClientSocketPoolManagerImpl::CloseIdleSockets(
}
ClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPool(
- const ProxyServer& proxy_server) {
- SocketPoolMap::const_iterator it = socket_pools_.find(proxy_server);
+ const ProxyChain& proxy_chain) {
+ SocketPoolMap::const_iterator it = socket_pools_.find(proxy_chain);
if (it != socket_pools_.end())
return it->second.get();
- int sockets_per_proxy_server;
+ int sockets_per_proxy_chain;
int sockets_per_group;
- if (proxy_server.is_direct()) {
- sockets_per_proxy_server = max_sockets_per_pool(pool_type_);
+ if (proxy_chain.is_direct()) {
+ sockets_per_proxy_chain = max_sockets_per_pool(pool_type_);
sockets_per_group = max_sockets_per_group(pool_type_);
} else {
- sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_);
+ sockets_per_proxy_chain = max_sockets_per_proxy_chain(pool_type_);
sockets_per_group =
- std::min(sockets_per_proxy_server, max_sockets_per_group(pool_type_));
+ std::min(sockets_per_proxy_chain, max_sockets_per_group(pool_type_));
}
std::unique_ptr<ClientSocketPool> new_pool;
- // Use specialized WebSockets pool for WebSockets when no proxy is in use.
+ // Use specialized WebSockets pool for WebSockets when no proxies are in use.
if (pool_type_ == HttpNetworkSession::WEBSOCKET_SOCKET_POOL &&
- proxy_server.is_direct()) {
+ proxy_chain.is_direct()) {
new_pool = std::make_unique<WebSocketTransportClientSocketPool>(
- sockets_per_proxy_server, sockets_per_group, proxy_server,
+ sockets_per_proxy_chain, sockets_per_group, proxy_chain,
&websocket_common_connect_job_params_);
} else {
new_pool = std::make_unique<TransportClientSocketPool>(
- sockets_per_proxy_server, sockets_per_group,
- unused_idle_socket_timeout(pool_type_), proxy_server,
+ sockets_per_proxy_chain, sockets_per_group,
+ unused_idle_socket_timeout(pool_type_), proxy_chain,
pool_type_ == HttpNetworkSession::WEBSOCKET_SOCKET_POOL,
&common_connect_job_params_, cleanup_on_ip_address_change_);
}
std::pair<SocketPoolMap::iterator, bool> ret =
- socket_pools_.insert(std::make_pair(proxy_server, std::move(new_pool)));
+ socket_pools_.insert(std::make_pair(proxy_chain, std::move(new_pool)));
return ret.first->second.get();
}
@@ -101,13 +102,13 @@ base::Value ClientSocketPoolManagerImpl::SocketPoolInfoToValue() const {
const char* type;
if (socket_pool.first.is_direct()) {
type = "transport_socket_pool";
- } else if (socket_pool.first.is_socks()) {
+ } else if (socket_pool.first.proxy_server().is_socks()) {
type = "socks_socket_pool";
} else {
type = "http_proxy_socket_pool";
}
list.Append(socket_pool.second->GetInfoAsValue(
- ProxyServerToProxyUri(socket_pool.first), type));
+ ProxyServerToProxyUri(socket_pool.first.proxy_server()), type));
}
return base::Value(std::move(list));
diff --git a/net/socket/client_socket_pool_manager_impl.h b/net/socket/client_socket_pool_manager_impl.h
index e85ff5390..38d13cee5 100644
--- a/net/socket/client_socket_pool_manager_impl.h
+++ b/net/socket/client_socket_pool_manager_impl.h
@@ -20,14 +20,14 @@
namespace net {
-class ProxyServer;
+class ProxyChain;
class ClientSocketPool;
class NET_EXPORT_PRIVATE ClientSocketPoolManagerImpl
: public ClientSocketPoolManager {
public:
- // |websocket_common_connect_job_params| is only used for direct WebSocket
- // connections (No proxy in use). It's never used if |pool_type| is not
+ // `websocket_common_connect_job_params` is only used for direct WebSocket
+ // connections (No proxies in use). It's never used if `pool_type` is not
// HttpNetworkSession::SocketPoolType::WEBSOCKET_SOCKET_POOL.
ClientSocketPoolManagerImpl(
const CommonConnectJobParams& common_connect_job_params,
@@ -45,14 +45,13 @@ class NET_EXPORT_PRIVATE ClientSocketPoolManagerImpl
const char* net_log_reason_utf8) override;
void CloseIdleSockets(const char* net_log_reason_utf8) override;
- ClientSocketPool* GetSocketPool(const ProxyServer& proxy_server) override;
+ ClientSocketPool* GetSocketPool(const ProxyChain& proxy_chain) override;
// Creates a Value summary of the state of the socket pools.
base::Value SocketPoolInfoToValue() const override;
private:
- using SocketPoolMap =
- std::map<ProxyServer, std::unique_ptr<ClientSocketPool>>;
+ using SocketPoolMap = std::map<ProxyChain, std::unique_ptr<ClientSocketPool>>;
const CommonConnectJobParams common_connect_job_params_;
// Used only for direct WebSocket connections (i.e., no proxy in use).
diff --git a/net/socket/connect_job.cc b/net/socket/connect_job.cc
index 71dc8243c..580c9342f 100644
--- a/net/socket/connect_job.cc
+++ b/net/socket/connect_job.cc
@@ -41,7 +41,8 @@ CommonConnectJobParams::CommonConnectJobParams(
SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
NetworkQualityEstimator* network_quality_estimator,
NetLog* net_log,
- WebSocketEndpointLockManager* websocket_endpoint_lock_manager)
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
+ HttpServerProperties* http_server_properties)
: client_socket_factory(client_socket_factory),
host_resolver(host_resolver),
http_auth_cache(http_auth_cache),
@@ -55,7 +56,8 @@ CommonConnectJobParams::CommonConnectJobParams(
socket_performance_watcher_factory(socket_performance_watcher_factory),
network_quality_estimator(network_quality_estimator),
net_log(net_log),
- websocket_endpoint_lock_manager(websocket_endpoint_lock_manager) {}
+ websocket_endpoint_lock_manager(websocket_endpoint_lock_manager),
+ http_server_properties(http_server_properties) {}
CommonConnectJobParams::CommonConnectJobParams(
const CommonConnectJobParams& other) = default;
diff --git a/net/socket/connect_job.h b/net/socket/connect_job.h
index 2f810362a..fb237414c 100644
--- a/net/socket/connect_job.h
+++ b/net/socket/connect_job.h
@@ -21,6 +21,7 @@
#include "net/base/request_priority.h"
#include "net/dns/public/host_resolver_results.h"
#include "net/dns/public/resolve_error_info.h"
+#include "net/http/http_server_properties.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/connection_attempts.h"
#include "net/socket/socket_tag.h"
@@ -71,7 +72,8 @@ struct NET_EXPORT_PRIVATE CommonConnectJobParams {
SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
NetworkQualityEstimator* network_quality_estimator,
NetLog* net_log,
- WebSocketEndpointLockManager* websocket_endpoint_lock_manager);
+ WebSocketEndpointLockManager* websocket_endpoint_lock_manager,
+ HttpServerProperties* http_server_properties);
CommonConnectJobParams(const CommonConnectJobParams& other);
~CommonConnectJobParams();
@@ -93,6 +95,8 @@ struct NET_EXPORT_PRIVATE CommonConnectJobParams {
// This must only be non-null for WebSockets.
raw_ptr<WebSocketEndpointLockManager> websocket_endpoint_lock_manager;
+
+ raw_ptr<HttpServerProperties> http_server_properties;
};
// When a host resolution completes, OnHostResolutionCallback() is invoked. If
@@ -274,6 +278,9 @@ class NET_EXPORT_PRIVATE ConnectJob {
WebSocketEndpointLockManager* websocket_endpoint_lock_manager() {
return common_connect_job_params_->websocket_endpoint_lock_manager;
}
+ HttpServerProperties* http_server_properties() {
+ return common_connect_job_params_->http_server_properties;
+ }
const CommonConnectJobParams* common_connect_job_params() const {
return common_connect_job_params_;
}
diff --git a/net/socket/connect_job_factory.cc b/net/socket/connect_job_factory.cc
index 778faf5c0..999bbcff3 100644
--- a/net/socket/connect_job_factory.cc
+++ b/net/socket/connect_job_factory.cc
@@ -13,6 +13,7 @@
#include "net/base/host_port_pair.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/privacy_mode.h"
+#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
#include "net/dns/public/secure_dns_policy.h"
@@ -105,10 +106,10 @@ ConnectJobFactory::~ConnectJobFactory() = default;
std::unique_ptr<ConnectJob> ConnectJobFactory::CreateConnectJob(
url::SchemeHostPort endpoint,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
const SSLConfig* ssl_config_for_origin,
- const SSLConfig* ssl_config_for_proxy,
+ const SSLConfig* base_ssl_config_for_proxies,
bool force_tunnel,
PrivacyMode privacy_mode,
const OnHostResolutionCallback& resolution_callback,
@@ -118,21 +119,21 @@ std::unique_ptr<ConnectJob> ConnectJobFactory::CreateConnectJob(
SecureDnsPolicy secure_dns_policy,
const CommonConnectJobParams* common_connect_job_params,
ConnectJob::Delegate* delegate) const {
- return CreateConnectJob(Endpoint(std::move(endpoint)), proxy_server,
- proxy_annotation_tag, ssl_config_for_origin,
- ssl_config_for_proxy, force_tunnel, privacy_mode,
- resolution_callback, request_priority, socket_tag,
- network_anonymization_key, secure_dns_policy,
- common_connect_job_params, delegate);
+ return CreateConnectJob(
+ Endpoint(std::move(endpoint)), proxy_chain, proxy_annotation_tag,
+ ssl_config_for_origin, base_ssl_config_for_proxies, force_tunnel,
+ privacy_mode, resolution_callback, request_priority, socket_tag,
+ network_anonymization_key, secure_dns_policy, common_connect_job_params,
+ delegate);
}
std::unique_ptr<ConnectJob> ConnectJobFactory::CreateConnectJob(
bool using_ssl,
HostPortPair endpoint,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
const SSLConfig* ssl_config_for_origin,
- const SSLConfig* ssl_config_for_proxy,
+ const SSLConfig* base_ssl_config_for_proxies,
bool force_tunnel,
PrivacyMode privacy_mode,
const OnHostResolutionCallback& resolution_callback,
@@ -143,20 +144,20 @@ std::unique_ptr<ConnectJob> ConnectJobFactory::CreateConnectJob(
const CommonConnectJobParams* common_connect_job_params,
ConnectJob::Delegate* delegate) const {
SchemelessEndpoint schemeless_endpoint{using_ssl, std::move(endpoint)};
- return CreateConnectJob(std::move(schemeless_endpoint), proxy_server,
- proxy_annotation_tag, ssl_config_for_origin,
- ssl_config_for_proxy, force_tunnel, privacy_mode,
- resolution_callback, request_priority, socket_tag,
- network_anonymization_key, secure_dns_policy,
- common_connect_job_params, delegate);
+ return CreateConnectJob(
+ std::move(schemeless_endpoint), proxy_chain, proxy_annotation_tag,
+ ssl_config_for_origin, base_ssl_config_for_proxies, force_tunnel,
+ privacy_mode, resolution_callback, request_priority, socket_tag,
+ network_anonymization_key, secure_dns_policy, common_connect_job_params,
+ delegate);
}
std::unique_ptr<ConnectJob> ConnectJobFactory::CreateConnectJob(
Endpoint endpoint,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
const SSLConfig* ssl_config_for_origin,
- const SSLConfig* ssl_config_for_proxy,
+ const SSLConfig* base_ssl_config_for_proxies,
bool force_tunnel,
PrivacyMode privacy_mode,
const OnHostResolutionCallback& resolution_callback,
@@ -170,53 +171,83 @@ std::unique_ptr<ConnectJob> ConnectJobFactory::CreateConnectJob(
scoped_refptr<SOCKSSocketParams> socks_params;
base::flat_set<std::string> no_alpn_protocols;
- if (!proxy_server.is_direct()) {
+ DCHECK(proxy_chain.IsValid());
+ if (!proxy_chain.is_direct()) {
+ SSLConfig first_proxy_server_ssl_config;
+ if (proxy_chain.proxy_server().is_secure_http_like()) {
+ DCHECK(base_ssl_config_for_proxies);
+ first_proxy_server_ssl_config = *base_ssl_config_for_proxies;
+
+ HttpServerProperties* http_server_properties =
+ common_connect_job_params->http_server_properties;
+ if (http_server_properties) {
+ // TODO(https://crbug.com/1491092): Also do this for the other hops if
+ // the proxy chain is multi-hop.
+ if (proxy_chain.proxy_server().is_https()) {
+ http_server_properties->MaybeForceHTTP11(
+ url::SchemeHostPort(
+ url::kHttpsScheme,
+ proxy_chain.proxy_server().host_port_pair().host(),
+ proxy_chain.proxy_server().host_port_pair().port()),
+ network_anonymization_key, &first_proxy_server_ssl_config);
+ }
+ }
+ }
+
// TODO(crbug.com/1206799): For an http-like proxy, should this pass a
// `SchemeHostPort`, so proxies can participate in ECH? Note doing so with
// `SCHEME_HTTP` requires handling the HTTPS record upgrade.
+ const ProxyServer& first_proxy_server =
+ proxy_chain.GetProxyServer(/*chain_index=*/0);
auto proxy_tcp_params = base::MakeRefCounted<TransportSocketParams>(
- proxy_server.host_port_pair(), proxy_dns_network_anonymization_key_,
- secure_dns_policy, resolution_callback,
- proxy_server.is_secure_http_like()
- ? SupportedProtocolsFromSSLConfig(*ssl_config_for_proxy)
+ first_proxy_server.host_port_pair(),
+ proxy_dns_network_anonymization_key_, secure_dns_policy,
+ resolution_callback,
+ first_proxy_server.is_secure_http_like()
+ ? SupportedProtocolsFromSSLConfig(first_proxy_server_ssl_config)
: no_alpn_protocols);
- if (proxy_server.is_http_like()) {
+ if (first_proxy_server.is_http_like()) {
scoped_refptr<SSLSocketParams> ssl_params;
- if (proxy_server.is_secure_http_like()) {
- DCHECK(ssl_config_for_proxy);
- // Set ssl_params, and unset proxy_tcp_params
+ if (first_proxy_server.is_secure_http_like()) {
+ // Set `ssl_params`, and unset `proxy_tcp_params`.
ssl_params = base::MakeRefCounted<SSLSocketParams>(
std::move(proxy_tcp_params), nullptr, nullptr,
- proxy_server.host_port_pair(), *ssl_config_for_proxy,
+ first_proxy_server.host_port_pair(), first_proxy_server_ssl_config,
PRIVACY_MODE_DISABLED, network_anonymization_key);
proxy_tcp_params = nullptr;
}
// TODO(crbug.com/1206799): Pass `endpoint` directly (preserving scheme
// when available)?
+ // TODO(https://crbug.com/1491092): The endpoint parameter here should
+ // correspond to either `endpoint` (for one-hop proxies) or the proxy
+ // server at index 1 (for n-hop proxies).
http_proxy_params = base::MakeRefCounted<HttpProxySocketParams>(
std::move(proxy_tcp_params), std::move(ssl_params),
- proxy_server.is_quic(), ToHostPortPair(endpoint),
+ ToHostPortPair(endpoint), proxy_chain, /*proxy_chain_index=*/0,
force_tunnel || UsingSsl(endpoint), *proxy_annotation_tag,
- network_anonymization_key);
+ network_anonymization_key, secure_dns_policy);
} else {
- DCHECK(proxy_server.is_socks());
+ DCHECK(first_proxy_server.is_socks());
// TODO(crbug.com/1206799): Pass `endpoint` directly (preserving scheme
// when available)?
socks_params = base::MakeRefCounted<SOCKSSocketParams>(
std::move(proxy_tcp_params),
- proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5,
+ first_proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5,
ToHostPortPair(endpoint), network_anonymization_key,
*proxy_annotation_tag);
}
}
+ // TODO(https://crbug.com/1491092): For nested proxies, create additional
+ // SSLSocketParam and HttpProxySocketParam objects for the remaining hops.
+
// Deal with SSL - which layers on top of any given proxy.
if (UsingSsl(endpoint)) {
DCHECK(ssl_config_for_origin);
scoped_refptr<TransportSocketParams> ssl_tcp_params;
- if (proxy_server.is_direct()) {
+ if (proxy_chain.is_direct()) {
ssl_tcp_params = base::MakeRefCounted<TransportSocketParams>(
ToTransportEndpoint(endpoint), network_anonymization_key,
secure_dns_policy, resolution_callback,
@@ -233,26 +264,28 @@ std::unique_ptr<ConnectJob> ConnectJobFactory::CreateConnectJob(
std::move(ssl_params), delegate, /*net_log=*/nullptr);
}
- if (proxy_server.is_http_like()) {
- return http_proxy_connect_job_factory_->Create(
- request_priority, socket_tag, common_connect_job_params,
- std::move(http_proxy_params), delegate, /*net_log=*/nullptr);
+ // Only SSL/TLS-based endpoints have ALPN protocols.
+ if (proxy_chain.is_direct()) {
+ auto tcp_params = base::MakeRefCounted<TransportSocketParams>(
+ ToTransportEndpoint(endpoint), network_anonymization_key,
+ secure_dns_policy, resolution_callback, no_alpn_protocols);
+ return transport_connect_job_factory_->Create(
+ request_priority, socket_tag, common_connect_job_params, tcp_params,
+ delegate, /*net_log=*/nullptr);
}
- if (proxy_server.is_socks()) {
- return socks_connect_job_factory_->Create(
+ const ProxyServer& first_proxy_server =
+ proxy_chain.GetProxyServer(/*chain_index=*/0);
+ if (first_proxy_server.is_http_like()) {
+ return http_proxy_connect_job_factory_->Create(
request_priority, socket_tag, common_connect_job_params,
- std::move(socks_params), delegate, /*net_log=*/nullptr);
+ std::move(http_proxy_params), delegate, /*net_log=*/nullptr);
}
- // Only SSL/TLS-based endpoints have ALPN protocols.
- DCHECK(proxy_server.is_direct());
- auto tcp_params = base::MakeRefCounted<TransportSocketParams>(
- ToTransportEndpoint(endpoint), network_anonymization_key,
- secure_dns_policy, resolution_callback, no_alpn_protocols);
- return transport_connect_job_factory_->Create(
- request_priority, socket_tag, common_connect_job_params, tcp_params,
- delegate, /*net_log=*/nullptr);
+ DCHECK(first_proxy_server.is_socks());
+ return socks_connect_job_factory_->Create(
+ request_priority, socket_tag, common_connect_job_params,
+ std::move(socks_params), delegate, /*net_log=*/nullptr);
}
} // namespace net
diff --git a/net/socket/connect_job_factory.h b/net/socket/connect_job_factory.h
index 6ea30912c..4fb6dc3e2 100644
--- a/net/socket/connect_job_factory.h
+++ b/net/socket/connect_job_factory.h
@@ -26,7 +26,7 @@ namespace net {
class NetworkAnonymizationKey;
struct NetworkTrafficAnnotationTag;
-class ProxyServer;
+class ProxyChain;
struct SSLConfig;
// Common factory for all ConnectJob types. Determines and creates the correct
@@ -64,10 +64,10 @@ class NET_EXPORT_PRIVATE ConnectJobFactory {
// ConnectJob.
std::unique_ptr<ConnectJob> CreateConnectJob(
url::SchemeHostPort endpoint,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
const SSLConfig* ssl_config_for_origin,
- const SSLConfig* ssl_config_for_proxy,
+ const SSLConfig* base_ssl_config_for_proxies,
bool force_tunnel,
PrivacyMode privacy_mode,
const OnHostResolutionCallback& resolution_callback,
@@ -83,10 +83,10 @@ class NET_EXPORT_PRIVATE ConnectJobFactory {
std::unique_ptr<ConnectJob> CreateConnectJob(
bool using_ssl,
HostPortPair endpoint,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
const SSLConfig* ssl_config_for_origin,
- const SSLConfig* ssl_config_for_proxy,
+ const SSLConfig* base_ssl_config_for_proxies,
bool force_tunnel,
PrivacyMode privacy_mode,
const OnHostResolutionCallback& resolution_callback,
@@ -100,10 +100,10 @@ class NET_EXPORT_PRIVATE ConnectJobFactory {
private:
virtual std::unique_ptr<ConnectJob> CreateConnectJob(
Endpoint endpoint,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const absl::optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag,
const SSLConfig* ssl_config_for_origin,
- const SSLConfig* ssl_config_for_proxy,
+ const SSLConfig* base_ssl_config_for_proxies,
bool force_tunnel,
PrivacyMode privacy_mode,
const OnHostResolutionCallback& resolution_callback,
diff --git a/net/socket/connect_job_factory_unittest.cc b/net/socket/connect_job_factory_unittest.cc
index d3b0268af..c149773bb 100644
--- a/net/socket/connect_job_factory_unittest.cc
+++ b/net/socket/connect_job_factory_unittest.cc
@@ -12,6 +12,7 @@
#include "net/base/host_port_pair.h"
#include "net/base/network_isolation_key.h"
#include "net/base/privacy_mode.h"
+#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
#include "net/dns/public/secure_dns_policy.h"
@@ -182,7 +183,8 @@ class ConnectJobFactoryTest : public TestWithTaskEnvironment {
/*socket_performance_watcher_factory=*/nullptr,
/*network_quality_estimator=*/nullptr,
/*net_log=*/nullptr,
- /*websocket_endpoint_lock_manager=*/nullptr};
+ /*websocket_endpoint_lock_manager=*/nullptr,
+ /*http_server_properties=*/nullptr};
TestConnectJobDelegate delegate_;
std::unique_ptr<ConnectJobFactory> factory_;
@@ -196,10 +198,10 @@ TEST_F(ConnectJobFactoryTest, CreateConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
- kEndpoint, ProxyServer::Direct(),
+ kEndpoint, ProxyChain::Direct(),
/*proxy_annotation_tag=*/absl::nullopt,
/*ssl_config_for_origin=*/nullptr,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -217,10 +219,10 @@ TEST_F(ConnectJobFactoryTest, CreateConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 82);
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
- /*using_ssl=*/false, kEndpoint, ProxyServer::Direct(),
+ /*using_ssl=*/false, kEndpoint, ProxyChain::Direct(),
/*proxy_annotation_tag=*/absl::nullopt,
/*ssl_config_for_origin=*/nullptr,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -240,10 +242,10 @@ TEST_F(ConnectJobFactoryTest, CreateHttpsConnectJob) {
ssl_config.alpn_protos = {kProtoHTTP2, kProtoHTTP11};
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
- kEndpoint, ProxyServer::Direct(),
+ kEndpoint, ProxyChain::Direct(),
/*proxy_annotation_tag=*/absl::nullopt,
/*ssl_config_for_origin=*/&ssl_config,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -269,10 +271,10 @@ TEST_F(ConnectJobFactoryTest, CreateHttpsConnectJobWithoutScheme) {
SSLConfig ssl_config;
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
- /*using_ssl=*/true, kEndpoint, ProxyServer::Direct(),
+ /*using_ssl=*/true, kEndpoint, ProxyChain::Direct(),
/*proxy_annotation_tag=*/absl::nullopt,
/*ssl_config_for_origin=*/&ssl_config,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -292,13 +294,13 @@ TEST_F(ConnectJobFactoryTest, CreateHttpsConnectJobWithoutScheme) {
TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 85);
- const ProxyServer kProxy(ProxyServer::SCHEME_HTTP,
- HostPortPair("proxy.test", 86));
+ const ProxyChain kProxy(ProxyServer::SCHEME_HTTP,
+ HostPortPair("proxy.test", 86));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*ssl_config_for_origin=*/nullptr,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -308,24 +310,25 @@ TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJob) {
ASSERT_THAT(http_proxy_job_factory_->params(), testing::SizeIs(1));
const HttpProxySocketParams& params =
*http_proxy_job_factory_->params().front();
- EXPECT_FALSE(params.is_quic());
+ EXPECT_FALSE(params.proxy_server().is_quic());
EXPECT_EQ(params.endpoint(), HostPortPair::FromSchemeHostPort(kEndpoint));
ASSERT_TRUE(params.transport_params());
const TransportSocketParams& transport_params = *params.transport_params();
EXPECT_THAT(transport_params.destination(),
- testing::VariantWith<HostPortPair>(kProxy.host_port_pair()));
+ testing::VariantWith<HostPortPair>(
+ kProxy.proxy_server().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 85);
- const ProxyServer kProxy(ProxyServer::SCHEME_HTTP,
- HostPortPair("proxy.test", 86));
+ const ProxyChain kProxy(ProxyServer::SCHEME_HTTP,
+ HostPortPair("proxy.test", 86));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/false, kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*ssl_config_for_origin=*/nullptr,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -335,25 +338,26 @@ TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJobWithoutScheme) {
ASSERT_THAT(http_proxy_job_factory_->params(), testing::SizeIs(1));
const HttpProxySocketParams& params =
*http_proxy_job_factory_->params().front();
- EXPECT_FALSE(params.is_quic());
+ EXPECT_FALSE(params.proxy_server().is_quic());
EXPECT_EQ(params.endpoint(), kEndpoint);
ASSERT_TRUE(params.transport_params());
const TransportSocketParams& transport_params = *params.transport_params();
EXPECT_THAT(transport_params.destination(),
- testing::VariantWith<HostPortPair>(kProxy.host_port_pair()));
+ testing::VariantWith<HostPortPair>(
+ kProxy.proxy_server().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJobForHttps) {
const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 87);
- const ProxyServer kProxy(ProxyServer::SCHEME_HTTP,
- HostPortPair("proxy.test", 88));
+ const ProxyChain kProxy(ProxyServer::SCHEME_HTTP,
+ HostPortPair("proxy.test", 88));
SSLConfig ssl_config;
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*ssl_config_for_origin=*/&ssl_config,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -368,7 +372,7 @@ TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJobForHttps) {
ASSERT_EQ(params.GetConnectionType(), SSLSocketParams::HTTP_PROXY);
const HttpProxySocketParams& proxy_params =
*params.GetHttpProxyConnectionParams();
- EXPECT_FALSE(proxy_params.is_quic());
+ EXPECT_FALSE(proxy_params.proxy_server().is_quic());
EXPECT_EQ(proxy_params.endpoint(),
HostPortPair::FromSchemeHostPort(kEndpoint));
@@ -376,19 +380,20 @@ TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJobForHttps) {
const TransportSocketParams& transport_params =
*proxy_params.transport_params();
EXPECT_THAT(transport_params.destination(),
- testing::VariantWith<HostPortPair>(kProxy.host_port_pair()));
+ testing::VariantWith<HostPortPair>(
+ kProxy.proxy_server().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJobForHttpsWithoutScheme) {
const HostPortPair kEndpoint("test", 87);
- const ProxyServer kProxy(ProxyServer::SCHEME_HTTP,
- HostPortPair("proxy.test", 88));
+ const ProxyChain kProxy(ProxyServer::SCHEME_HTTP,
+ HostPortPair("proxy.test", 88));
SSLConfig ssl_config;
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/true, kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*ssl_config_for_origin=*/&ssl_config,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -402,26 +407,27 @@ TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJobForHttpsWithoutScheme) {
ASSERT_EQ(params.GetConnectionType(), SSLSocketParams::HTTP_PROXY);
const HttpProxySocketParams& proxy_params =
*params.GetHttpProxyConnectionParams();
- EXPECT_FALSE(proxy_params.is_quic());
+ EXPECT_FALSE(proxy_params.proxy_server().is_quic());
EXPECT_EQ(proxy_params.endpoint(), kEndpoint);
ASSERT_TRUE(proxy_params.transport_params());
const TransportSocketParams& transport_params =
*proxy_params.transport_params();
EXPECT_THAT(transport_params.destination(),
- testing::VariantWith<HostPortPair>(kProxy.host_port_pair()));
+ testing::VariantWith<HostPortPair>(
+ kProxy.proxy_server().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateHttpsProxyConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 89);
- const ProxyServer kProxy(ProxyServer::SCHEME_HTTPS,
- HostPortPair("proxy.test", 90));
+ const ProxyChain kProxy(ProxyServer::SCHEME_HTTPS,
+ HostPortPair("proxy.test", 90));
SSLConfig ssl_config;
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*ssl_config_for_origin=*/nullptr,
- /*ssl_config_for_proxy=*/&ssl_config,
+ /*base_ssl_config_for_proxies=*/&ssl_config,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -431,30 +437,31 @@ TEST_F(ConnectJobFactoryTest, CreateHttpsProxyConnectJob) {
ASSERT_THAT(http_proxy_job_factory_->params(), testing::SizeIs(1));
const HttpProxySocketParams& params =
*http_proxy_job_factory_->params().front();
- EXPECT_FALSE(params.is_quic());
+ EXPECT_FALSE(params.proxy_server().is_quic());
EXPECT_EQ(params.endpoint(), HostPortPair::FromSchemeHostPort(kEndpoint));
ASSERT_TRUE(params.ssl_params());
const SSLSocketParams& ssl_params = *params.ssl_params();
- EXPECT_EQ(ssl_params.host_and_port(), kProxy.host_port_pair());
+ EXPECT_EQ(ssl_params.host_and_port(), kProxy.proxy_server().host_port_pair());
ASSERT_EQ(ssl_params.GetConnectionType(), SSLSocketParams::DIRECT);
const TransportSocketParams& transport_params =
*ssl_params.GetDirectConnectionParams();
EXPECT_THAT(transport_params.destination(),
- testing::VariantWith<HostPortPair>(kProxy.host_port_pair()));
+ testing::VariantWith<HostPortPair>(
+ kProxy.proxy_server().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateHttpsProxyConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 89);
- const ProxyServer kProxy(ProxyServer::SCHEME_HTTPS,
- HostPortPair("proxy.test", 90));
+ const ProxyChain kProxy(ProxyServer::SCHEME_HTTPS,
+ HostPortPair("proxy.test", 90));
SSLConfig ssl_config;
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/false, kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*ssl_config_for_origin=*/nullptr,
- /*ssl_config_for_proxy=*/&ssl_config,
+ /*base_ssl_config_for_proxies=*/&ssl_config,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -464,29 +471,30 @@ TEST_F(ConnectJobFactoryTest, CreateHttpsProxyConnectJobWithoutScheme) {
ASSERT_THAT(http_proxy_job_factory_->params(), testing::SizeIs(1));
const HttpProxySocketParams& params =
*http_proxy_job_factory_->params().front();
- EXPECT_FALSE(params.is_quic());
+ EXPECT_FALSE(params.proxy_server().is_quic());
EXPECT_EQ(params.endpoint(), kEndpoint);
ASSERT_TRUE(params.ssl_params());
const SSLSocketParams& ssl_params = *params.ssl_params();
- EXPECT_EQ(ssl_params.host_and_port(), kProxy.host_port_pair());
+ EXPECT_EQ(ssl_params.host_and_port(), kProxy.proxy_server().host_port_pair());
ASSERT_EQ(ssl_params.GetConnectionType(), SSLSocketParams::DIRECT);
const TransportSocketParams& transport_params =
*ssl_params.GetDirectConnectionParams();
EXPECT_THAT(transport_params.destination(),
- testing::VariantWith<HostPortPair>(kProxy.host_port_pair()));
+ testing::VariantWith<HostPortPair>(
+ kProxy.proxy_server().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateSocksProxyConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 91);
- const ProxyServer kProxy(ProxyServer::SCHEME_SOCKS5,
- HostPortPair("proxy.test", 92));
+ const ProxyChain kProxy(ProxyServer::SCHEME_SOCKS5,
+ HostPortPair("proxy.test", 92));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*ssl_config_for_origin=*/nullptr,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -500,18 +508,19 @@ TEST_F(ConnectJobFactoryTest, CreateSocksProxyConnectJob) {
const TransportSocketParams& transport_params = *params.transport_params();
EXPECT_THAT(transport_params.destination(),
- testing::VariantWith<HostPortPair>(kProxy.host_port_pair()));
+ testing::VariantWith<HostPortPair>(
+ kProxy.proxy_server().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateSocksProxyConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 91);
- const ProxyServer kProxy(ProxyServer::SCHEME_SOCKS5,
- HostPortPair("proxy.test", 92));
+ const ProxyChain kProxy(ProxyServer::SCHEME_SOCKS5,
+ HostPortPair("proxy.test", 92));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/false, kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*ssl_config_for_origin=*/nullptr,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -525,7 +534,8 @@ TEST_F(ConnectJobFactoryTest, CreateSocksProxyConnectJobWithoutScheme) {
const TransportSocketParams& transport_params = *params.transport_params();
EXPECT_THAT(transport_params.destination(),
- testing::VariantWith<HostPortPair>(kProxy.host_port_pair()));
+ testing::VariantWith<HostPortPair>(
+ kProxy.proxy_server().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateWebsocketConnectJob) {
@@ -537,10 +547,10 @@ TEST_F(ConnectJobFactoryTest, CreateWebsocketConnectJob) {
&websocket_endpoint_lock_manager;
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
- kEndpoint, ProxyServer::Direct(),
+ kEndpoint, ProxyChain::Direct(),
/*proxy_annotation_tag=*/absl::nullopt,
/*ssl_config_for_origin=*/nullptr,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
@@ -563,10 +573,10 @@ TEST_F(ConnectJobFactoryTest, CreateWebsocketConnectJobWithoutScheme) {
&websocket_endpoint_lock_manager;
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
- /*using_ssl=*/false, kEndpoint, ProxyServer::Direct(),
+ /*using_ssl=*/false, kEndpoint, ProxyChain::Direct(),
/*proxy_annotation_tag=*/absl::nullopt,
/*ssl_config_for_origin=*/nullptr,
- /*ssl_config_for_proxy=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
diff --git a/net/socket/connect_job_unittest.cc b/net/socket/connect_job_unittest.cc
index cead9b45e..53c0950e3 100644
--- a/net/socket/connect_job_unittest.cc
+++ b/net/socket/connect_job_unittest.cc
@@ -94,20 +94,21 @@ class ConnectJobTest : public testing::Test {
ConnectJobTest()
: task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
common_connect_job_params_(
- nullptr /* client_socket_factory */,
- nullptr /* host_resolver */,
- nullptr /* http_auth_cache */,
- nullptr /* http_auth_handler_factory */,
- nullptr /* spdy_session_pool */,
- nullptr /* quic_supported_versions */,
- nullptr /* quic_stream_factory */,
- nullptr /* proxy_delegate */,
- nullptr /* http_user_agent_settings */,
- nullptr /* ssl_client_context */,
- nullptr /* socket_performance_watcher_factory */,
- nullptr /* network_quality_estimator */,
+ /*client_socket_factory=*/nullptr,
+ /*host_resolver=*/nullptr,
+ /*http_auth_cache=*/nullptr,
+ /*http_auth_handler_factory=*/nullptr,
+ /*spdy_session_pool=*/nullptr,
+ /*quic_supported_versions=*/nullptr,
+ /*quic_stream_factory=*/nullptr,
+ /*proxy_delegate=*/nullptr,
+ /*http_user_agent_settings=*/nullptr,
+ /*ssl_client_context=*/nullptr,
+ /*socket_performance_watcher_factory=*/nullptr,
+ /*network_quality_estimator=*/nullptr,
NetLog::Get(),
- nullptr /* websocket_endpoint_lock_manager */) {}
+ /*websocket_endpoint_lock_manager=*/nullptr,
+ /*http_server_properties*/ nullptr) {}
~ConnectJobTest() override = default;
protected:
diff --git a/net/socket/datagram_socket.h b/net/socket/datagram_socket.h
index acb991217..8961f7c47 100644
--- a/net/socket/datagram_socket.h
+++ b/net/socket/datagram_socket.h
@@ -45,6 +45,10 @@ class NET_EXPORT_PRIVATE DatagramSocket {
// return ERR_IO_PENDING.
virtual int SetDoNotFragment() = 0;
+ // Requests that packets received by this socket have the ECN bit set. Returns
+ // a network error code if there was a problem.
+ virtual int SetRecvEcn() = 0;
+
// If |confirm| is true, then the MSG_CONFIRM flag will be passed to
// subsequent writes if it's supported by the platform.
virtual void SetMsgConfirm(bool confirm) = 0;
diff --git a/net/socket/fuzzed_datagram_client_socket.cc b/net/socket/fuzzed_datagram_client_socket.cc
index 924116283..cefc828b4 100644
--- a/net/socket/fuzzed_datagram_client_socket.cc
+++ b/net/socket/fuzzed_datagram_client_socket.cc
@@ -214,6 +214,10 @@ int FuzzedDatagramClientSocket::SetDoNotFragment() {
return OK;
}
+int FuzzedDatagramClientSocket::SetRecvEcn() {
+ return OK;
+}
+
void FuzzedDatagramClientSocket::OnReadComplete(
net::CompletionOnceCallback callback,
int result) {
diff --git a/net/socket/fuzzed_datagram_client_socket.h b/net/socket/fuzzed_datagram_client_socket.h
index 4b3ec1608..162e16e66 100644
--- a/net/socket/fuzzed_datagram_client_socket.h
+++ b/net/socket/fuzzed_datagram_client_socket.h
@@ -72,6 +72,7 @@ class FuzzedDatagramClientSocket : public DatagramClientSocket {
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int SetDoNotFragment() override;
+ int SetRecvEcn() override;
void SetMsgConfirm(bool confirm) override {}
private:
diff --git a/net/socket/mock_client_socket_pool_manager.cc b/net/socket/mock_client_socket_pool_manager.cc
index 05ee41653..236d553e0 100644
--- a/net/socket/mock_client_socket_pool_manager.cc
+++ b/net/socket/mock_client_socket_pool_manager.cc
@@ -15,9 +15,9 @@ MockClientSocketPoolManager::MockClientSocketPoolManager() = default;
MockClientSocketPoolManager::~MockClientSocketPoolManager() = default;
void MockClientSocketPoolManager::SetSocketPool(
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
std::unique_ptr<ClientSocketPool> pool) {
- socket_pools_[proxy_server] = std::move(pool);
+ socket_pools_[proxy_chain] = std::move(pool);
}
void MockClientSocketPoolManager::FlushSocketPoolsWithError(
@@ -32,8 +32,8 @@ void MockClientSocketPoolManager::CloseIdleSockets(
}
ClientSocketPool* MockClientSocketPoolManager::GetSocketPool(
- const ProxyServer& proxy_server) {
- ClientSocketPoolMap::const_iterator it = socket_pools_.find(proxy_server);
+ const ProxyChain& proxy_chain) {
+ ClientSocketPoolMap::const_iterator it = socket_pools_.find(proxy_chain);
if (it != socket_pools_.end())
return it->second.get();
return nullptr;
diff --git a/net/socket/mock_client_socket_pool_manager.h b/net/socket/mock_client_socket_pool_manager.h
index def60f5c7..0b63d7c20 100644
--- a/net/socket/mock_client_socket_pool_manager.h
+++ b/net/socket/mock_client_socket_pool_manager.h
@@ -9,7 +9,7 @@
#include <memory>
#include <string>
-#include "net/base/proxy_server.h"
+#include "net/base/proxy_chain.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/socket/client_socket_pool_manager_impl.h"
@@ -27,20 +27,20 @@ class MockClientSocketPoolManager : public ClientSocketPoolManager {
~MockClientSocketPoolManager() override;
- // Sets socket pool that gets used for the specified ProxyServer.
- void SetSocketPool(const ProxyServer& proxy_server,
+ // Sets socket pool that gets used for the specified ProxyChain.
+ void SetSocketPool(const ProxyChain& proxy_chain,
std::unique_ptr<ClientSocketPool> pool);
// ClientSocketPoolManager methods:
void FlushSocketPoolsWithError(int error,
const char* net_log_reason_utf8) override;
void CloseIdleSockets(const char* net_log_reason_utf8) override;
- ClientSocketPool* GetSocketPool(const ProxyServer& proxy_server) override;
+ ClientSocketPool* GetSocketPool(const ProxyChain& proxy_chain) override;
base::Value SocketPoolInfoToValue() const override;
private:
using ClientSocketPoolMap =
- std::map<ProxyServer, std::unique_ptr<ClientSocketPool>>;
+ std::map<ProxyChain, std::unique_ptr<ClientSocketPool>>;
ClientSocketPoolMap socket_pools_;
};
diff --git a/net/socket/socket_bio_adapter_unittest.cc b/net/socket/socket_bio_adapter_unittest.cc
index bc2169b2d..7fabbe6cc 100644
--- a/net/socket/socket_bio_adapter_unittest.cc
+++ b/net/socket/socket_bio_adapter_unittest.cc
@@ -13,6 +13,7 @@
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
+#include "build/build_config.h"
#include "crypto/openssl_util.h"
#include "net/base/address_list.h"
#include "net/base/completion_once_callback.h"
@@ -283,8 +284,14 @@ TEST_P(SocketBIOAdapterTest, ReadEOFSync) {
ExpectReadError(adapter->bio(), ERR_CONNECTION_CLOSED, tracer);
}
+#if BUILDFLAG(IS_ANDROID)
// Test that asynchronous EOF is mapped to ERR_CONNECTION_CLOSED.
-TEST_P(SocketBIOAdapterTest, ReadEOFAsync) {
+// TODO(crbug.com/1480024): Test is flaky on Android.
+#define MAYBE_ReadEOFAsync DISABLED_ReadEOFAsync
+#else
+#define MAYBE_ReadEOFAsync ReadEOFAsync
+#endif
+TEST_P(SocketBIOAdapterTest, MAYBE_ReadEOFAsync) {
crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
MockRead reads[] = {
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index acaf5868c..821166ed9 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -1577,6 +1577,10 @@ int MockUDPClientSocket::SetDoNotFragment() {
return OK;
}
+int MockUDPClientSocket::SetRecvEcn() {
+ return OK;
+}
+
void MockUDPClientSocket::Close() {
connected_ = false;
}
@@ -1921,7 +1925,7 @@ MockTransportClientSocketPool::MockTransportClientSocketPool(
max_sockets,
max_sockets_per_group,
base::Seconds(10) /* unused_idle_socket_timeout */,
- ProxyServer::Direct(),
+ ProxyChain::Direct(),
false /* is_for_websockets */,
common_connect_job_params),
client_socket_factory_(common_connect_job_params->client_socket_factory) {
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 5119e6619..e3edda34b 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -976,6 +976,7 @@ class MockUDPClientSocket : public DatagramClientSocket, public AsyncSocket {
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int SetDoNotFragment() override;
+ int SetRecvEcn() override;
// DatagramSocket implementation.
void Close() override;
diff --git a/net/socket/socks_connect_job_unittest.cc b/net/socket/socks_connect_job_unittest.cc
index 5fb0a2d40..45322cd78 100644
--- a/net/socket/socks_connect_job_unittest.cc
+++ b/net/socket/socks_connect_job_unittest.cc
@@ -53,18 +53,19 @@ class SOCKSConnectJobTest : public testing::Test, public WithTaskEnvironment {
common_connect_job_params_(
&client_socket_factory_,
&host_resolver_,
- nullptr /* http_auth_cache */,
- nullptr /* http_auth_handler_factory */,
- nullptr /* spdy_session_pool */,
- nullptr /* quic_supported_versions */,
- nullptr /* quic_stream_factory */,
- nullptr /* proxy_delegate */,
- nullptr /* http_user_agent_settings */,
- nullptr /* ssl_client_context */,
- nullptr /* socket_performance_watcher_factory */,
- nullptr /* network_quality_estimator */,
+ /*http_auth_cache=*/nullptr,
+ /*http_auth_handler_factory=*/nullptr,
+ /*spdy_session_pool=*/nullptr,
+ /*quic_supported_versions=*/nullptr,
+ /*quic_stream_factory=*/nullptr,
+ /*proxy_delegate=*/nullptr,
+ /*http_user_agent_settings=*/nullptr,
+ /*ssl_client_context=*/nullptr,
+ /*socket_performance_watcher_factory=*/nullptr,
+ /*network_quality_estimator=*/nullptr,
NetLog::Get(),
- nullptr /* websocket_endpoint_lock_manager */) {}
+ /*websocket_endpoint_lock_manager=*/nullptr,
+ /*http_server_properties=*/nullptr) {}
~SOCKSConnectJobTest() override = default;
diff --git a/net/socket/ssl_client_socket.cc b/net/socket/ssl_client_socket.cc
index 8290b9592..d3e12a59b 100644
--- a/net/socket/ssl_client_socket.cc
+++ b/net/socket/ssl_client_socket.cc
@@ -9,6 +9,10 @@
#include "base/containers/flat_tree.h"
#include "base/logging.h"
#include "base/observer_list.h"
+#include "base/values.h"
+#include "net/cert/x509_certificate_net_log_param.h"
+#include "net/log/net_log.h"
+#include "net/log/net_log_event_type.h"
#include "net/socket/ssl_client_socket_impl.h"
#include "net/socket/stream_socket.h"
#include "net/ssl/ssl_client_session_cache.h"
@@ -16,6 +20,33 @@
namespace net {
+namespace {
+
+// Returns true if |first_cert| and |second_cert| represent the same certificate
+// (with the same chain), or if they're both NULL.
+bool AreCertificatesEqual(const scoped_refptr<X509Certificate>& first_cert,
+ const scoped_refptr<X509Certificate>& second_cert) {
+ return (!first_cert && !second_cert) ||
+ (first_cert && second_cert &&
+ first_cert->EqualsIncludingChain(second_cert.get()));
+}
+
+// Returns a base::Value::Dict value NetLog parameter with the expected format
+// for events of type CLEAR_CACHED_CLIENT_CERT.
+base::Value::Dict NetLogClearCachedClientCertParams(
+ const net::HostPortPair& host,
+ const scoped_refptr<net::X509Certificate>& cert,
+ bool is_cleared) {
+ base::Value::Dict dict;
+ dict.Set("host", host.ToString());
+ dict.Set("certificates", cert ? net::NetLogX509CertificateList(cert.get())
+ : base::Value(base::Value::List()));
+ dict.Set("is_cleared", is_cleared);
+ return dict;
+}
+
+} // namespace
+
SSLClientSocket::SSLClientSocket() = default;
// static
@@ -157,6 +188,38 @@ void SSLClientContext::OnClientCertStoreChanged() {
NotifySSLConfigForServersChanged(servers);
}
+void SSLClientContext::ClearClientCertificateIfNeeded(
+ const net::HostPortPair& host,
+ const scoped_refptr<net::X509Certificate>& certificate) {
+ scoped_refptr<X509Certificate> cached_certificate;
+ scoped_refptr<SSLPrivateKey> cached_private_key;
+ if (!ssl_client_auth_cache_.Lookup(host, &cached_certificate,
+ &cached_private_key) ||
+ AreCertificatesEqual(cached_certificate, certificate)) {
+ // No cached client certificate preference for this host.
+ net::NetLog::Get()->AddGlobalEntry(
+ NetLogEventType::CLEAR_CACHED_CLIENT_CERT, [&]() {
+ return NetLogClearCachedClientCertParams(host, certificate,
+ /*is_cleared=*/false);
+ });
+ return;
+ }
+
+ net::NetLog::Get()->AddGlobalEntry(
+ NetLogEventType::CLEAR_CACHED_CLIENT_CERT, [&]() {
+ return NetLogClearCachedClientCertParams(host, certificate,
+ /*is_cleared=*/true);
+ });
+
+ ssl_client_auth_cache_.Remove(host);
+
+ if (ssl_client_session_cache_) {
+ ssl_client_session_cache_->FlushForServers({host});
+ }
+
+ NotifySSLConfigForServersChanged({host});
+}
+
void SSLClientContext::NotifySSLConfigChanged(SSLConfigChangeType change_type) {
for (Observer& observer : observers_) {
observer.OnSSLConfigChanged(change_type);
diff --git a/net/socket/ssl_client_socket.h b/net/socket/ssl_client_socket.h
index f34320c57..637c32b52 100644
--- a/net/socket/ssl_client_socket.h
+++ b/net/socket/ssl_client_socket.h
@@ -181,6 +181,16 @@ class NET_EXPORT SSLClientContext : public SSLConfigService::Observer,
// observers.
bool ClearClientCertificate(const HostPortPair& server);
+ // Clears a client certificate preference for |host| set by
+ // SetClientCertificate() if |certificate| doesn't match the cached
+ // certificate.
+ //
+ // Note this method will synchronously call OnSSLConfigForServersChanged() on
+ // observers.
+ void ClearClientCertificateIfNeeded(
+ const net::HostPortPair& host,
+ const scoped_refptr<net::X509Certificate>& certificate);
+
base::flat_set<HostPortPair> GetClientCertificateCachedServersForTesting()
const {
return ssl_client_auth_cache_.GetCachedServers();
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index 9d7134c1c..19db6d77a 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -21,7 +21,6 @@
#include "base/location.h"
#include "base/memory/singleton.h"
#include "base/metrics/field_trial.h"
-#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
@@ -31,6 +30,7 @@
#include "base/task/sequenced_task_runner.h"
#include "base/values.h"
#include "build/build_config.h"
+#include "components/miracle_parameter/common/public/miracle_parameter.h"
#include "crypto/ec_private_key.h"
#include "crypto/openssl_util.h"
#include "net/base/features.h"
@@ -81,8 +81,15 @@ const int kSSLClientSocketNoPendingResult = 1;
// overlap with any value of the net::Error range, including net::OK).
const int kCertVerifyPending = 1;
+BASE_FEATURE(kDefaultOpenSSLBufferSizeFeature,
+ "DefaultOpenSSLBufferSizeFeature",
+ base::FEATURE_ENABLED_BY_DEFAULT);
+
// Default size of the internal BoringSSL buffers.
-const int kDefaultOpenSSLBufferSize = 17 * 1024;
+MIRACLE_PARAMETER_FOR_INT(GetDefaultOpenSSLBufferSize,
+ kDefaultOpenSSLBufferSizeFeature,
+ "DefaultOpenSSLBufferSize",
+ 17 * 1024)
base::Value::Dict NetLogPrivateKeyOperationParams(uint16_t algorithm,
SSLPrivateKey* key) {
@@ -771,9 +778,9 @@ int SSLClientSocketImpl::Init() {
SSL_set_session(ssl_.get(), session.get());
}
+ const int kBufferSize = GetDefaultOpenSSLBufferSize();
transport_adapter_ = std::make_unique<SocketBIOAdapter>(
- stream_socket_.get(), kDefaultOpenSSLBufferSize,
- kDefaultOpenSSLBufferSize, this);
+ stream_socket_.get(), kBufferSize, kBufferSize, this);
BIO* transport_bio = transport_adapter_->bio();
BIO_up_ref(transport_bio); // SSL_set0_rbio takes ownership.
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc
index 6c30471f2..b12a14594 100644
--- a/net/socket/ssl_client_socket_unittest.cc
+++ b/net/socket/ssl_client_socket_unittest.cc
@@ -2620,7 +2620,7 @@ TEST_P(SSLClientSocketVersionTest, VerifyReturnChainProperlyOrdered) {
scoped_refptr<X509Certificate> root_cert = ImportCertFromFile(
GetTestCertsDirectory(), "redundant-validated-chain-root.pem");
ASSERT_NE(static_cast<X509Certificate*>(nullptr), root_cert.get());
- ScopedTestRoot scoped_root(root_cert.get());
+ ScopedTestRoot scoped_root(root_cert);
// Set up a test server with CERT_CHAIN_WRONG_ROOT.
ASSERT_TRUE(StartEmbeddedTestServer(EmbeddedTestServer::CERT_CHAIN_WRONG_ROOT,
@@ -3802,6 +3802,283 @@ TEST_F(SSLClientSocketTest, ClearSessionCacheOnClientCertDatabaseChange) {
context_->RemoveObserver(&observer);
}
+TEST_F(SSLClientSocketTest, DontClearEmptyClientCertCache) {
+ SSLServerConfig server_config;
+ // TLS 1.3 reports client certificate errors after the handshake, so test at
+ // TLS 1.2 for simplicity.
+ server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
+ server_config.client_cert_type = SSLServerConfig::REQUIRE_CLIENT_CERT;
+ ASSERT_TRUE(
+ StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
+
+ testing::StrictMock<MockSSLClientContextObserver> observer;
+ context_->AddObserver(&observer);
+
+ // No cached client certs and no open session.
+ EXPECT_TRUE(context_->GetClientCertificateCachedServersForTesting().empty());
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 0U);
+
+ base::FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<net::X509Certificate> certificate1 =
+ ImportCertFromFile(certs_dir, "client_1.pem");
+ context_->ClearClientCertificateIfNeeded(host_port_pair(), certificate1);
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_TRUE(context_->GetClientCertificateCachedServersForTesting().empty());
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 0U);
+
+ context_->RemoveObserver(&observer);
+
+ auto entries = log_observer_.GetEntriesWithType(
+ NetLogEventType::CLEAR_CACHED_CLIENT_CERT);
+ ASSERT_EQ(1u, entries.size());
+ EXPECT_EQ(GetStringValueFromParams(entries[0], "host"),
+ host_port_pair().ToString());
+ EXPECT_FALSE(GetBooleanValueFromParams(entries[0], "is_cleared"));
+}
+
+TEST_F(SSLClientSocketTest, DontClearMatchingClientCertificates) {
+ SSLServerConfig server_config;
+ // TLS 1.3 reports client certificate errors after the handshake, so test at
+ // TLS 1.2 for simplicity.
+ server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
+ server_config.client_cert_type = SSLServerConfig::REQUIRE_CLIENT_CERT;
+ ASSERT_TRUE(
+ StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
+
+ testing::StrictMock<MockSSLClientContextObserver> observer;
+ EXPECT_CALL(observer, OnSSLConfigForServersChanged(
+ base::flat_set<HostPortPair>({host_port_pair()})));
+ context_->AddObserver(&observer);
+
+ base::FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<net::X509Certificate> certificate1 =
+ ImportCertFromFile(certs_dir, "client_1.pem");
+ scoped_refptr<net::SSLPrivateKey> private_key1 =
+ key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key"));
+
+ context_->SetClientCertificate(host_port_pair(), certificate1, private_key1);
+ EXPECT_EQ(context_->GetClientCertificateCachedServersForTesting().size(), 1U);
+
+ // Connect to `host_port_pair()` using the client cert.
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(sock_->IsConnected());
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 1U);
+
+ context_->ClearClientCertificateIfNeeded(host_port_pair(), certificate1);
+ base::RunLoop().RunUntilIdle();
+
+ // Cached certificate and session should not have been cleared since the
+ // certificates were identical.
+ EXPECT_EQ(context_->GetClientCertificateCachedServersForTesting().size(), 1U);
+ EXPECT_TRUE(context_->GetClientCertificateCachedServersForTesting().contains(
+ host_port_pair()));
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 1U);
+
+ context_->RemoveObserver(&observer);
+
+ auto entries = log_observer_.GetEntriesWithType(
+ NetLogEventType::CLEAR_CACHED_CLIENT_CERT);
+ ASSERT_EQ(1u, entries.size());
+ EXPECT_EQ(GetStringValueFromParams(entries[0], "host"),
+ host_port_pair().ToString());
+ EXPECT_FALSE(GetBooleanValueFromParams(entries[0], "is_cleared"));
+}
+
+TEST_F(SSLClientSocketTest, ClearMismatchingClientCertificates) {
+ SSLServerConfig server_config;
+ // TLS 1.3 reports client certificate errors after the handshake, so test at
+ // TLS 1.2 for simplicity.
+ server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
+ server_config.client_cert_type = SSLServerConfig::REQUIRE_CLIENT_CERT;
+ ASSERT_TRUE(
+ StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
+
+ testing::StrictMock<MockSSLClientContextObserver> observer;
+ EXPECT_CALL(observer, OnSSLConfigForServersChanged(
+ base::flat_set<HostPortPair>({host_port_pair()})))
+ .Times(2);
+ context_->AddObserver(&observer);
+
+ base::FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<net::X509Certificate> certificate1 =
+ ImportCertFromFile(certs_dir, "client_1.pem");
+ scoped_refptr<net::SSLPrivateKey> private_key1 =
+ key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key"));
+
+ context_->SetClientCertificate(host_port_pair(), certificate1, private_key1);
+ EXPECT_EQ(context_->GetClientCertificateCachedServersForTesting().size(), 1U);
+
+ // Connect to `host_port_pair()` using the client cert.
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(sock_->IsConnected());
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 1U);
+
+ scoped_refptr<net::X509Certificate> certificate2 =
+ ImportCertFromFile(certs_dir, "client_2.pem");
+ context_->ClearClientCertificateIfNeeded(host_port_pair(), certificate2);
+ base::RunLoop().RunUntilIdle();
+
+ // Cached certificate and session should have been cleared since the
+ // certificates were different.
+ EXPECT_TRUE(context_->GetClientCertificateCachedServersForTesting().empty());
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 0U);
+
+ context_->RemoveObserver(&observer);
+
+ auto entries = log_observer_.GetEntriesWithType(
+ NetLogEventType::CLEAR_CACHED_CLIENT_CERT);
+ ASSERT_EQ(1u, entries.size());
+ EXPECT_EQ(GetStringValueFromParams(entries[0], "host"),
+ host_port_pair().ToString());
+ EXPECT_TRUE(GetBooleanValueFromParams(entries[0], "is_cleared"));
+}
+
+TEST_F(SSLClientSocketTest,
+ ClearMismatchingClientCertificatesWithNullParameter) {
+ SSLServerConfig server_config;
+ // TLS 1.3 reports client certificate errors after the handshake, so test at
+ // TLS 1.2 for simplicity.
+ server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
+ server_config.client_cert_type = SSLServerConfig::REQUIRE_CLIENT_CERT;
+ ASSERT_TRUE(
+ StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
+
+ testing::StrictMock<MockSSLClientContextObserver> observer;
+ EXPECT_CALL(observer, OnSSLConfigForServersChanged(
+ base::flat_set<HostPortPair>({host_port_pair()})))
+ .Times(2);
+ context_->AddObserver(&observer);
+
+ base::FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<net::X509Certificate> certificate1 =
+ ImportCertFromFile(certs_dir, "client_1.pem");
+ scoped_refptr<net::SSLPrivateKey> private_key1 =
+ key_util::LoadPrivateKeyOpenSSL(certs_dir.AppendASCII("client_1.key"));
+
+ context_->SetClientCertificate(host_port_pair(), certificate1, private_key1);
+ EXPECT_EQ(context_->GetClientCertificateCachedServersForTesting().size(), 1U);
+
+ // Connect to `host_port_pair()` using the client cert.
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(sock_->IsConnected());
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 1U);
+
+ context_->ClearClientCertificateIfNeeded(host_port_pair(), nullptr);
+ base::RunLoop().RunUntilIdle();
+
+ // Cached certificate and session should have been cleared since the
+ // certificates were different.
+ EXPECT_TRUE(context_->GetClientCertificateCachedServersForTesting().empty());
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 0U);
+
+ context_->RemoveObserver(&observer);
+
+ auto entries = log_observer_.GetEntriesWithType(
+ NetLogEventType::CLEAR_CACHED_CLIENT_CERT);
+ ASSERT_EQ(1u, entries.size());
+ EXPECT_EQ(GetStringValueFromParams(entries[0], "host"),
+ host_port_pair().ToString());
+ EXPECT_TRUE(GetBooleanValueFromParams(entries[0], "is_cleared"));
+}
+
+TEST_F(SSLClientSocketTest,
+ ClearMismatchingClientCertificatesWithNullCachedCert) {
+ SSLServerConfig server_config;
+ // TLS 1.3 reports client certificate errors after the handshake, so test at
+ // TLS 1.2 for simplicity.
+ server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
+ server_config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
+ ASSERT_TRUE(
+ StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
+
+ testing::StrictMock<MockSSLClientContextObserver> observer;
+ EXPECT_CALL(observer, OnSSLConfigForServersChanged(
+ base::flat_set<HostPortPair>({host_port_pair()})))
+ .Times(2);
+ context_->AddObserver(&observer);
+
+ context_->SetClientCertificate(host_port_pair(), nullptr, nullptr);
+ EXPECT_EQ(context_->GetClientCertificateCachedServersForTesting().size(), 1U);
+
+ // Connect to `host_port_pair()` using the client cert.
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(sock_->IsConnected());
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 1U);
+
+ base::FilePath certs_dir = GetTestCertsDirectory();
+ scoped_refptr<net::X509Certificate> certificate2 =
+ ImportCertFromFile(certs_dir, "client_2.pem");
+ context_->ClearClientCertificateIfNeeded(host_port_pair(), certificate2);
+ base::RunLoop().RunUntilIdle();
+
+ // Cached certificate and session should have been cleared since the
+ // certificates were different.
+ EXPECT_TRUE(context_->GetClientCertificateCachedServersForTesting().empty());
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 0U);
+
+ context_->RemoveObserver(&observer);
+
+ auto entries = log_observer_.GetEntriesWithType(
+ NetLogEventType::CLEAR_CACHED_CLIENT_CERT);
+ ASSERT_EQ(1u, entries.size());
+ EXPECT_EQ(GetStringValueFromParams(entries[0], "host"),
+ host_port_pair().ToString());
+ EXPECT_TRUE(GetBooleanValueFromParams(entries[0], "is_cleared"));
+}
+
+TEST_F(SSLClientSocketTest, DontClearClientCertificatesWithNullCerts) {
+ SSLServerConfig server_config;
+ // TLS 1.3 reports client certificate errors after the handshake, so test at
+ // TLS 1.2 for simplicity.
+ server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2;
+ server_config.client_cert_type = SSLServerConfig::OPTIONAL_CLIENT_CERT;
+ ASSERT_TRUE(
+ StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config));
+
+ testing::StrictMock<MockSSLClientContextObserver> observer;
+ EXPECT_CALL(observer, OnSSLConfigForServersChanged(
+ base::flat_set<HostPortPair>({host_port_pair()})));
+ context_->AddObserver(&observer);
+
+ context_->SetClientCertificate(host_port_pair(), nullptr, nullptr);
+ EXPECT_EQ(context_->GetClientCertificateCachedServersForTesting().size(), 1U);
+
+ // Connect to `host_port_pair()` using the client cert.
+ int rv;
+ ASSERT_TRUE(CreateAndConnectSSLClientSocket(SSLConfig(), &rv));
+ EXPECT_THAT(rv, IsOk());
+ EXPECT_TRUE(sock_->IsConnected());
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 1U);
+
+ context_->ClearClientCertificateIfNeeded(host_port_pair(), nullptr);
+ base::RunLoop().RunUntilIdle();
+
+ // Cached certificate and session should not have been cleared since the
+ // certificates were identical.
+ EXPECT_EQ(context_->GetClientCertificateCachedServersForTesting().size(), 1U);
+ EXPECT_TRUE(context_->GetClientCertificateCachedServersForTesting().contains(
+ host_port_pair()));
+ EXPECT_EQ(context_->ssl_client_session_cache()->size(), 1U);
+
+ context_->RemoveObserver(&observer);
+
+ auto entries = log_observer_.GetEntriesWithType(
+ NetLogEventType::CLEAR_CACHED_CLIENT_CERT);
+ ASSERT_EQ(1u, entries.size());
+ EXPECT_EQ(GetStringValueFromParams(entries[0], "host"),
+ host_port_pair().ToString());
+ EXPECT_FALSE(GetBooleanValueFromParams(entries[0], "is_cleared"));
+}
+
TEST_F(SSLClientSocketTest, DontClearSessionCacheOnServerCertDatabaseChange) {
SSLServerConfig server_config;
// TLS 1.3 reports client certificate errors after the handshake, so test at
diff --git a/net/socket/ssl_connect_job.cc b/net/socket/ssl_connect_job.cc
index d0d9eddfe..cceb033ba 100644
--- a/net/socket/ssl_connect_job.cc
+++ b/net/socket/ssl_connect_job.cc
@@ -333,8 +333,6 @@ int SSLConnectJob::DoTunnelConnect() {
DCHECK(!TimerIsRunning());
next_state_ = STATE_TUNNEL_CONNECT_COMPLETE;
- scoped_refptr<HttpProxySocketParams> http_proxy_params =
- params_->GetHttpProxyConnectionParams();
nested_connect_job_ = std::make_unique<HttpProxyConnectJob>(
priority(), socket_tag(), common_connect_job_params(),
params_->GetHttpProxyConnectionParams(), this, &net_log());
diff --git a/net/socket/ssl_connect_job_unittest.cc b/net/socket/ssl_connect_job_unittest.cc
index 886943b12..fa9db38c1 100644
--- a/net/socket/ssl_connect_job_unittest.cc
+++ b/net/socket/ssl_connect_job_unittest.cc
@@ -17,9 +17,13 @@
#include "base/time/time.h"
#include "net/base/auth.h"
#include "net/base/features.h"
+#include "net/base/host_port_pair.h"
#include "net/base/load_timing_info.h"
#include "net/base/net_errors.h"
+#include "net/base/network_anonymization_key.h"
#include "net/base/network_isolation_key.h"
+#include "net/base/proxy_chain.h"
+#include "net/base/proxy_server.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
@@ -91,6 +95,15 @@ void CheckConnectTimesExceptDnsSet(
EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
}
+const url::SchemeHostPort kHostHttps{url::kHttpsScheme, "host", 443};
+const HostPortPair kHostHttp{"host", 80};
+const ProxyServer kSocksProxyServer{ProxyServer::SCHEME_SOCKS5,
+ HostPortPair("sockshost", 443)};
+const ProxyServer kHttpProxyServer{ProxyServer::SCHEME_HTTP,
+ HostPortPair("proxy", 443)};
+
+const ProxyChain kHttpProxyChain{kHttpProxyServer};
+
class SSLConnectJobTest : public WithTaskEnvironment, public testing::Test {
public:
SSLConnectJobTest()
@@ -100,56 +113,71 @@ class SSLConnectJobTest : public WithTaskEnvironment, public testing::Test {
ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()),
http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
session_(CreateNetworkSession()),
- direct_transport_socket_params_(
- base::MakeRefCounted<TransportSocketParams>(
- url::SchemeHostPort(url::kHttpsScheme, "host", 443),
- NetworkAnonymizationKey(),
- SecureDnsPolicy::kAllow,
- OnHostResolutionCallback(),
- /*supported_alpns=*/
- base::flat_set<std::string>({"h2", "http/1.1"}))),
- proxy_transport_socket_params_(
- base::MakeRefCounted<TransportSocketParams>(
- HostPortPair("proxy", 443),
- NetworkAnonymizationKey(),
- SecureDnsPolicy::kAllow,
- OnHostResolutionCallback(),
- /*supported_alpns=*/base::flat_set<std::string>({}))),
- socks_socket_params_(base::MakeRefCounted<SOCKSSocketParams>(
- proxy_transport_socket_params_,
- true,
- HostPortPair("sockshost", 443),
- NetworkAnonymizationKey(),
- TRAFFIC_ANNOTATION_FOR_TESTS)),
- http_proxy_socket_params_(base::MakeRefCounted<HttpProxySocketParams>(
- proxy_transport_socket_params_,
- nullptr /* ssl_params */,
- false /* is_quic */,
- HostPortPair("host", 80),
- /*tunnel=*/true,
- TRAFFIC_ANNOTATION_FOR_TESTS,
- NetworkAnonymizationKey())),
common_connect_job_params_(session_->CreateCommonConnectJobParams()) {}
~SSLConnectJobTest() override = default;
+ scoped_refptr<TransportSocketParams> CreateDirectTransportSocketParams(
+ SecureDnsPolicy secure_dns_policy) const {
+ return base::MakeRefCounted<TransportSocketParams>(
+ kHostHttps, NetworkAnonymizationKey(), secure_dns_policy,
+ OnHostResolutionCallback(),
+ /*supported_alpns=*/base::flat_set<std::string>({"h2", "http/1.1"}));
+ }
+
+ scoped_refptr<TransportSocketParams> CreateProxyTransportSocketParams(
+ SecureDnsPolicy secure_dns_policy) const {
+ return base::MakeRefCounted<TransportSocketParams>(
+ kHttpProxyServer.host_port_pair(), NetworkAnonymizationKey(),
+ secure_dns_policy, OnHostResolutionCallback(),
+ /*supported_alpns=*/base::flat_set<std::string>({}));
+ }
+
+ scoped_refptr<SOCKSSocketParams> CreateSOCKSSocketParams(
+ SecureDnsPolicy secure_dns_policy) {
+ return base::MakeRefCounted<SOCKSSocketParams>(
+ CreateProxyTransportSocketParams(secure_dns_policy),
+ kSocksProxyServer.scheme() == ProxyServer::SCHEME_SOCKS5,
+ kSocksProxyServer.host_port_pair(), NetworkAnonymizationKey(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ }
+
+ scoped_refptr<HttpProxySocketParams> CreateHttpProxySocketParams(
+ SecureDnsPolicy secure_dns_policy) {
+ return base::MakeRefCounted<HttpProxySocketParams>(
+ CreateProxyTransportSocketParams(secure_dns_policy),
+ /*ssl_params=*/nullptr, kHostHttp, kHttpProxyChain,
+ /*proxy_server_index=*/0,
+ /*tunnel=*/true, TRAFFIC_ANNOTATION_FOR_TESTS,
+ NetworkAnonymizationKey(), secure_dns_policy);
+ }
+
std::unique_ptr<ConnectJob> CreateConnectJob(
TestConnectJobDelegate* test_delegate,
ProxyServer::Scheme proxy_scheme = ProxyServer::SCHEME_DIRECT,
- RequestPriority priority = DEFAULT_PRIORITY) {
+ RequestPriority priority = DEFAULT_PRIORITY,
+ SecureDnsPolicy secure_dns_policy = SecureDnsPolicy::kAllow) {
return std::make_unique<SSLConnectJob>(
priority, SocketTag(), &common_connect_job_params_,
- SSLParams(proxy_scheme), test_delegate, nullptr /* net_log */);
+ CreateSSLSocketParams(proxy_scheme, secure_dns_policy), test_delegate,
+ /*net_log=*/nullptr);
}
- scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy) {
+ scoped_refptr<SSLSocketParams> CreateSSLSocketParams(
+ ProxyServer::Scheme proxy_scheme,
+ SecureDnsPolicy secure_dns_policy) {
return base::MakeRefCounted<SSLSocketParams>(
- proxy == ProxyServer::SCHEME_DIRECT ? direct_transport_socket_params_
- : nullptr,
- proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : nullptr,
- proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : nullptr,
- HostPortPair("host", 443), SSLConfig(), PRIVACY_MODE_DISABLED,
- NetworkAnonymizationKey());
+ proxy_scheme == ProxyServer::SCHEME_DIRECT
+ ? CreateDirectTransportSocketParams(secure_dns_policy)
+ : nullptr,
+ proxy_scheme == ProxyServer::SCHEME_SOCKS5
+ ? CreateSOCKSSocketParams(secure_dns_policy)
+ : nullptr,
+ proxy_scheme == ProxyServer::SCHEME_HTTP
+ ? CreateHttpProxySocketParams(secure_dns_policy)
+ : nullptr,
+ HostPortPair::FromSchemeHostPort(kHostHttps), SSLConfig(),
+ PRIVACY_MODE_DISABLED, NetworkAnonymizationKey());
}
void AddAuthToCache() {
@@ -192,12 +220,6 @@ class SSLConnectJobTest : public WithTaskEnvironment, public testing::Test {
QuicContext quic_context_;
const std::unique_ptr<HttpNetworkSession> session_;
- scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
-
- scoped_refptr<TransportSocketParams> proxy_transport_socket_params_;
- scoped_refptr<SOCKSSocketParams> socks_socket_params_;
- scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
-
const CommonConnectJobParams common_connect_job_params_;
};
@@ -444,18 +466,9 @@ TEST_F(SSLConnectJobTest, SecureDnsPolicy) {
for (auto secure_dns_policy :
{SecureDnsPolicy::kAllow, SecureDnsPolicy::kDisable}) {
TestConnectJobDelegate test_delegate;
- direct_transport_socket_params_ =
- base::MakeRefCounted<TransportSocketParams>(
- url::SchemeHostPort(url::kHttpsScheme, "host", 443),
- NetworkAnonymizationKey(), secure_dns_policy,
- OnHostResolutionCallback(),
- /*supported_alpns=*/base::flat_set<std::string>{"h2", "http/1.1"});
- auto common_connect_job_params = session_->CreateCommonConnectJobParams();
std::unique_ptr<ConnectJob> ssl_connect_job =
- std::make_unique<SSLConnectJob>(DEFAULT_PRIORITY, SocketTag(),
- &common_connect_job_params,
- SSLParams(ProxyServer::SCHEME_DIRECT),
- &test_delegate, nullptr /* net_log */);
+ CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT,
+ DEFAULT_PRIORITY, secure_dns_policy);
EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
EXPECT_EQ(secure_dns_policy, host_resolver_.last_secure_dns_policy());
@@ -662,7 +675,7 @@ TEST_F(SSLConnectJobTest, LegacyCryptoFallbackHistograms) {
socket_factory_.AddSocketDataProvider(&data2);
socket_factory_.AddSSLSocketDataProvider(&ssl2);
ssl2.ssl_info = ssl_info;
- ssl2.expected_disable_sha1_server_signatures = false;
+ ssl2.expected_disable_sha1_server_signatures = true;
} else {
ssl.ssl_info = ssl_info;
}
@@ -1618,7 +1631,7 @@ TEST_F(SSLConnectJobTest, ECHRecoveryThenLegacyCrypto) {
// connection enables legacy crypto and succeeds.
SSLSocketDataProvider ssl4(ASYNC, OK);
ssl4.expected_ech_config_list = ech_config_list3;
- ssl4.expected_disable_sha1_server_signatures = false;
+ ssl4.expected_disable_sha1_server_signatures = true;
socket_factory_.AddSSLSocketDataProvider(&ssl4);
// The connection should ultimately succeed.
@@ -1686,7 +1699,7 @@ TEST_F(SSLConnectJobTest, LegacyCryptoThenECHRecovery) {
// The handshake enables legacy crypto. Now ECH fails with retry configs.
SSLSocketDataProvider ssl4(ASYNC, ERR_ECH_NOT_NEGOTIATED);
ssl4.expected_ech_config_list = ech_config_list2;
- ssl4.expected_disable_sha1_server_signatures = false;
+ ssl4.expected_disable_sha1_server_signatures = true;
ssl4.ech_retry_configs = ech_config_list3;
socket_factory_.AddSSLSocketDataProvider(&ssl4);
// The fourth connection attempt should still skip `endpoint1` and retry with
@@ -1699,7 +1712,7 @@ TEST_F(SSLConnectJobTest, LegacyCryptoThenECHRecovery) {
// cryptography.
SSLSocketDataProvider ssl5(ASYNC, OK);
ssl5.expected_ech_config_list = ech_config_list3;
- ssl5.expected_disable_sha1_server_signatures = false;
+ ssl5.expected_disable_sha1_server_signatures = true;
socket_factory_.AddSSLSocketDataProvider(&ssl5);
// The connection should ultimately succeed.
diff --git a/net/socket/tcp_client_socket.h b/net/socket/tcp_client_socket.h
index 200246171..2f61b410d 100644
--- a/net/socket/tcp_client_socket.h
+++ b/net/socket/tcp_client_socket.h
@@ -70,7 +70,7 @@ class NET_EXPORT TCPClientSocket : public TransportClientSocket,
const IPEndPoint& peer_address);
// Adopts an unconnected TCPSocket. TCPSocket may be bound or unbound. This
- // function is used by TCPClientSocketBrokered.
+ // function is used by BrokeredTcpClientSocket.
TCPClientSocket(std::unique_ptr<TCPSocket> unconnected_socket,
const AddressList& addresses,
std::unique_ptr<IPEndPoint> bound_address,
diff --git a/net/socket/transport_client_socket_pool.cc b/net/socket/transport_client_socket_pool.cc
index 8587f4b9d..6a5206298 100644
--- a/net/socket/transport_client_socket_pool.cc
+++ b/net/socket/transport_client_socket_pool.cc
@@ -25,6 +25,7 @@
#include "base/values.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
+#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
@@ -136,7 +137,7 @@ TransportClientSocketPool::TransportClientSocketPool(
int max_sockets,
int max_sockets_per_group,
base::TimeDelta unused_idle_socket_timeout,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
bool is_for_websockets,
const CommonConnectJobParams* common_connect_job_params,
bool cleanup_on_ip_address_change)
@@ -144,13 +145,13 @@ TransportClientSocketPool::TransportClientSocketPool(
max_sockets_per_group,
unused_idle_socket_timeout,
ClientSocketPool::used_idle_socket_timeout(),
- proxy_server,
+ proxy_chain,
is_for_websockets,
common_connect_job_params,
cleanup_on_ip_address_change,
std::make_unique<ConnectJobFactory>(),
common_connect_job_params->ssl_client_context,
- true /* connect_backup_jobs_enabled */) {}
+ /*connect_backup_jobs_enabled=*/true) {}
TransportClientSocketPool::~TransportClientSocketPool() {
// Clean up any idle sockets and pending connect jobs. Assert that we have no
@@ -176,7 +177,7 @@ TransportClientSocketPool::CreateForTesting(
int max_sockets_per_group,
base::TimeDelta unused_idle_socket_timeout,
base::TimeDelta used_idle_socket_timeout,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
bool is_for_websockets,
const CommonConnectJobParams* common_connect_job_params,
std::unique_ptr<ConnectJobFactory> connect_job_factory,
@@ -185,8 +186,8 @@ TransportClientSocketPool::CreateForTesting(
return base::WrapUnique<TransportClientSocketPool>(
new TransportClientSocketPool(
max_sockets, max_sockets_per_group, unused_idle_socket_timeout,
- used_idle_socket_timeout, proxy_server, is_for_websockets,
- common_connect_job_params, true /* cleanup_on_ip_address_change */,
+ used_idle_socket_timeout, proxy_chain, is_for_websockets,
+ common_connect_job_params, /*cleanup_on_ip_address_change=*/true,
std::move(connect_job_factory), ssl_client_context,
connect_backup_jobs_enabled));
}
@@ -449,7 +450,7 @@ int TransportClientSocketPool::RequestSocketInternal(
// so allocate and connect a new one.
group = GetOrCreateGroup(group_id);
std::unique_ptr<ConnectJob> connect_job(
- CreateConnectJob(group_id, request.socket_params(), proxy_server_,
+ CreateConnectJob(group_id, request.socket_params(), proxy_chain_,
request.proxy_annotation_tag(), request.priority(),
request.socket_tag(), group));
connect_job->net_log().AddEvent(
@@ -775,7 +776,7 @@ TransportClientSocketPool::TransportClientSocketPool(
int max_sockets_per_group,
base::TimeDelta unused_idle_socket_timeout,
base::TimeDelta used_idle_socket_timeout,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
bool is_for_websockets,
const CommonConnectJobParams* common_connect_job_params,
bool cleanup_on_ip_address_change,
@@ -789,7 +790,7 @@ TransportClientSocketPool::TransportClientSocketPool(
max_sockets_per_group_(max_sockets_per_group),
unused_idle_socket_timeout_(unused_idle_socket_timeout),
used_idle_socket_timeout_(used_idle_socket_timeout),
- proxy_server_(proxy_server),
+ proxy_chain_(proxy_chain),
cleanup_on_ip_address_change_(cleanup_on_ip_address_change),
connect_backup_jobs_enabled_(connect_backup_jobs_enabled &&
g_connect_backup_jobs_enabled),
@@ -842,9 +843,11 @@ void TransportClientSocketPool::OnSSLConfigForServersChanged(
// If the proxy is |server| and uses SSL settings (HTTPS or QUIC), refresh
// every group.
- bool proxy_matches = proxy_server_.is_http_like() &&
- !proxy_server_.is_http() &&
- servers.contains(proxy_server_.host_port_pair());
+ // TODO(https://crbug.com/1491092): Check each ProxyServer in `proxy_chain_`.
+ bool proxy_matches =
+ proxy_chain_.proxy_server().is_http_like() &&
+ !proxy_chain_.proxy_server().is_http() &&
+ servers.contains(proxy_chain_.proxy_server().host_port_pair());
bool refreshed_any = false;
for (auto it = group_map_.begin(); it != group_map_.end();) {
if (proxy_matches ||
@@ -1610,9 +1613,9 @@ void TransportClientSocketPool::Group::OnBackupJobTimerFired(
Request* request = unbound_requests_.FirstMax().value().get();
std::unique_ptr<ConnectJob> owned_backup_job =
client_socket_pool_->CreateConnectJob(
- group_id, request->socket_params(),
- client_socket_pool_->proxy_server_, request->proxy_annotation_tag(),
- request->priority(), request->socket_tag(), this);
+ group_id, request->socket_params(), client_socket_pool_->proxy_chain_,
+ request->proxy_annotation_tag(), request->priority(),
+ request->socket_tag(), this);
owned_backup_job->net_log().AddEvent(
NetLogEventType::SOCKET_POOL_CONNECT_JOB_CREATED, [&] {
return NetLogCreateConnectJobParams(true /* backup_job */, &group_id_);
diff --git a/net/socket/transport_client_socket_pool.h b/net/socket/transport_client_socket_pool.h
index 470c878df..bb218b3f0 100644
--- a/net/socket/transport_client_socket_pool.h
+++ b/net/socket/transport_client_socket_pool.h
@@ -29,7 +29,7 @@
#include "net/base/net_export.h"
#include "net/base/network_change_notifier.h"
#include "net/base/priority_queue.h"
-#include "net/base/proxy_server.h"
+#include "net/base/proxy_chain.h"
#include "net/base/request_priority.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/client_socket_handle.h"
@@ -151,7 +151,7 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool
int max_sockets,
int max_sockets_per_group,
base::TimeDelta unused_idle_socket_timeout,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
bool is_for_websockets,
const CommonConnectJobParams* common_connect_job_params,
bool cleanup_on_ip_address_change = true);
@@ -170,7 +170,7 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool
int max_sockets_per_group,
base::TimeDelta unused_idle_socket_timeout,
base::TimeDelta used_idle_socket_timeout,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain_,
bool is_for_websockets,
const CommonConnectJobParams* common_connect_job_params,
std::unique_ptr<ConnectJobFactory> connect_job_factory,
@@ -581,7 +581,7 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool
int max_sockets_per_group,
base::TimeDelta unused_idle_socket_timeout,
base::TimeDelta used_idle_socket_timeout,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
bool is_for_websockets,
const CommonConnectJobParams* common_connect_job_params,
bool cleanup_on_ip_address_change,
@@ -786,7 +786,7 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool
const base::TimeDelta unused_idle_socket_timeout_;
const base::TimeDelta used_idle_socket_timeout_;
- const ProxyServer proxy_server_;
+ const ProxyChain proxy_chain_;
const bool cleanup_on_ip_address_change_;
diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc
index 112eef963..63bc6b999 100644
--- a/net/socket/transport_client_socket_pool_unittest.cc
+++ b/net/socket/transport_client_socket_pool_unittest.cc
@@ -24,6 +24,7 @@
#include "net/base/load_timing_info_test_util.h"
#include "net/base/net_errors.h"
#include "net/base/privacy_mode.h"
+#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/proxy_string_util.h"
#include "net/base/schemeful_site.h"
@@ -133,7 +134,7 @@ class TransportClientSocketPoolTest : public ::testing::Test,
common_connect_job_params_->client_socket_factory = &client_socket_factory_;
pool_ = std::make_unique<TransportClientSocketPool>(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
- ProxyServer::Direct(), false /* is_for_websockets */,
+ ProxyChain::Direct(), /*is_for_websockets=*/false,
common_connect_job_params_.get());
tagging_common_connect_job_params_ =
@@ -143,7 +144,7 @@ class TransportClientSocketPoolTest : public ::testing::Test,
&tagging_client_socket_factory_;
tagging_pool_ = std::make_unique<TransportClientSocketPool>(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
- ProxyServer::Direct(), false /* is_for_websockets */,
+ ProxyChain::Direct(), /*is_for_websockets=*/false,
tagging_common_connect_job_params_.get());
common_connect_job_params_for_real_sockets_ =
@@ -153,7 +154,7 @@ class TransportClientSocketPoolTest : public ::testing::Test,
ClientSocketFactory::GetDefaultFactory();
pool_for_real_sockets_ = std::make_unique<TransportClientSocketPool>(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
- ProxyServer::Direct(), false /* is_for_websockets */,
+ ProxyChain::Direct(), /*is_for_websockets=*/false,
common_connect_job_params_for_real_sockets_.get());
}
@@ -531,8 +532,8 @@ TEST_F(TransportClientSocketPoolTest, ReprioritizeRequests) {
TEST_F(TransportClientSocketPoolTest, RequestIgnoringLimitsIsReprioritized) {
TransportClientSocketPool pool(
- kMaxSockets, 1, kUnusedIdleSocketTimeout, ProxyServer::Direct(),
- false /* is_for_websockets */, common_connect_job_params_.get());
+ kMaxSockets, 1, kUnusedIdleSocketTimeout, ProxyChain::Direct(),
+ /*is_for_websockets=*/false, common_connect_job_params_.get());
// Creates a job which ignores limits whose priority is MAXIMUM_PRIORITY.
TestCompletionCallback callback1;
@@ -1056,9 +1057,9 @@ TEST(TransportClientSocketPoolStandaloneTest, DontCleanupOnIPAddressChange) {
ClientSocketPool::SocketParams::CreateForHttpForTesting());
auto pool = std::make_unique<TransportClientSocketPool>(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
- ProxyServer::Direct(), false /* is_for_websockets */,
+ ProxyChain::Direct(), /*is_for_websockets=*/false,
common_connect_job_params.get(),
- false /* cleanup_on_ip_address_change */);
+ /*cleanup_on_ip_address_change=*/false);
const ClientSocketPool::GroupId group_id(
url::SchemeHostPort(url::kHttpScheme, "www.google.com", 80),
PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
@@ -1105,7 +1106,7 @@ TEST_F(TransportClientSocketPoolTest, SSLCertError) {
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
std::move(ssl_config_for_origin),
- /*ssl_config_for_proxy=*/nullptr);
+ /*base_ssl_config_for_proxies=*/nullptr);
ClientSocketHandle handle;
TestCompletionCallback callback;
@@ -1507,15 +1508,15 @@ TEST_F(TransportClientSocketPoolTest, SOCKS) {
TransportClientSocketPool proxy_pool(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
- ProxyUriToProxyServer("socks5://foopy",
- ProxyServer::SCHEME_HTTP /* default_scheme */),
- false /* is_for_websockets */, tagging_common_connect_job_params_.get());
+ ProxyUriToProxyChain("socks5://foopy",
+ /*default_scheme=*/ProxyServer::SCHEME_HTTP),
+ /*is_for_websockets=*/false, tagging_common_connect_job_params_.get());
for (IoMode socket_io_mode : {SYNCHRONOUS, ASYNC}) {
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */);
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr);
SOCKS5MockData data(socket_io_mode);
data.data_provider()->set_connect_data(MockConnect(socket_io_mode, OK));
@@ -1551,9 +1552,9 @@ TEST_F(TransportClientSocketPoolTest, SpdyOneConnectJobTwoRequestsError) {
// Create a socket pool which only allows a single connection at a time.
TransportClientSocketPool pool(
1, 1, kUnusedIdleSocketTimeout,
- ProxyUriToProxyServer("https://unresolvable.proxy.name",
- ProxyServer::SCHEME_HTTP /* default_scheme */),
- false /* is_for_websockets */, tagging_common_connect_job_params_.get());
+ ProxyUriToProxyChain("https://unresolvable.proxy.name",
+ /*default_scheme=*/ProxyServer::SCHEME_HTTP),
+ /*is_for_websockets=*/false, tagging_common_connect_job_params_.get());
// First connection attempt will get an error after creating the SpdyStream.
@@ -1588,8 +1589,8 @@ TEST_F(TransportClientSocketPoolTest, SpdyOneConnectJobTwoRequestsError) {
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- std::make_unique<SSLConfig>() /* ssl_config_for_origin */,
- std::make_unique<SSLConfig>() /* ssl_config_for_proxy */);
+ /*ssl_config_for_origin=*/std::make_unique<SSLConfig>(),
+ /*base_ssl_config_for_proxies=*/std::make_unique<SSLConfig>());
ClientSocketPool::GroupId group_id(
kEndpoint, PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
@@ -1643,9 +1644,9 @@ TEST_F(TransportClientSocketPoolTest, SpdyAuthOneConnectJobTwoRequests) {
// Create a socket pool which only allows a single connection at a time.
TransportClientSocketPool pool(
1, 1, kUnusedIdleSocketTimeout,
- ProxyUriToProxyServer("https://unresolvable.proxy.name",
- ProxyServer::SCHEME_HTTP /* default_scheme */),
- false /* is_for_websockets */, tagging_common_connect_job_params_.get());
+ ProxyUriToProxyChain("https://unresolvable.proxy.name",
+ /*default_scheme=*/ProxyServer::SCHEME_HTTP),
+ /*is_for_websockets=*/false, tagging_common_connect_job_params_.get());
SpdyTestUtil spdy_util;
spdy::SpdySerializedFrame connect(spdy_util.ConstructSpdyConnect(
@@ -1693,8 +1694,8 @@ TEST_F(TransportClientSocketPoolTest, SpdyAuthOneConnectJobTwoRequests) {
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- std::make_unique<SSLConfig>() /* ssl_config_for_origin */,
- std::make_unique<SSLConfig>() /* ssl_config_for_proxy */);
+ /*ssl_config_for_origin=*/std::make_unique<SSLConfig>(),
+ /*base_ssl_config_for_proxies=*/std::make_unique<SSLConfig>());
ClientSocketPool::GroupId group_id(
kEndpoint, PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
@@ -1763,10 +1764,10 @@ TEST_F(TransportClientSocketPoolTest, HttpTunnelSetupRedirect) {
TransportClientSocketPool proxy_pool(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
- ProxyUriToProxyServer(
+ ProxyUriToProxyChain(
use_https_proxy ? "https://proxy.test" : "http://proxy.test",
- ProxyServer::SCHEME_HTTP /* default_scheme */),
- false /* is_for_websockets */,
+ /*default_scheme=*/ProxyServer::SCHEME_HTTP),
+ /*is_for_websockets=*/false,
tagging_common_connect_job_params_.get());
MockWrite writes[] = {
@@ -1789,8 +1790,8 @@ TEST_F(TransportClientSocketPoolTest, HttpTunnelSetupRedirect) {
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- std::make_unique<SSLConfig>() /* ssl_config_for_origin */,
- std::make_unique<SSLConfig>() /* ssl_config_for_proxy */);
+ /*ssl_config_for_origin=*/std::make_unique<SSLConfig>(),
+ /*base_ssl_config_for_proxies=*/std::make_unique<SSLConfig>());
int rv = handle.Init(
ClientSocketPool::GroupId(
@@ -1834,8 +1835,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKey) {
EXPECT_THAT(
handle.Init(group_id,
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */),
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr),
TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -1876,7 +1877,7 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySsl) {
handle.Init(group_id,
base::MakeRefCounted<ClientSocketPool::SocketParams>(
std::move(ssl_config_for_origin),
- /*ssl_config_for_proxy=*/nullptr),
+ /*base_ssl_config_for_proxies=*/nullptr),
TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
ClientSocketPool::ProxyAuthCallback(), pool_.get(),
@@ -1900,8 +1901,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpProxy) {
const auto kNetworkAnonymizationKey2 =
NetworkAnonymizationKey::CreateSameSite(kSite2);
const char kHost[] = "bar.test";
- const ProxyServer kProxyServer = ProxyUriToProxyServer(
- "http://proxy.test", ProxyServer::SCHEME_HTTP /* default_scheme */);
+ const ProxyChain kProxyChain = ProxyUriToProxyChain(
+ "http://proxy.test", /*default_scheme=*/ProxyServer::SCHEME_HTTP);
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
@@ -1914,8 +1915,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpProxy) {
session_deps_.host_resolver->set_ondemand_mode(true);
TransportClientSocketPool proxy_pool(
- kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, kProxyServer,
- false /* is_for_websockets */, tagging_common_connect_job_params_.get());
+ kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, kProxyChain,
+ /*is_for_websockets=*/false, tagging_common_connect_job_params_.get());
TransportClientSocketPool::GroupId group_id1(
url::SchemeHostPort(url::kHttpScheme, kHost, 80),
@@ -1926,8 +1927,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpProxy) {
EXPECT_THAT(
handle1.Init(group_id1,
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */),
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr),
TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
@@ -1943,8 +1944,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpProxy) {
EXPECT_THAT(
handle2.Init(group_id2,
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */),
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr),
TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
@@ -1952,9 +1953,9 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpProxy) {
IsError(ERR_IO_PENDING));
ASSERT_EQ(2u, session_deps_.host_resolver->last_id());
- EXPECT_EQ(kProxyServer.host_port_pair().host(),
+ EXPECT_EQ(kProxyChain.proxy_server().host_port_pair().host(),
session_deps_.host_resolver->request_host(1));
- EXPECT_EQ(kProxyServer.host_port_pair().host(),
+ EXPECT_EQ(kProxyChain.proxy_server().host_port_pair().host(),
session_deps_.host_resolver->request_host(2));
EXPECT_TRUE(session_deps_.host_resolver->request_network_anonymization_key(1)
.IsTransient());
@@ -1973,8 +1974,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpsProxy) {
const auto kNetworkAnonymizationKey2 =
NetworkAnonymizationKey::CreateSameSite(kSite2);
const char kHost[] = "bar.test";
- const ProxyServer kProxyServer = ProxyUriToProxyServer(
- "https://proxy.test", ProxyServer::SCHEME_HTTP /* default_scheme */);
+ const ProxyChain kProxyChain = ProxyUriToProxyChain(
+ "https://proxy.test", /*default_scheme=*/ProxyServer::SCHEME_HTTP);
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
@@ -1987,7 +1988,7 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpsProxy) {
session_deps_.host_resolver->set_ondemand_mode(true);
TransportClientSocketPool proxy_pool(
- kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, kProxyServer,
+ kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, kProxyChain,
false /* is_for_websockets */, tagging_common_connect_job_params_.get());
TransportClientSocketPool::GroupId group_id1(
@@ -1996,16 +1997,17 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpsProxy) {
SecureDnsPolicy::kAllow);
ClientSocketHandle handle1;
TestCompletionCallback callback1;
- EXPECT_THAT(handle1.Init(
- group_id1,
- base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- std::make_unique<SSLConfig>() /* ssl_config_for_proxy */),
- TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
- ClientSocketPool::RespectLimits::ENABLED,
- callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
- &proxy_pool, NetLogWithSource()),
- IsError(ERR_IO_PENDING));
+ EXPECT_THAT(
+ handle1.Init(
+ group_id1,
+ base::MakeRefCounted<ClientSocketPool::SocketParams>(
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/std::make_unique<SSLConfig>()),
+ TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED, callback1.callback(),
+ ClientSocketPool::ProxyAuthCallback(), &proxy_pool,
+ NetLogWithSource()),
+ IsError(ERR_IO_PENDING));
TransportClientSocketPool::GroupId group_id2(
url::SchemeHostPort(url::kHttpScheme, kHost, 80),
@@ -2013,21 +2015,22 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeyHttpsProxy) {
SecureDnsPolicy::kAllow);
ClientSocketHandle handle2;
TestCompletionCallback callback2;
- EXPECT_THAT(handle2.Init(
- group_id2,
- base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- std::make_unique<SSLConfig>() /* ssl_config_for_proxy */),
- TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
- ClientSocketPool::RespectLimits::ENABLED,
- callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
- &proxy_pool, NetLogWithSource()),
- IsError(ERR_IO_PENDING));
+ EXPECT_THAT(
+ handle2.Init(
+ group_id2,
+ base::MakeRefCounted<ClientSocketPool::SocketParams>(
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/std::make_unique<SSLConfig>()),
+ TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
+ ClientSocketPool::RespectLimits::ENABLED, callback2.callback(),
+ ClientSocketPool::ProxyAuthCallback(), &proxy_pool,
+ NetLogWithSource()),
+ IsError(ERR_IO_PENDING));
ASSERT_EQ(2u, session_deps_.host_resolver->last_id());
- EXPECT_EQ(kProxyServer.host_port_pair().host(),
+ EXPECT_EQ(kProxyChain.proxy_server().host_port_pair().host(),
session_deps_.host_resolver->request_host(1));
- EXPECT_EQ(kProxyServer.host_port_pair().host(),
+ EXPECT_EQ(kProxyChain.proxy_server().host_port_pair().host(),
session_deps_.host_resolver->request_host(2));
EXPECT_TRUE(session_deps_.host_resolver->request_network_anonymization_key(1)
.IsTransient());
@@ -2047,8 +2050,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks4Proxy) {
const auto kNetworkAnonymizationKey2 =
NetworkAnonymizationKey::CreateSameSite(kSite2);
const char kHost[] = "bar.test";
- const ProxyServer kProxyServer = ProxyUriToProxyServer(
- "socks4://proxy.test", ProxyServer::SCHEME_HTTP /* default_scheme */);
+ const ProxyChain kProxyChain = ProxyUriToProxyChain(
+ "socks4://proxy.test", /*default_scheme=*/ProxyServer::SCHEME_HTTP);
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
@@ -2070,8 +2073,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks4Proxy) {
tagging_client_socket_factory_.AddSocketDataProvider(&data2);
TransportClientSocketPool proxy_pool(
- kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, kProxyServer,
- false /* is_for_websockets */, tagging_common_connect_job_params_.get());
+ kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, kProxyChain,
+ /*is_for_websockets=*/false, tagging_common_connect_job_params_.get());
TransportClientSocketPool::GroupId group_id1(
url::SchemeHostPort(url::kHttpScheme, kHost, 80),
@@ -2082,8 +2085,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks4Proxy) {
EXPECT_THAT(
handle1.Init(group_id1,
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */),
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr),
TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
@@ -2099,8 +2102,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks4Proxy) {
EXPECT_THAT(
handle2.Init(group_id2,
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */),
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr),
TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
@@ -2110,9 +2113,9 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks4Proxy) {
// First two lookups are for the proxy's hostname, and should use the same
// transient NIK.
ASSERT_EQ(2u, session_deps_.host_resolver->last_id());
- EXPECT_EQ(kProxyServer.host_port_pair().host(),
+ EXPECT_EQ(kProxyChain.proxy_server().host_port_pair().host(),
session_deps_.host_resolver->request_host(1));
- EXPECT_EQ(kProxyServer.host_port_pair().host(),
+ EXPECT_EQ(kProxyChain.proxy_server().host_port_pair().host(),
session_deps_.host_resolver->request_host(2));
EXPECT_TRUE(session_deps_.host_resolver->request_network_anonymization_key(1)
.IsTransient());
@@ -2143,8 +2146,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks5Proxy) {
const auto kNetworkAnonymizationKey2 =
NetworkAnonymizationKey::CreateSameSite(kSite2);
const char kHost[] = "bar.test";
- const ProxyServer kProxyServer = ProxyUriToProxyServer(
- "socks5://proxy.test", ProxyServer::SCHEME_HTTP /* default_scheme */);
+ const ProxyChain kProxyChain = ProxyUriToProxyChain(
+ "socks5://proxy.test", /*default_scheme=*/ProxyServer::SCHEME_HTTP);
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
@@ -2157,8 +2160,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks5Proxy) {
session_deps_.host_resolver->set_ondemand_mode(true);
TransportClientSocketPool proxy_pool(
- kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, kProxyServer,
- false /* is_for_websockets */, tagging_common_connect_job_params_.get());
+ kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, kProxyChain,
+ /*is_for_websockets=*/false, tagging_common_connect_job_params_.get());
TransportClientSocketPool::GroupId group_id1(
url::SchemeHostPort(url::kHttpScheme, kHost, 80),
@@ -2169,8 +2172,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks5Proxy) {
EXPECT_THAT(
handle1.Init(group_id1,
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */),
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr),
TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback1.callback(), ClientSocketPool::ProxyAuthCallback(),
@@ -2186,8 +2189,8 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks5Proxy) {
EXPECT_THAT(
handle2.Init(group_id2,
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */),
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr),
TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED,
callback2.callback(), ClientSocketPool::ProxyAuthCallback(),
@@ -2195,9 +2198,9 @@ TEST_F(TransportClientSocketPoolTest, NetworkIsolationKeySocks5Proxy) {
IsError(ERR_IO_PENDING));
ASSERT_EQ(2u, session_deps_.host_resolver->last_id());
- EXPECT_EQ(kProxyServer.host_port_pair().host(),
+ EXPECT_EQ(kProxyChain.proxy_server().host_port_pair().host(),
session_deps_.host_resolver->request_host(1));
- EXPECT_EQ(kProxyServer.host_port_pair().host(),
+ EXPECT_EQ(kProxyChain.proxy_server().host_port_pair().host(),
session_deps_.host_resolver->request_host(2));
EXPECT_TRUE(session_deps_.host_resolver->request_network_anonymization_key(1)
.IsTransient());
@@ -2414,9 +2417,9 @@ TEST_F(TransportClientSocketPoolTest, TagSOCKSProxy) {
TransportClientSocketPool proxy_pool(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
- ProxyUriToProxyServer("socks5://proxy",
- ProxyServer::SCHEME_HTTP /* default_scheme */),
- false /* is_for_websockets */, tagging_common_connect_job_params_.get());
+ ProxyUriToProxyChain("socks5://proxy",
+ /*default_scheme=*/ProxyServer::SCHEME_HTTP),
+ /*is_for_websockets=*/false, tagging_common_connect_job_params_.get());
SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
SocketTag tag2(getuid(), 0x87654321);
@@ -2426,8 +2429,8 @@ TEST_F(TransportClientSocketPoolTest, TagSOCKSProxy) {
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
scoped_refptr<ClientSocketPool::SocketParams> socks_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */);
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr);
// Test socket is tagged when created synchronously.
SOCKS5MockData data_sync(SYNCHRONOUS);
@@ -2524,7 +2527,7 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirect) {
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
std::move(ssl_config_for_origin),
- /*ssl_config_for_proxy=*/nullptr);
+ /*base_ssl_config_for_proxies=*/nullptr);
// Test socket is tagged before connected.
uint64_t old_traffic = GetTaggedBytes(tag_val1);
@@ -2596,7 +2599,7 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirectTwoSockets) {
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
std::move(ssl_config_for_origin),
- /*ssl_config_for_proxy=*/nullptr);
+ /*base_ssl_config_for_proxies=*/nullptr);
// Test connect jobs that are orphaned and then adopted, appropriately apply
// new tag. Request socket with |tag1|.
@@ -2662,7 +2665,7 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirectTwoSocketsFullPool) {
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
std::move(ssl_config_for_origin),
- /*ssl_config_for_proxy=*/nullptr);
+ /*base_ssl_config_for_proxies=*/nullptr);
// Test that sockets paused by a full underlying socket pool are properly
// connected and tagged when underlying pool is freed up.
@@ -2725,9 +2728,9 @@ TEST_F(TransportClientSocketPoolTest, TagHttpProxyNoTunnel) {
TransportClientSocketPool proxy_pool(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
- ProxyUriToProxyServer("http://proxy",
- ProxyServer::SCHEME_HTTP /* default_scheme */),
- false /* is_for_websockets */, tagging_common_connect_job_params_.get());
+ ProxyUriToProxyChain("http://proxy",
+ /*default_scheme=*/ProxyServer::SCHEME_HTTP),
+ /*is_for_websockets=*/false, tagging_common_connect_job_params_.get());
session_deps_.host_resolver->set_synchronous_mode(true);
SequencedSocketData socket_data;
@@ -2741,8 +2744,8 @@ TEST_F(TransportClientSocketPoolTest, TagHttpProxyNoTunnel) {
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow);
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */);
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr);
// Verify requested socket is tagged properly.
ClientSocketHandle handle;
@@ -2785,9 +2788,9 @@ TEST_F(TransportClientSocketPoolTest, TagHttpProxyTunnel) {
TransportClientSocketPool proxy_pool(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
- ProxyUriToProxyServer("http://proxy",
- ProxyServer::SCHEME_HTTP /* default_scheme */),
- false /* is_for_websockets */, tagging_common_connect_job_params_.get());
+ ProxyUriToProxyChain("http://proxy",
+ /*default_scheme=*/ProxyServer::SCHEME_HTTP),
+ /*is_for_websockets=*/false, tagging_common_connect_job_params_.get());
session_deps_.host_resolver->set_synchronous_mode(true);
@@ -2818,7 +2821,7 @@ TEST_F(TransportClientSocketPoolTest, TagHttpProxyTunnel) {
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
std::move(ssl_config_for_origin),
- /*ssl_config_for_proxy=*/nullptr);
+ /*base_ssl_config_for_proxies=*/nullptr);
// Verify requested socket is tagged properly.
ClientSocketHandle handle;
@@ -2929,8 +2932,8 @@ TEST_F(TransportClientSocketPoolMockNowSourceTest, IdleUnusedSocketTimeout) {
// Create 1 socket.
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */);
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr);
session_deps.socket_factory->AddSocketDataProvider(&provider_socket_1);
ClientSocketHandle connection;
TestCompletionCallback callback;
@@ -2939,11 +2942,11 @@ TEST_F(TransportClientSocketPoolMockNowSourceTest, IdleUnusedSocketTimeout) {
kSchemeHostPort1, PrivacyMode::PRIVACY_MODE_DISABLED,
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow),
ClientSocketPool::SocketParams::CreateForHttpForTesting(),
- absl::nullopt /* proxy_annotation_tag */, MEDIUM, SocketTag(),
+ /*proxy_annotation_tag=*/absl::nullopt, MEDIUM, SocketTag(),
ClientSocketPool::RespectLimits::ENABLED, callback.callback(),
ClientSocketPool::ProxyAuthCallback(),
session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
- ProxyServer::Direct()),
+ ProxyChain::Direct()),
NetLogWithSource());
EXPECT_THAT(callback.GetResult(rv), IsOk());
EXPECT_FALSE(connection.socket()->WasEverUsed());
@@ -2964,7 +2967,7 @@ TEST_F(TransportClientSocketPoolMockNowSourceTest, IdleUnusedSocketTimeout) {
EXPECT_EQ(1, session
->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
- ProxyServer::Direct())
+ ProxyChain::Direct())
->IdleSocketCount());
// Moving the clock forward may cause the idle socket to be timedout.
@@ -2974,8 +2977,8 @@ TEST_F(TransportClientSocketPoolMockNowSourceTest, IdleUnusedSocketTimeout) {
// Request a new socket to trigger cleanup of idle timedout sockets.
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
- nullptr /* ssl_config_for_origin */,
- nullptr /* ssl_config_for_proxy */);
+ /*ssl_config_for_origin=*/nullptr,
+ /*base_ssl_config_for_proxies=*/nullptr);
SequencedSocketData provider_socket_2(MockConnect(ASYNC, OK),
base::span<MockRead>(),
base::span<MockWrite>());
@@ -2986,11 +2989,11 @@ TEST_F(TransportClientSocketPoolMockNowSourceTest, IdleUnusedSocketTimeout) {
ClientSocketPool::GroupId(
kSchemeHostPort2, PrivacyMode::PRIVACY_MODE_DISABLED,
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow),
- socket_params, absl::nullopt /* proxy_annotation_tag */, MEDIUM,
+ socket_params, /*proxy_annotation_tag=*/absl::nullopt, MEDIUM,
SocketTag(), ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), ClientSocketPool::ProxyAuthCallback(),
session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
- ProxyServer::Direct()),
+ ProxyChain::Direct()),
NetLogWithSource());
EXPECT_THAT(callback.GetResult(rv), IsOk());
connection.socket()->Disconnect();
@@ -2999,7 +3002,7 @@ TEST_F(TransportClientSocketPoolMockNowSourceTest, IdleUnusedSocketTimeout) {
EXPECT_EQ(test.expect_idle_socket ? 1 : 0,
session
->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL,
- ProxyServer::Direct())
+ ProxyChain::Direct())
->IdleSocketCount());
}
}
diff --git a/net/socket/transport_connect_job_unittest.cc b/net/socket/transport_connect_job_unittest.cc
index 01a8d706a..714cdaced 100644
--- a/net/socket/transport_connect_job_unittest.cc
+++ b/net/socket/transport_connect_job_unittest.cc
@@ -67,7 +67,8 @@ class TransportConnectJobTest : public WithTaskEnvironment,
/*socket_performance_watcher_factory=*/nullptr,
/*network_quality_estimator=*/nullptr,
NetLog::Get(),
- /*websocket_endpoint_lock_manager=*/nullptr) {}
+ /*websocket_endpoint_lock_manager=*/nullptr,
+ /*http_server_properties=*/nullptr) {}
~TransportConnectJobTest() override = default;
diff --git a/net/socket/udp_client_socket.cc b/net/socket/udp_client_socket.cc
index ca4a277e7..406903220 100644
--- a/net/socket/udp_client_socket.cc
+++ b/net/socket/udp_client_socket.cc
@@ -12,18 +12,58 @@
namespace net {
+namespace {
+
+base::Value::Dict CreateNetLogUDPConnectParams(const IPEndPoint& address,
+ int net_error) {
+ DCHECK_NE(ERR_IO_PENDING, net_error);
+ base::Value::Dict params;
+ params.Set("address", address.ToString());
+ if (net_error < 0) {
+ params.Set("net_error", net_error);
+ }
+ return params;
+}
+
+base::Value::Dict CreateNetLogUDPBindToNetworkParams(
+ handles::NetworkHandle network,
+ int net_error) {
+ DCHECK_NE(ERR_IO_PENDING, net_error);
+ base::Value::Dict params;
+ params.Set("network", static_cast<int>(network));
+ if (net_error < 0) {
+ params.Set("net_error", net_error);
+ }
+ return params;
+}
+
+} // namespace
+
UDPClientSocket::UDPClientSocket(DatagramSocket::BindType bind_type,
net::NetLog* net_log,
const net::NetLogSource& source,
handles::NetworkHandle network)
- : socket_(bind_type, net_log, source), connect_using_network_(network) {}
+ : net_log_(
+ NetLogWithSource::Make(net_log, NetLogSourceType::UDP_CLIENT_SOCKET)),
+ socket_(bind_type, net_log, net_log_.source()),
+ connect_using_network_(network) {
+ net_log_.BeginEventReferencingSource(NetLogEventType::SOCKET_ALIVE, source);
+}
UDPClientSocket::UDPClientSocket(DatagramSocket::BindType bind_type,
NetLogWithSource source_net_log,
handles::NetworkHandle network)
- : socket_(bind_type, source_net_log), connect_using_network_(network) {}
+ : net_log_(NetLogWithSource::Make(source_net_log.net_log(),
+ NetLogSourceType::UDP_CLIENT_SOCKET)),
+ socket_(bind_type, net_log_),
+ connect_using_network_(network) {
+ net_log_.BeginEventReferencingSource(NetLogEventType::SOCKET_ALIVE,
+ source_net_log.source());
+}
-UDPClientSocket::~UDPClientSocket() = default;
+UDPClientSocket::~UDPClientSocket() {
+ net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE);
+}
int UDPClientSocket::Connect(const IPEndPoint& address) {
CHECK(!connect_called_);
@@ -34,10 +74,14 @@ int UDPClientSocket::Connect(const IPEndPoint& address) {
int rv = OK;
if (!adopted_opened_socket_) {
rv = socket_.Open(address.GetFamily());
+ net_log_.AddEventWithNetErrorCode(NetLogEventType::SOCKET_OPEN, rv);
}
if (rv != OK)
return rv;
- return socket_.Connect(address);
+ rv = socket_.Connect(address);
+ net_log_.AddEvent(NetLogEventType::SOCKET_CONNECT,
+ [&] { return CreateNetLogUDPConnectParams(address, rv); });
+ return rv;
}
int UDPClientSocket::ConnectUsingNetwork(handles::NetworkHandle network,
@@ -49,15 +93,22 @@ int UDPClientSocket::ConnectUsingNetwork(handles::NetworkHandle network,
int rv = OK;
if (!adopted_opened_socket_) {
rv = socket_.Open(address.GetFamily());
+ net_log_.AddEventWithNetErrorCode(NetLogEventType::SOCKET_OPEN, rv);
}
if (rv != OK) {
return rv;
}
rv = socket_.BindToNetwork(network);
+ net_log_.AddEvent(NetLogEventType::SOCKET_BIND_TO_NETWORK, [&] {
+ return CreateNetLogUDPBindToNetworkParams(network, rv);
+ });
if (rv != OK)
return rv;
network_ = network;
- return socket_.Connect(address);
+ rv = socket_.Connect(address);
+ net_log_.AddEvent(NetLogEventType::SOCKET_CONNECT,
+ [&] { return CreateNetLogUDPConnectParams(address, rv); });
+ return rv;
}
int UDPClientSocket::ConnectUsingDefaultNetwork(const IPEndPoint& address) {
@@ -68,6 +119,7 @@ int UDPClientSocket::ConnectUsingDefaultNetwork(const IPEndPoint& address) {
int rv = OK;
if (!adopted_opened_socket_) {
rv = socket_.Open(address.GetFamily());
+ net_log_.AddEventWithNetErrorCode(NetLogEventType::SOCKET_OPEN, rv);
}
if (rv != OK)
return rv;
@@ -84,6 +136,9 @@ int UDPClientSocket::ConnectUsingDefaultNetwork(const IPEndPoint& address) {
if (network == handles::kInvalidNetworkHandle)
return ERR_INTERNET_DISCONNECTED;
rv = socket_.BindToNetwork(network);
+ net_log_.AddEvent(NetLogEventType::SOCKET_BIND_TO_NETWORK, [&] {
+ return CreateNetLogUDPBindToNetworkParams(network, rv);
+ });
// |network| may have disconnected between the call to GetDefaultNetwork()
// and the call to BindToNetwork(). Loop only if this is the case (|rv| will
// be ERR_NETWORK_CHANGED).
@@ -93,7 +148,10 @@ int UDPClientSocket::ConnectUsingDefaultNetwork(const IPEndPoint& address) {
if (rv != OK)
return rv;
network_ = network;
- return socket_.Connect(address);
+ rv = socket_.Connect(address);
+ net_log_.AddEvent(NetLogEventType::SOCKET_CONNECT,
+ [&] { return CreateNetLogUDPConnectParams(address, rv); });
+ return rv;
}
int UDPClientSocket::ConnectAsync(const IPEndPoint& address,
@@ -163,6 +221,10 @@ int UDPClientSocket::SetDoNotFragment() {
return socket_.SetDoNotFragment();
}
+int UDPClientSocket::SetRecvEcn() {
+ return socket_.SetRecvEcn();
+}
+
void UDPClientSocket::SetMsgConfirm(bool confirm) {
socket_.SetMsgConfirm(confirm);
}
diff --git a/net/socket/udp_client_socket.h b/net/socket/udp_client_socket.h
index 6e3875b4f..503dbd61d 100644
--- a/net/socket/udp_client_socket.h
+++ b/net/socket/udp_client_socket.h
@@ -72,6 +72,7 @@ class NET_EXPORT_PRIVATE UDPClientSocket : public DatagramClientSocket {
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int SetDoNotFragment() override;
+ int SetRecvEcn() override;
void SetMsgConfirm(bool confirm) override;
const NetLogWithSource& NetLog() const override;
void EnableRecvOptimization() override;
@@ -102,6 +103,7 @@ class NET_EXPORT_PRIVATE UDPClientSocket : public DatagramClientSocket {
#endif
private:
+ NetLogWithSource net_log_;
UDPSocket socket_;
bool adopted_opened_socket_ = false;
bool connect_called_ = false;
diff --git a/net/socket/udp_server_socket.cc b/net/socket/udp_server_socket.cc
index 0e8715d53..1520411b2 100644
--- a/net/socket/udp_server_socket.cc
+++ b/net/socket/udp_server_socket.cc
@@ -75,6 +75,10 @@ int UDPServerSocket::SetDoNotFragment() {
return socket_.SetDoNotFragment();
}
+int UDPServerSocket::SetRecvEcn() {
+ return socket_.SetRecvEcn();
+}
+
void UDPServerSocket::SetMsgConfirm(bool confirm) {
return socket_.SetMsgConfirm(confirm);
}
diff --git a/net/socket/udp_server_socket.h b/net/socket/udp_server_socket.h
index fb7ca9ca5..f93c84afa 100644
--- a/net/socket/udp_server_socket.h
+++ b/net/socket/udp_server_socket.h
@@ -42,6 +42,7 @@ class NET_EXPORT UDPServerSocket : public DatagramServerSocket {
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
int SetDoNotFragment() override;
+ int SetRecvEcn() override;
void SetMsgConfirm(bool confirm) override;
void Close() override;
int GetPeerAddress(IPEndPoint* address) const override;
diff --git a/net/socket/udp_socket_posix.cc b/net/socket/udp_socket_posix.cc
index 120ce583c..ac4a3e58f 100644
--- a/net/socket/udp_socket_posix.cc
+++ b/net/socket/udp_socket_posix.cc
@@ -552,7 +552,7 @@ int UDPSocketPosix::SetDoNotFragment() {
// setsockopt(IP_DONTFRAG) is supported on macOS from Big Sur
#elif BUILDFLAG(IS_MAC)
- if (!base::mac::IsAtLeastOS11()) {
+ if (base::mac::MacOSMajorVersion() < 11) {
return ERR_NOT_IMPLEMENTED;
}
int val = 1;
@@ -590,6 +590,32 @@ int UDPSocketPosix::SetDoNotFragment() {
#endif
}
+int UDPSocketPosix::SetRecvEcn() {
+ DCHECK_NE(socket_, kInvalidSocket);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ unsigned int ecn = 1;
+ if (addr_family_ == AF_INET6) {
+ if (setsockopt(socket_, IPPROTO_IPV6, IPV6_RECVTCLASS, &ecn, sizeof(ecn)) !=
+ 0) {
+ return MapSystemError(errno);
+ }
+
+ int v6_only = false;
+ socklen_t v6_only_len = sizeof(v6_only);
+ if (getsockopt(socket_, IPPROTO_IPV6, IPV6_V6ONLY, &v6_only,
+ &v6_only_len) != 0) {
+ return MapSystemError(errno);
+ }
+ if (v6_only) {
+ return OK;
+ }
+ }
+
+ int rv = setsockopt(socket_, IPPROTO_IP, IP_RECVTOS, &ecn, sizeof(ecn));
+ return rv == 0 ? OK : MapSystemError(errno);
+}
+
void UDPSocketPosix::SetMsgConfirm(bool confirm) {
#if !BUILDFLAG(IS_APPLE)
if (confirm) {
diff --git a/net/socket/udp_socket_posix.h b/net/socket/udp_socket_posix.h
index a0cb1e2f5..08a9fc757 100644
--- a/net/socket/udp_socket_posix.h
+++ b/net/socket/udp_socket_posix.h
@@ -173,6 +173,10 @@ class NET_EXPORT UDPSocketPosix {
// return ERR_IO_PENDING.
int SetDoNotFragment();
+ // Requests that packets received by this socket have the ECN bit set. Returns
+ // a network error code if there was a problem.
+ int SetRecvEcn();
+
// If |confirm| is true, then the MSG_CONFIRM flag will be passed to
// subsequent writes if it's supported by the platform.
void SetMsgConfirm(bool confirm);
diff --git a/net/socket/udp_socket_unittest.cc b/net/socket/udp_socket_unittest.cc
index 6f362047f..c0d4fd284 100644
--- a/net/socket/udp_socket_unittest.cc
+++ b/net/socket/udp_socket_unittest.cc
@@ -660,7 +660,7 @@ TEST_F(UDPSocketTest, ClientSetDoNotFragment) {
// TODO(crbug.com/945590): IP_MTU_DISCOVER is not implemented on Fuchsia.
EXPECT_THAT(rv, IsError(ERR_NOT_IMPLEMENTED));
#elif BUILDFLAG(IS_MAC)
- if (base::mac::IsAtLeastOS11()) {
+ if (base::mac::MacOSMajorVersion() >= 11) {
EXPECT_THAT(rv, IsOk());
} else {
EXPECT_THAT(rv, IsError(ERR_NOT_IMPLEMENTED));
@@ -688,7 +688,7 @@ TEST_F(UDPSocketTest, ServerSetDoNotFragment) {
// TODO(crbug.com/945590): IP_MTU_DISCOVER is not implemented on Fuchsia.
EXPECT_THAT(rv, IsError(ERR_NOT_IMPLEMENTED));
#elif BUILDFLAG(IS_MAC)
- if (base::mac::IsAtLeastOS11()) {
+ if (base::mac::MacOSMajorVersion() >= 11) {
EXPECT_THAT(rv, IsOk());
} else {
EXPECT_THAT(rv, IsError(ERR_NOT_IMPLEMENTED));
diff --git a/net/socket/udp_socket_win.cc b/net/socket/udp_socket_win.cc
index 32926a00c..deb0561db 100644
--- a/net/socket/udp_socket_win.cc
+++ b/net/socket/udp_socket_win.cc
@@ -589,6 +589,23 @@ int UDPSocketWin::SetDoNotFragment() {
return rv == 0 ? OK : MapSystemError(WSAGetLastError());
}
+int UDPSocketWin::SetRecvEcn() {
+ DCHECK_NE(socket_, INVALID_SOCKET);
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ int rv;
+ unsigned int ecn = 1;
+ if (addr_family_ == AF_INET6) {
+ rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_RECVTCLASS,
+ reinterpret_cast<const char*>(&ecn), sizeof(ecn));
+ } else {
+ DCHECK_EQ(addr_family_, AF_INET);
+ rv = setsockopt(socket_, IPPROTO_IP, IP_RECVTOS,
+ reinterpret_cast<const char*>(&ecn), sizeof(ecn));
+ }
+ return rv == 0 ? OK : MapSystemError(WSAGetLastError());
+}
+
void UDPSocketWin::SetMsgConfirm(bool confirm) {}
int UDPSocketWin::AllowAddressReuse() {
diff --git a/net/socket/udp_socket_win.h b/net/socket/udp_socket_win.h
index dd27752c6..2069bd530 100644
--- a/net/socket/udp_socket_win.h
+++ b/net/socket/udp_socket_win.h
@@ -262,6 +262,10 @@ class NET_EXPORT UDPSocketWin : public base::win::ObjectWatcher::Delegate {
// return ERR_IO_PENDING.
int SetDoNotFragment();
+ // Requests that packets received by this socket have the ECN bit set. Returns
+ // a network error code if there was a problem.
+ int SetRecvEcn();
+
// This is a no-op on Windows.
void SetMsgConfirm(bool confirm);
diff --git a/net/socket/websocket_transport_client_socket_pool.cc b/net/socket/websocket_transport_client_socket_pool.cc
index 286652d99..dfaa3ed25 100644
--- a/net/socket/websocket_transport_client_socket_pool.cc
+++ b/net/socket/websocket_transport_client_socket_pool.cc
@@ -31,12 +31,12 @@ namespace net {
WebSocketTransportClientSocketPool::WebSocketTransportClientSocketPool(
int max_sockets,
int max_sockets_per_group,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const CommonConnectJobParams* common_connect_job_params)
: ClientSocketPool(/*is_for_websockets=*/true,
common_connect_job_params,
std::make_unique<ConnectJobFactory>()),
- proxy_server_(proxy_server),
+ proxy_chain_(proxy_chain),
max_sockets_(max_sockets) {
DCHECK(common_connect_job_params->websocket_endpoint_lock_manager);
}
@@ -104,7 +104,7 @@ int WebSocketTransportClientSocketPool::RequestSocket(
request_net_log);
std::unique_ptr<ConnectJob> connect_job =
- CreateConnectJob(group_id, params, proxy_server_, proxy_annotation_tag,
+ CreateConnectJob(group_id, params, proxy_chain_, proxy_annotation_tag,
priority, SocketTag(), connect_job_delegate.get());
int result = connect_job_delegate->Connect(std::move(connect_job));
diff --git a/net/socket/websocket_transport_client_socket_pool.h b/net/socket/websocket_transport_client_socket_pool.h
index 2750816af..c32983e54 100644
--- a/net/socket/websocket_transport_client_socket_pool.h
+++ b/net/socket/websocket_transport_client_socket_pool.h
@@ -17,7 +17,7 @@
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "net/base/net_export.h"
-#include "net/base/proxy_server.h"
+#include "net/base/proxy_chain.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/client_socket_pool.h"
#include "net/socket/connect_job.h"
@@ -42,7 +42,7 @@ class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool
WebSocketTransportClientSocketPool(
int max_sockets,
int max_sockets_per_group,
- const ProxyServer& proxy_server,
+ const ProxyChain& proxy_chain,
const CommonConnectJobParams* common_connect_job_params);
WebSocketTransportClientSocketPool(
@@ -206,7 +206,7 @@ class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool
void ActivateStalledRequest();
bool DeleteStalledRequest(ClientSocketHandle* handle);
- const ProxyServer proxy_server_;
+ const ProxyChain proxy_chain_;
std::set<ClientSocketHandleID> pending_callbacks_;
PendingConnectsMap pending_connects_;
StalledRequestQueue stalled_request_queue_;
diff --git a/net/socket/websocket_transport_client_socket_pool_unittest.cc b/net/socket/websocket_transport_client_socket_pool_unittest.cc
index 787d08226..1e00ba861 100644
--- a/net/socket/websocket_transport_client_socket_pool_unittest.cc
+++ b/net/socket/websocket_transport_client_socket_pool_unittest.cc
@@ -24,6 +24,7 @@
#include "net/base/load_timing_info_test_util.h"
#include "net/base/net_errors.h"
#include "net/base/privacy_mode.h"
+#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/schemeful_site.h"
#include "net/base/test_completion_callback.h"
@@ -91,21 +92,22 @@ class WebSocketTransportClientSocketPoolTest : public TestWithTaskEnvironment {
common_connect_job_params_(
&client_socket_factory_,
host_resolver_.get(),
- nullptr /* http_auth_cache */,
- nullptr /* http_auth_handler_factory */,
- nullptr /* spdy_session_pool */,
- nullptr /* quic_supported_versions */,
- nullptr /* quic_stream_factory */,
- nullptr /* proxy_delegate */,
- nullptr /* http_user_agent_settings */,
- nullptr /* ssl_client_context */,
- nullptr /* socket_performance_watcher_factory */,
- nullptr /* network_quality_estimator */,
- nullptr /* netlog */,
- &websocket_endpoint_lock_manager_),
+ /*http_auth_cache=*/nullptr,
+ /*http_auth_handler_factory=*/nullptr,
+ /*spdy_session_pool=*/nullptr,
+ /*quic_supported_versions=*/nullptr,
+ /*quic_stream_factory=*/nullptr,
+ /*proxy_delegate=*/nullptr,
+ /*http_user_agent_settings=*/nullptr,
+ /*ssl_client_context=*/nullptr,
+ /*socket_performance_watcher_factory=*/nullptr,
+ /*network_quality_estimator=*/nullptr,
+ /*net_log=*/nullptr,
+ &websocket_endpoint_lock_manager_,
+ /*http_server_properties=*/nullptr),
pool_(kMaxSockets,
kMaxSocketsPerGroup,
- ProxyServer::Direct(),
+ ProxyChain::Direct(),
&common_connect_job_params_) {
websocket_endpoint_lock_manager_.SetUnlockDelayForTesting(
base::TimeDelta());