diff --git a/chromium_src/net/base/host_port_pair.cc b/chromium_src/net/base/host_port_pair.cc new file mode 100644 index 000000000000..fb56a11f3c0c --- /dev/null +++ b/chromium_src/net/base/host_port_pair.cc @@ -0,0 +1,39 @@ +// Copyright 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "../../../../net/base/host_port_pair.cc" + +#include "net/base/host_port_pair.h" + +#include "base/strings/string_number_conversions.h" + +namespace net { + +HostPortPair::~HostPortPair() = default; +HostPortPair::HostPortPair(const HostPortPair& host_port) = default; + +HostPortPair::HostPortPair(const std::string& username, + const std::string& password, + const std::string& in_host, uint16_t in_port) + : username_(username), password_(password), + host_(in_host), port_(in_port) { +} + +std::string HostPortPair::ToString() const { + std::string ret; + if (username_.size() != 0 || password_.size() != 0) { + ret += username_; + if (password_.size() != 0) { + ret += ':'; + ret += password_; + } + ret += '@'; + } + ret += HostForURL(); + ret += ':'; + ret += base::UintToString(port_); + return ret; +} + +} // namespace net diff --git a/chromium_src/net/base/url_util.cc b/chromium_src/net/base/url_util.cc new file mode 100644 index 000000000000..bd7f498930d5 --- /dev/null +++ b/chromium_src/net/base/url_util.cc @@ -0,0 +1,83 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "../../../../net/base/url_util.cc" + +#include +#include + +#include "base/strings/string_piece.h" +#include "url/third_party/mozilla/url_parse.h" +#include "url/url_canon_ip.h" + +namespace net { + +// Copypasta of ParseHostAndPort that extracts the username and +// password instead of rejecting them. +bool ParseAuthHostAndPort(base::StringPiece input, + std::string* username, + std::string* password, + std::string* host, + int* port) { + if (input.empty()) + return false; + + url::Component auth_component(0, input.size()); + url::Component username_component; + url::Component password_component; + url::Component hostname_component; + url::Component port_component; + + url::ParseAuthority(input.data(), auth_component, &username_component, + &password_component, &hostname_component, + &port_component); + + if (!hostname_component.is_nonempty()) + return false; // Failed parsing. + + int parsed_port_number = -1; + if (port_component.is_nonempty()) { + parsed_port_number = url::ParsePort(input.data(), port_component); + + // If parsing failed, port_number will be either PORT_INVALID or + // PORT_UNSPECIFIED, both of which are negative. + if (parsed_port_number < 0) + return false; // Failed parsing the port number. + } + + if (port_component.len == 0) + return false; // Reject inputs like "foo:" + + unsigned char tmp_ipv6_addr[16]; + + // If the hostname starts with a bracket, it is either an IPv6 literal or + // invalid. If it is an IPv6 literal then strip the brackets. + if (hostname_component.len > 0 && input[hostname_component.begin] == '[') { + if (input[hostname_component.end() - 1] == ']' && + url::IPv6AddressToNumber(input.data(), hostname_component, + tmp_ipv6_addr)) { + // Strip the brackets. + hostname_component.begin++; + hostname_component.len -= 2; + } else { + return false; + } + } + + // Pass results back to caller. + if (username_component.is_valid()) { + username->assign(input.data() + username_component.begin, + username_component.len); + } + if (password_component.is_valid()) { + password->assign(input.data() + password_component.begin, + password_component.len); + } + host->assign(input.data() + hostname_component.begin, hostname_component.len); + *port = parsed_port_number; + + return true; // Success. +} + +} diff --git a/chromium_src/net/base/url_util.h b/chromium_src/net/base/url_util.h new file mode 100644 index 000000000000..a120771b03ac --- /dev/null +++ b/chromium_src/net/base/url_util.h @@ -0,0 +1,24 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BRAVE_NET_BASE_URL_AUTH_UTIL_H_ +#define BRAVE_NET_BASE_URL_AUTH_UTIL_H_ + +#include "../../../../net/base/url_util.h" + +#include "base/strings/string_piece_forward.h" +#include "net/base/net_export.h" + +namespace net { + +NET_EXPORT bool ParseAuthHostAndPort( + base::StringPiece input, + std::string* username, + std::string* password, + std::string* host, + int* port); + +} + +#endif // BRAVE_NET_BASE_URL_AUTH_UTIL_H_ diff --git a/chromium_src/net/log/net_log_event_type_list.h b/chromium_src/net/log/net_log_event_type_list.h new file mode 100644 index 000000000000..eaefd4834fa5 --- /dev/null +++ b/chromium_src/net/log/net_log_event_type_list.h @@ -0,0 +1,11 @@ +// Copyright 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "../../../../net/log/net_log_event_type_list.h" + +// The time spent sending authentication to the SOCKS server +EVENT_TYPE(SOCKS5_AUTH_WRITE) + +// The time spent waiting for the authentication response from the SOCKS server +EVENT_TYPE(SOCKS5_AUTH_READ) diff --git a/chromium_src/net/socket/socks5_client_socket.cc b/chromium_src/net/socket/socks5_client_socket.cc new file mode 100644 index 000000000000..daafad6da40d --- /dev/null +++ b/chromium_src/net/socket/socks5_client_socket.cc @@ -0,0 +1,151 @@ +// Copyright 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "../../../../net/socket/socks5_client_socket.cc" + +#include "net/base/io_buffer.h" +#include "net/socket/socks5_client_socket.h" + +namespace net { + +SOCKS5ClientSocketAuth::SOCKS5ClientSocketAuth( + std::unique_ptr transport_socket, + const HostResolver::RequestInfo& req_info, + const NetworkTrafficAnnotationTag& traffic_annotation, + const HostPortPair& proxy_host_port) + : SOCKS5ClientSocket(std::move(transport_socket), req_info, + traffic_annotation), + proxy_host_port_(proxy_host_port), + next_state_(STATE_INIT_WRITE) { +} + +SOCKS5ClientSocketAuth::~SOCKS5ClientSocketAuth() = default; + +const std::string& SOCKS5ClientSocketAuth::username() { + return proxy_host_port_.username(); +} + +const std::string& SOCKS5ClientSocketAuth::password() { + return proxy_host_port_.password(); +} + +bool SOCKS5ClientSocketAuth::do_auth() { + return username().size() != 0 || password().size() != 0; +} + +uint8_t SOCKS5ClientSocketAuth::auth_method() { + if (!do_auth()) + return 0x00; + return 0x02; +} + +static const size_t kSOCKSAuthUsernamePasswordResponseLen = 2; + +int SOCKS5ClientSocketAuth::Authenticate( + int rv, ClientSocketHandle& transport, NetLogWithSource& net_log, + CompletionCallback& callback) { + if (!do_auth()) { + DCHECK_EQ(OK, rv); + return OK; + } + do { + switch (next_state_) { + case STATE_INIT_WRITE: { + DCHECK_EQ(OK, rv); + // Initialize the buffer with  + // 0x01, usernamelen, username, passwordlen, password + size_t usernamelen = username().size(); + size_t passwordlen = password().size(); + buffer_ = std::string(1 + 1 + usernamelen + 1 + passwordlen, 0); + buffer_[0] = 0x01; + buffer_[1] = usernamelen; + buffer_.replace(2, usernamelen, username()); + buffer_[2 + usernamelen] = passwordlen; + buffer_.replace(2 + usernamelen + 1, passwordlen, password()); + DCHECK_EQ(buffer_.size(), 2 + usernamelen + 1 + passwordlen); + buffer_left_ = buffer_.size(); + next_state_ = STATE_WRITE; + rv = OK; + break; + } + case STATE_WRITE: + DCHECK_EQ(OK, rv); + DCHECK_LT(0u, buffer_left_); + iobuf_ = new IOBuffer(buffer_left_); + memcpy(iobuf_->data(), + &buffer_.data()[buffer_.size() - buffer_left_], + buffer_left_); + next_state_ = STATE_WRITE_COMPLETE; + net_log.BeginEvent(NetLogEventType::SOCKS5_AUTH_WRITE); + rv = transport.socket()->Write(iobuf_.get(), buffer_left_, callback, + traffic_annotation_); + break; + + case STATE_WRITE_COMPLETE: + // TODO(riastradh): Zero iobuf? Zero buffer? + net_log.EndEventWithNetErrorCode(NetLogEventType::SOCKS5_AUTH_WRITE, + std::max(rv, 0)); + if (rv < 0) { + next_state_ = STATE_BAD; + return rv; + } + DCHECK_LE(static_cast(rv), buffer_left_); + buffer_left_ -= rv; + next_state_ = (buffer_left_ == 0 ? STATE_INIT_READ : STATE_WRITE); + rv = OK; + break; + + case STATE_INIT_READ: + DCHECK_EQ(OK, rv); + buffer_.clear(); + buffer_left_ = kSOCKSAuthUsernamePasswordResponseLen; + iobuf_ = new IOBuffer(buffer_left_); + next_state_ = STATE_READ; + rv = OK; + break; + + case STATE_READ: + DCHECK_EQ(OK, rv); + iobuf_ = new IOBuffer(buffer_left_); + next_state_ = STATE_READ_COMPLETE; + net_log.BeginEvent(NetLogEventType::SOCKS5_AUTH_READ); + rv = transport.socket()->Read(iobuf_.get(), buffer_left_, callback); + break; + + case STATE_READ_COMPLETE: + net_log.EndEventWithNetErrorCode(NetLogEventType::SOCKS5_AUTH_READ, + std::max(rv, 0)); + if (rv < 0) { + next_state_ = STATE_BAD; + return rv; + } + DCHECK_LE(static_cast(rv), buffer_left_); + buffer_.append(iobuf_->data(), rv); + buffer_left_ -= rv; + next_state_ = (buffer_left_ == 0 ? STATE_DONE : STATE_READ); + rv = OK; + break; + + case STATE_DONE: { + DCHECK_EQ(OK, rv); + DCHECK_EQ(buffer_.size(), kSOCKSAuthUsernamePasswordResponseLen); + static_assert(kSOCKSAuthUsernamePasswordResponseLen == 2, "bad size"); + uint8_t ver = buffer_[0]; + uint8_t status = buffer_[1]; + next_state_ = STATE_BAD; // Caller had better stop here. + if (ver != 0x01 || status != 0x00) + return ERR_FAILED; + return OK; + } + + case STATE_BAD: + default: + NOTREACHED() << "bad state"; + return ERR_UNEXPECTED; + } + } while (rv != ERR_IO_PENDING); + return rv; +} + +} // namespace net diff --git a/chromium_src/net/socket/socks5_client_socket.h b/chromium_src/net/socket/socks5_client_socket.h new file mode 100644 index 000000000000..b2a6a0b4d3fa --- /dev/null +++ b/chromium_src/net/socket/socks5_client_socket.h @@ -0,0 +1,46 @@ +// Copyright 2018 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BRAVE_NET_SOCKET_SOCKS5_CLIENT_SOCKET_AUTH_H_ +#define BRAVE_NET_SOCKET_SOCKS5_CLIENT_SOCKET_AUTH_H_ + +#include "../../../../net/socket/socks5_client_socket.h" + +namespace net { + +class NET_EXPORT_PRIVATE SOCKS5ClientSocketAuth : public SOCKS5ClientSocket { + public: + SOCKS5ClientSocketAuth(std::unique_ptr transport_socket, + const HostResolver::RequestInfo& req_info, + const NetworkTrafficAnnotationTag& traffic_annotation, + const HostPortPair& proxy_host_port); + ~SOCKS5ClientSocketAuth() override; + private: + bool do_auth(); + const std::string& username(); + const std::string& password(); + uint8_t auth_method() override; + int Authenticate(int rv, + ClientSocketHandle& transport, NetLogWithSource& net_log, + CompletionCallback& callback) override; + const HostPortPair proxy_host_port_; + enum { + STATE_INIT_WRITE = 0, + STATE_WRITE, + STATE_WRITE_COMPLETE, + STATE_INIT_READ, + STATE_READ, + STATE_READ_COMPLETE, + STATE_DONE, + STATE_BAD, + } next_state_; + scoped_refptr iobuf_; + std::string buffer_; + size_t buffer_left_; + DISALLOW_COPY_AND_ASSIGN(SOCKS5ClientSocketAuth); +}; + +} // namespace net + +#endif // BRAVE_NET_SOCKET_SOCKS5_CLIENT_SOCKET_AUTH_H_ diff --git a/patches/net-base-host_port_pair.cc.patch b/patches/net-base-host_port_pair.cc.patch new file mode 100644 index 000000000000..7af13cb02a1e --- /dev/null +++ b/patches/net-base-host_port_pair.cc.patch @@ -0,0 +1,19 @@ +diff --git a/net/base/host_port_pair.cc b/net/base/host_port_pair.cc +index ec8248449dbcd4156e361fcc8781ce0712f26a02..fd8af49cfa6f41c56b7218a71048dd077e072f6e 100644 +--- a/net/base/host_port_pair.cc ++++ b/net/base/host_port_pair.cc +@@ -50,12 +50,14 @@ HostPortPair HostPortPair::FromString(const std::string& str) { + return host_port_pair; + } + ++#if !defined(BRAVE_CHROMIUM_BUILD) + std::string HostPortPair::ToString() const { + std::string ret(HostForURL()); + ret += ':'; + ret += base::UintToString(port_); + return ret; + } ++#endif + + std::string HostPortPair::HostForURL() const { + // TODO(rtenneti): Add support for |host| to have '\0'. diff --git a/patches/net-base-host_port_pair.h.patch b/patches/net-base-host_port_pair.h.patch new file mode 100644 index 000000000000..9210276beafb --- /dev/null +++ b/patches/net-base-host_port_pair.h.patch @@ -0,0 +1,53 @@ +diff --git a/net/base/host_port_pair.h b/net/base/host_port_pair.h +index a5ee6bda3ff542624b484b7a11811b708fec3e11..084616da28ba3569cc75d1b0fef51a0b89a9f54e 100644 +--- a/net/base/host_port_pair.h ++++ b/net/base/host_port_pair.h +@@ -24,6 +24,13 @@ class NET_EXPORT HostPortPair { + // If |in_host| represents an IPv6 address, it should not bracket the address. + HostPortPair(const std::string& in_host, uint16_t in_port); + ++ // Brave addition. Nudges HostPortPair past Chromium's style ++ // threshold for in-line constructors and destructors. ++ HostPortPair(const std::string& username, const std::string& password, ++ const std::string& in_host, uint16_t in_port); ++ ~HostPortPair(); ++ HostPortPair(const HostPortPair&); ++ + // Creates a HostPortPair for the origin of |url|. + static HostPortPair FromURL(const GURL& url); + +@@ -37,18 +44,23 @@ class NET_EXPORT HostPortPair { + // TODO(willchan): Define a functor instead. + // Comparator function so this can be placed in a std::map. + bool operator<(const HostPortPair& other) const { +- return std::tie(port_, host_) < std::tie(other.port_, other.host_); ++ return std::tie(port_, host_, username_, password_) < ++ std::tie(other.port_, other.host_, other.username_, other.password_); + } + + // Equality test of contents. (Probably another violation of style guide). + bool Equals(const HostPortPair& other) const { +- return host_ == other.host_ && port_ == other.port_; ++ return username_ == other.username_ && password_ == other.password_ && ++ host_ == other.host_ && port_ == other.port_; + } + + bool IsEmpty() const { + return host_.empty() && port_ == 0; + } + ++ const std::string& username() const { return username_; } ++ const std::string& password() const { return password_; } ++ + const std::string& host() const { + return host_; + } +@@ -72,6 +84,8 @@ class NET_EXPORT HostPortPair { + size_t EstimateMemoryUsage() const; + + private: ++ std::string username_; ++ std::string password_; + // If |host_| represents an IPv6 address, this string will not contain + // brackets around the address. + std::string host_; diff --git a/patches/net-base-proxy_server.cc.patch b/patches/net-base-proxy_server.cc.patch new file mode 100644 index 000000000000..01630cde231e --- /dev/null +++ b/patches/net-base-proxy_server.cc.patch @@ -0,0 +1,29 @@ +diff --git a/net/base/proxy_server.cc b/net/base/proxy_server.cc +index da31a40fbe8dc454dd24cb368c3af7d0b8c3506d..85f8ee0367f949809e18bd7ec1eab0010975a87d 100644 +--- a/net/base/proxy_server.cc ++++ b/net/base/proxy_server.cc +@@ -223,10 +223,13 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( + HostPortPair host_port_pair; + + if (scheme != SCHEME_INVALID && scheme != SCHEME_DIRECT) { ++ std::string username; ++ std::string password; + std::string host; + int port = -1; + // If the scheme has a host/port, parse it. +- bool ok = ParseHostAndPort(host_and_port, &host, &port); ++ bool ok = ParseAuthHostAndPort(host_and_port, &username, &password, ++ &host, &port); + if (!ok) + return ProxyServer(); // Invalid -- failed parsing [":"] + +@@ -234,7 +237,8 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( + if (port == -1) + port = GetDefaultPortForScheme(scheme); + +- host_port_pair = HostPortPair(host, static_cast(port)); ++ host_port_pair = HostPortPair(username, password, host, ++ static_cast(port)); + } + + return ProxyServer(scheme, host_port_pair); diff --git a/patches/net-socket-socks5_client_socket.cc.patch b/patches/net-socket-socks5_client_socket.cc.patch new file mode 100644 index 000000000000..4845082df890 --- /dev/null +++ b/patches/net-socket-socks5_client_socket.cc.patch @@ -0,0 +1,73 @@ +diff --git a/net/socket/socks5_client_socket.cc b/net/socket/socks5_client_socket.cc +index 784bcef533288d1eced7daa5b470b8d99550cd98..490766ba173a5f15f618a8fcdd0de8bfa8c5328d 100644 +--- a/net/socket/socks5_client_socket.cc ++++ b/net/socket/socks5_client_socket.cc +@@ -241,6 +241,9 @@ int SOCKS5ClientSocket::DoLoop(int last_io_result) { + net_log_.EndEventWithNetErrorCode(NetLogEventType::SOCKS5_GREET_READ, + rv); + break; ++ case STATE_AUTH: ++ rv = DoAuth(rv); ++ break; + case STATE_HANDSHAKE_WRITE: + DCHECK_EQ(OK, rv); + net_log_.BeginEvent(NetLogEventType::SOCKS5_HANDSHAKE_WRITE); +@@ -270,8 +273,6 @@ int SOCKS5ClientSocket::DoLoop(int last_io_result) { + return rv; + } + +-const char kSOCKS5GreetWriteData[] = { 0x05, 0x01, 0x00 }; // no authentication +- + int SOCKS5ClientSocket::DoGreetWrite() { + // Since we only have 1 byte to send the hostname length in, if the + // URL has a hostname longer than 255 characters we can't send it. +@@ -281,8 +282,12 @@ int SOCKS5ClientSocket::DoGreetWrite() { + } + + if (buffer_.empty()) { +- buffer_ = std::string(kSOCKS5GreetWriteData, +- arraysize(kSOCKS5GreetWriteData)); ++ const char greeting[] = { ++ 0x05, // SOCKS version ++ 0x01, // number of authentication methods ++ auth_method(), ++ }; ++ buffer_ = std::string(greeting, sizeof(greeting)); + bytes_sent_ = 0; + } + +@@ -341,14 +346,32 @@ int SOCKS5ClientSocket::DoGreetReadComplete(int result) { + NetLog::IntCallback("version", buffer_[0])); + return ERR_SOCKS_CONNECTION_FAILED; + } +- if (buffer_[1] != 0x00) { ++ if (buffer_[1] != auth_method()) { + net_log_.AddEvent(NetLogEventType::SOCKS_UNEXPECTED_AUTH, + NetLog::IntCallback("method", buffer_[1])); + return ERR_SOCKS_CONNECTION_FAILED; + } + + buffer_.clear(); +- next_state_ = STATE_HANDSHAKE_WRITE; ++ next_state_ = STATE_AUTH; ++ return OK; ++} ++ ++int SOCKS5ClientSocket::DoAuth(int rv) { ++ rv = Authenticate(rv, *transport_, net_log_, io_callback_); ++ next_state_ = (rv == OK ? STATE_HANDSHAKE_WRITE : STATE_AUTH); ++ return rv; ++} ++ ++uint8_t SOCKS5ClientSocket::auth_method() { ++ return 0x00; ++} ++ ++int SOCKS5ClientSocket::Authenticate(int rv, ++ ClientSocketHandle& socket, ++ NetLogWithSource& net_log, ++ CompletionCallback& callback) { ++ DCHECK_EQ(OK, rv); + return OK; + } + diff --git a/patches/net-socket-socks5_client_socket.h.patch b/patches/net-socket-socks5_client_socket.h.patch new file mode 100644 index 000000000000..7a903ecdfbc2 --- /dev/null +++ b/patches/net-socket-socks5_client_socket.h.patch @@ -0,0 +1,42 @@ +diff --git a/net/socket/socks5_client_socket.h b/net/socket/socks5_client_socket.h +index b6e59ae6b07823087e44ffc40fb7d2d54c6a7c3e..98ee500609b2a72970387324a09da102b7230c14 100644 +--- a/net/socket/socks5_client_socket.h ++++ b/net/socket/socks5_client_socket.h +@@ -20,6 +20,7 @@ + #include "net/base/net_export.h" + #include "net/dns/host_resolver.h" + #include "net/log/net_log_with_source.h" ++#include "net/socket/socks_client_socket_pool.h" + #include "net/socket/stream_socket.h" + #include "net/traffic_annotation/network_traffic_annotation.h" + #include "url/gurl.h" +@@ -79,11 +80,14 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { + int GetLocalAddress(IPEndPoint* address) const override; + + private: ++ friend class SOCKS5ClientSocketAuth; + enum State { + STATE_GREET_WRITE, + STATE_GREET_WRITE_COMPLETE, + STATE_GREET_READ, + STATE_GREET_READ_COMPLETE, ++ STATE_AUTH, ++ STATE_AUTH_COMPLETE, + STATE_HANDSHAKE_WRITE, + STATE_HANDSHAKE_WRITE_COMPLETE, + STATE_HANDSHAKE_READ, +@@ -118,6 +122,14 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { + int DoGreetReadComplete(int result); + int DoGreetWrite(); + int DoGreetWriteComplete(int result); ++ int DoAuth(int result); ++ ++ // Authentication hooks. ++ virtual uint8_t auth_method(); ++ virtual int Authenticate(int result, ++ ClientSocketHandle& socket, ++ NetLogWithSource& net_log, ++ CompletionCallback& callback); + + // Writes the SOCKS handshake buffer into |handshake| + // and return OK on success. diff --git a/patches/net-socket-socks_client_socket_pool.cc.patch b/patches/net-socket-socks_client_socket_pool.cc.patch new file mode 100644 index 000000000000..e0fe131d6c20 --- /dev/null +++ b/patches/net-socket-socks_client_socket_pool.cc.patch @@ -0,0 +1,19 @@ +diff --git a/net/socket/socks_client_socket_pool.cc b/net/socket/socks_client_socket_pool.cc +index 2dad2733466a194da7898919604ebf4dcb463d74..c00c43c8febf0d78ca14e479cfe4f9af14146cb7 100644 +--- a/net/socket/socks_client_socket_pool.cc ++++ b/net/socket/socks_client_socket_pool.cc +@@ -149,9 +149,11 @@ int SOCKSConnectJob::DoSOCKSConnect() { + + // Add a SOCKS connection on top of the tcp socket. + if (socks_params_->is_socks_v5()) { +- socket_.reset(new SOCKS5ClientSocket(std::move(transport_socket_handle_), +- socks_params_->destination(), +- socks_params_->traffic_annotation())); ++ socket_.reset(new SOCKS5ClientSocketAuth( ++ std::move(transport_socket_handle_), ++ socks_params_->destination(), ++ socks_params_->traffic_annotation(), ++ socks_params_->transport_params()->destination().host_port_pair())); + } else { + socket_.reset(new SOCKSClientSocket( + std::move(transport_socket_handle_), socks_params_->destination(),