Commit b52e5772 authored by Matt Menke's avatar Matt Menke Committed by Commit Bot

Add TCPConnectedSocket methods to configure buffer sizes.

Also add a TCPConnectedSocketOptions structure to sent options on
socket construction, as it makes state management and error handling
in consumers simpler if they want to set multiple options when creating
a socket.

BUG=848078
TBR=mfoltz@chromium.org

Cq-Include-Trybots: luci.chromium.try:linux_mojo
Change-Id: I2177b907b2a1d75212e27505f8366c608457e2b8
Reviewed-on: https://chromium-review.googlesource.com/1204852
Commit-Queue: Matt Menke <mmenke@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarMaks Orlovich <morlovich@chromium.org>
Cr-Commit-Position: refs/heads/master@{#592515}
parent 1fa87f75
...@@ -77,6 +77,7 @@ void ConnectOnUIThread( ...@@ -77,6 +77,7 @@ void ConnectOnUIThread(
network::mojom::NetworkContext::CreateTCPConnectedSocketCallback callback) { network::mojom::NetworkContext::CreateTCPConnectedSocketCallback callback) {
network_context_getter.Run()->CreateTCPConnectedSocket( network_context_getter.Run()->CreateTCPConnectedSocket(
base::nullopt /* local_addr */, remote_address_list, base::nullopt /* local_addr */, remote_address_list,
nullptr /* tcp_connected_socket_options */,
net::MutableNetworkTrafficAnnotationTag( net::MutableNetworkTrafficAnnotationTag(
CastSocketImpl::GetNetworkTrafficAnnotationTag()), CastSocketImpl::GetNetworkTrafficAnnotationTag()),
std::move(request), nullptr /* observer */, std::move(request), nullptr /* observer */,
......
...@@ -333,7 +333,7 @@ void TCPSocket::ConnectOnUIThread( ...@@ -333,7 +333,7 @@ void TCPSocket::ConnectOnUIThread(
content::BrowserContext::GetDefaultStoragePartition(browser_context); content::BrowserContext::GetDefaultStoragePartition(browser_context);
} }
storage_partition->GetNetworkContext()->CreateTCPConnectedSocket( storage_partition->GetNetworkContext()->CreateTCPConnectedSocket(
base::nullopt, remote_addr_list, base::nullopt, remote_addr_list, nullptr /* options */,
net::MutableNetworkTrafficAnnotationTag( net::MutableNetworkTrafficAnnotationTag(
Socket::GetNetworkTrafficAnnotationTag()), Socket::GetNetworkTrafficAnnotationTag()),
std::move(request), nullptr /* observer */, std::move(request), nullptr /* observer */,
......
...@@ -169,7 +169,7 @@ void SocketDataProvider::DetachSocket() { ...@@ -169,7 +169,7 @@ void SocketDataProvider::DetachSocket() {
socket_ = nullptr; socket_ = nullptr;
} }
SocketDataProvider::SocketDataProvider() : socket_(nullptr) {} SocketDataProvider::SocketDataProvider() {}
SocketDataProvider::~SocketDataProvider() { SocketDataProvider::~SocketDataProvider() {
if (socket_) if (socket_)
...@@ -1004,6 +1004,34 @@ int MockTCPClientSocket::Write( ...@@ -1004,6 +1004,34 @@ int MockTCPClientSocket::Write(
return write_result.result; return write_result.result;
} }
int MockTCPClientSocket::SetReceiveBufferSize(int32_t size) {
if (!connected_)
return net::ERR_UNEXPECTED;
data_->set_receive_buffer_size(size);
return data_->set_receive_buffer_size_result();
}
int MockTCPClientSocket::SetSendBufferSize(int32_t size) {
if (!connected_)
return net::ERR_UNEXPECTED;
data_->set_send_buffer_size(size);
return data_->set_send_buffer_size_result();
}
bool MockTCPClientSocket::SetNoDelay(bool no_delay) {
if (!connected_)
return false;
data_->set_no_delay(no_delay);
return data_->set_no_delay_result();
}
bool MockTCPClientSocket::SetKeepAlive(bool enable, int delay) {
if (!connected_)
return false;
data_->set_keep_alive(enable, delay);
return data_->set_keep_alive_result();
}
void MockTCPClientSocket::GetConnectionAttempts(ConnectionAttempts* out) const { void MockTCPClientSocket::GetConnectionAttempts(ConnectionAttempts* out) const {
*out = connection_attempts_; *out = connection_attempts_;
} }
...@@ -1018,13 +1046,34 @@ void MockTCPClientSocket::AddConnectionAttempts( ...@@ -1018,13 +1046,34 @@ void MockTCPClientSocket::AddConnectionAttempts(
attempts.end()); attempts.end());
} }
void MockTCPClientSocket::SetBeforeConnectCallback(
const BeforeConnectCallback& before_connect_callback) {
DCHECK(!before_connect_callback_);
DCHECK(!connected_);
before_connect_callback_ = before_connect_callback;
}
int MockTCPClientSocket::Connect(CompletionOnceCallback callback) { int MockTCPClientSocket::Connect(CompletionOnceCallback callback) {
if (!data_) if (!data_)
return ERR_UNEXPECTED; return ERR_UNEXPECTED;
if (connected_) if (connected_)
return OK; return OK;
// Setting socket options fails if not connected, so need to set this before
// calling |before_connect_callback_|.
connected_ = true; connected_ = true;
if (before_connect_callback_) {
int result = before_connect_callback_.Run();
DCHECK_NE(result, ERR_IO_PENDING);
if (result != net::OK) {
connected_ = false;
return result;
}
}
peer_closed_connection_ = false; peer_closed_connection_ = false;
int result = data_->connect_data().result; int result = data_->connect_data().result;
......
...@@ -225,6 +225,59 @@ class SocketDataProvider { ...@@ -225,6 +225,59 @@ class SocketDataProvider {
virtual void OnEnableTCPFastOpenIfSupported(); virtual void OnEnableTCPFastOpenIfSupported();
// Returns the last set receive buffer size, or -1 if never set.
int receive_buffer_size() const { return receive_buffer_size_; }
void set_receive_buffer_size(int receive_buffer_size) {
receive_buffer_size_ = receive_buffer_size;
}
// Returns the last set send buffer size, or -1 if never set.
int send_buffer_size() const { return send_buffer_size_; }
void set_send_buffer_size(int send_buffer_size) {
send_buffer_size_ = send_buffer_size;
}
// Returns the last set value of TCP no delay, or false if never set.
bool no_delay() const { return no_delay_; }
void set_no_delay(bool no_delay) { no_delay_ = no_delay; }
// Returns whether TCP keepalives were enabled or not. Returns 0 by default,
// which may not match the default behavior on all platforms.
bool keep_alive_enabled() const { return keep_alive_enabled_; }
// Last set TCP keepalive delay.
int keep_alive_delay() const { return keep_alive_delay_; }
void set_keep_alive(bool enable, int delay) {
keep_alive_enabled_ = enable;
keep_alive_delay_ = delay;
}
// Setters / getters for the return values of the corresponding Set*()
// methods. By default, they all succeed, if the socket is connected.
void set_set_receive_buffer_size_result(int receive_buffer_size_result) {
set_receive_buffer_size_result_ = receive_buffer_size_result;
}
int set_receive_buffer_size_result() const {
return set_receive_buffer_size_result_;
}
void set_set_send_buffer_size_result(int set_send_buffer_size_result) {
set_send_buffer_size_result_ = set_send_buffer_size_result;
}
int set_send_buffer_size_result() const {
return set_send_buffer_size_result_;
}
void set_set_no_delay_result(bool set_no_delay_result) {
set_no_delay_result_ = set_no_delay_result;
}
bool set_no_delay_result() const { return set_no_delay_result_; }
void set_set_keep_alive_result(bool set_keep_alive_result) {
set_keep_alive_result_ = set_keep_alive_result;
}
bool set_keep_alive_result() const { return set_keep_alive_result_; }
// Returns true if the request should be considered idle, for the purposes of // Returns true if the request should be considered idle, for the purposes of
// IsConnectedAndIdle. // IsConnectedAndIdle.
virtual bool IsIdle() const; virtual bool IsIdle() const;
...@@ -249,7 +302,20 @@ class SocketDataProvider { ...@@ -249,7 +302,20 @@ class SocketDataProvider {
virtual void Reset() = 0; virtual void Reset() = 0;
MockConnect connect_; MockConnect connect_;
AsyncSocket* socket_; AsyncSocket* socket_ = nullptr;
int receive_buffer_size_ = -1;
int send_buffer_size_ = -1;
// This reflects the default state of TCPClientSockets.
bool no_delay_ = true;
// Default varies by platform. Just pretend it's disabled.
bool keep_alive_enabled_ = false;
int keep_alive_delay_ = 0;
int set_receive_buffer_size_result_ = net::OK;
int set_send_buffer_size_result_ = net::OK;
bool set_no_delay_result_ = true;
bool set_keep_alive_result_ = true;
DISALLOW_COPY_AND_ASSIGN(SocketDataProvider); DISALLOW_COPY_AND_ASSIGN(SocketDataProvider);
}; };
...@@ -676,8 +742,16 @@ class MockTCPClientSocket : public MockClientSocket, public AsyncSocket { ...@@ -676,8 +742,16 @@ class MockTCPClientSocket : public MockClientSocket, public AsyncSocket {
int buf_len, int buf_len,
CompletionOnceCallback callback, CompletionOnceCallback callback,
const NetworkTrafficAnnotationTag& traffic_annotation) override; const NetworkTrafficAnnotationTag& traffic_annotation) override;
int SetReceiveBufferSize(int32_t size) override;
int SetSendBufferSize(int32_t size) override;
// TransportClientSocket implementation.
bool SetNoDelay(bool no_delay) override;
bool SetKeepAlive(bool enable, int delay) override;
// StreamSocket implementation. // StreamSocket implementation.
void SetBeforeConnectCallback(
const BeforeConnectCallback& before_connect_callback) override;
int Connect(CompletionOnceCallback callback) override; int Connect(CompletionOnceCallback callback) override;
void Disconnect() override; void Disconnect() override;
bool IsConnected() const override; bool IsConnected() const override;
...@@ -737,6 +811,8 @@ class MockTCPClientSocket : public MockClientSocket, public AsyncSocket { ...@@ -737,6 +811,8 @@ class MockTCPClientSocket : public MockClientSocket, public AsyncSocket {
// ERR_READ_IF_READY_NOT_IMPLEMENTED. // ERR_READ_IF_READY_NOT_IMPLEMENTED.
bool enable_read_if_ready_; bool enable_read_if_ready_;
BeforeConnectCallback before_connect_callback_;
ConnectionAttempts connection_attempts_; ConnectionAttempts connection_attempts_;
DISALLOW_COPY_AND_ASSIGN(MockTCPClientSocket); DISALLOW_COPY_AND_ASSIGN(MockTCPClientSocket);
......
...@@ -811,12 +811,13 @@ void NetworkContext::CreateTCPServerSocket( ...@@ -811,12 +811,13 @@ void NetworkContext::CreateTCPServerSocket(
void NetworkContext::CreateTCPConnectedSocket( void NetworkContext::CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr, const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list, const net::AddressList& remote_addr_list,
mojom::TCPConnectedSocketOptionsPtr tcp_connected_socket_options,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest request, mojom::TCPConnectedSocketRequest request,
mojom::SocketObserverPtr observer, mojom::SocketObserverPtr observer,
CreateTCPConnectedSocketCallback callback) { CreateTCPConnectedSocketCallback callback) {
socket_factory_->CreateTCPConnectedSocket( socket_factory_->CreateTCPConnectedSocket(
local_addr, remote_addr_list, local_addr, remote_addr_list, std::move(tcp_connected_socket_options),
static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation), static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation),
std::move(request), std::move(observer), std::move(callback)); std::move(request), std::move(observer), std::move(callback));
} }
......
...@@ -197,6 +197,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext ...@@ -197,6 +197,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
void CreateTCPConnectedSocket( void CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr, const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list, const net::AddressList& remote_addr_list,
mojom::TCPConnectedSocketOptionsPtr tcp_connected_socket_options,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest request, mojom::TCPConnectedSocketRequest request,
mojom::SocketObserverPtr observer, mojom::SocketObserverPtr observer,
......
...@@ -49,9 +49,10 @@ class TestHttpClient { ...@@ -49,9 +49,10 @@ class TestHttpClient {
base::RunLoop run_loop; base::RunLoop run_loop;
int net_error = net::ERR_FAILED; int net_error = net::ERR_FAILED;
factory_.CreateTCPConnectedSocket( factory_.CreateTCPConnectedSocket(
base::nullopt, /* local address */ base::nullopt /* local address */, addresses,
addresses, TRAFFIC_ANNOTATION_FOR_TESTS, mojo::MakeRequest(&socket_), nullptr /* tcp_connected_socket_options */,
nullptr, /* observer */ TRAFFIC_ANNOTATION_FOR_TESTS, mojo::MakeRequest(&socket_),
nullptr /* observer */,
base::BindOnce( base::BindOnce(
[](base::RunLoop* run_loop, int* result_out, [](base::RunLoop* run_loop, int* result_out,
mojo::ScopedDataPipeConsumerHandle* receive_pipe_handle_out, mojo::ScopedDataPipeConsumerHandle* receive_pipe_handle_out,
......
...@@ -509,6 +509,7 @@ interface NetworkContext { ...@@ -509,6 +509,7 @@ interface NetworkContext {
CreateTCPConnectedSocket( CreateTCPConnectedSocket(
net.interfaces.IPEndPoint? local_addr, net.interfaces.IPEndPoint? local_addr,
net.interfaces.AddressList remote_addr_list, net.interfaces.AddressList remote_addr_list,
TCPConnectedSocketOptions? tcp_connected_socket_options,
MutableNetworkTrafficAnnotationTag traffic_annotation, MutableNetworkTrafficAnnotationTag traffic_annotation,
TCPConnectedSocket& socket, TCPConnectedSocket& socket,
SocketObserver? observer) SocketObserver? observer)
......
...@@ -11,6 +11,26 @@ import "services/network/public/mojom/tls_socket.mojom"; ...@@ -11,6 +11,26 @@ import "services/network/public/mojom/tls_socket.mojom";
import "services/network/public/mojom/network_param.mojom"; import "services/network/public/mojom/network_param.mojom";
import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom"; import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom";
struct TCPConnectedSocketOptions {
// Sets the OS send buffer size (in bytes) for the socket. This is the
// SO_SNDBUF socket option. If 0, the default size is used. The value will
// be clamped to a reasonable range.
int32 send_buffer_size = 0;
// Sets the OS receive buffer size (in bytes) for the socket. This is the
// SO_RCVBUF socket option. If 0, the default size is used. The value will
// be clamped to a reasonable range.
int32 receive_buffer_size = 0;
// This function enables/disables buffering in the kernel. By default, on
// Linux, TCP sockets will wait up to 200ms for more data to complete a packet
// before transmitting. The network service, however, overrides the default
// setting all socket, so the kernel will not wait unless this is set to
// false. See TCP_NODELAY in `man 7 tcp`. On Windows, the Nagle implementation
// is governed by RFC 896.
bool no_delay = true;
};
// Represents a bound TCP socket. Once a call succeeds, cannot be reused. // Represents a bound TCP socket. Once a call succeeds, cannot be reused.
interface TCPBoundSocket { interface TCPBoundSocket {
// Starts listening on the socket. |net_error| is set to net::OK on success, // Starts listening on the socket. |net_error| is set to net::OK on success,
...@@ -68,13 +88,21 @@ interface TCPConnectedSocket { ...@@ -68,13 +88,21 @@ interface TCPConnectedSocket {
// the platform. Consumers do not need to set these themselves unless they // the platform. Consumers do not need to set these themselves unless they
// want to change the default settings. // want to change the default settings.
// This function enables/disables buffering in the kernel. By default, on // These set the send / receive buffer sizes on the connected socket. See the
// Linux, TCP sockets will wait up to 200ms for more data to complete a packet // corresponding values in TCPConnectedSocketOptions for descriptions,
// before transmitting. After calling this function, the kernel will not wait. // though note that passing in "0" here will set the size to the minimum
// See TCP_NODELAY in `man 7 tcp`. On Windows, the Nagle implementation is // value, instead of restoring the default. Consumers should prefer setting
// governed by RFC 896. SetTCPNoDelay() sets the TCP_NODELAY option. Use // these values on creation, as some platforms may not respect changes to
// |no_delay| to enable or disable it. // these values on a connected socket, even if the method succeeds. These are
// Returns whether the operation is successful. // present mostly for legacy consumers that expose the behavior to
// non-Chrome code.
// A network error code is returned on completion.
SetSendBufferSize(int32 send_buffer_size) => (int32 net_error);
SetReceiveBufferSize(int32 receive_buffer_size) => (int32 net_error);
// Enables / disables TCP_NODELAY on the connected socket. See
// TCPConnectedSocketOptions::no_delay for more details.
// Returns whether the operation was successful.
SetNoDelay(bool no_delay) => (bool success); SetNoDelay(bool no_delay) => (bool success);
// Enables or disables TCP Keep-Alive. This sets SO_KEEPALIVE on the socket. // Enables or disables TCP Keep-Alive. This sets SO_KEEPALIVE on the socket.
...@@ -110,6 +138,9 @@ interface TCPServerSocket { ...@@ -110,6 +138,9 @@ interface TCPServerSocket {
// |backlog| is a number that is specified when requesting TCPServerSocket. If // |backlog| is a number that is specified when requesting TCPServerSocket. If
// more than |backlog| number of Accept()s are outstanding, // more than |backlog| number of Accept()s are outstanding,
// net::ERR_INSUFFICIENT_RESOUCES will be returned. // net::ERR_INSUFFICIENT_RESOUCES will be returned.
//
// Accepted sockets may not be upgraded to TLS by invoking UpgradeToTLS, as
// UpgradeToTLS only supports the client part of the TLS handshake.
Accept(SocketObserver? observer) Accept(SocketObserver? observer)
=> (int32 net_error, => (int32 net_error,
net.interfaces.IPEndPoint? remote_addr, net.interfaces.IPEndPoint? remote_addr,
......
...@@ -70,6 +70,7 @@ void SocketFactory::CreateTCPServerSocket( ...@@ -70,6 +70,7 @@ void SocketFactory::CreateTCPServerSocket(
void SocketFactory::CreateTCPConnectedSocket( void SocketFactory::CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr, const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list, const net::AddressList& remote_addr_list,
mojom::TCPConnectedSocketOptionsPtr tcp_connected_socket_options,
const net::NetworkTrafficAnnotationTag& traffic_annotation, const net::NetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest request, mojom::TCPConnectedSocketRequest request,
mojom::SocketObserverPtr observer, mojom::SocketObserverPtr observer,
...@@ -80,7 +81,9 @@ void SocketFactory::CreateTCPConnectedSocket( ...@@ -80,7 +81,9 @@ void SocketFactory::CreateTCPConnectedSocket(
TCPConnectedSocket* socket_raw = socket.get(); TCPConnectedSocket* socket_raw = socket.get();
tcp_connected_socket_bindings_.AddBinding(std::move(socket), tcp_connected_socket_bindings_.AddBinding(std::move(socket),
std::move(request)); std::move(request));
socket_raw->Connect(local_addr, remote_addr_list, std::move(callback)); socket_raw->Connect(local_addr, remote_addr_list,
std::move(tcp_connected_socket_options),
std::move(callback));
} }
void SocketFactory::CreateTCPBoundSocket( void SocketFactory::CreateTCPBoundSocket(
......
...@@ -53,6 +53,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) SocketFactory ...@@ -53,6 +53,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) SocketFactory
void CreateTCPConnectedSocket( void CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr, const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list, const net::AddressList& remote_addr_list,
mojom::TCPConnectedSocketOptionsPtr tcp_connected_socket_options,
const net::NetworkTrafficAnnotationTag& traffic_annotation, const net::NetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest request, mojom::TCPConnectedSocketRequest request,
mojom::SocketObserverPtr observer, mojom::SocketObserverPtr observer,
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <utility> #include <utility>
#include "base/logging.h" #include "base/logging.h"
#include "base/numerics/ranges.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
#include "base/optional.h" #include "base/optional.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
...@@ -17,6 +18,52 @@ ...@@ -17,6 +18,52 @@
namespace network { namespace network {
namespace {
int ClampBufferSize(int requested_buffer_size) {
return base::ClampToRange(requested_buffer_size, 0,
TCPConnectedSocket::kMaxBufferSize);
}
// Sets the initial options on a fresh socket. Assumes |socket| is currently
// configured using the default client socket options
// (TCPSocket::SetDefaultOptionsForClient()).
int ConfigureSocket(
net::TransportClientSocket* socket,
const mojom::TCPConnectedSocketOptions& tcp_connected_socket_options) {
int send_buffer_size =
ClampBufferSize(tcp_connected_socket_options.send_buffer_size);
if (send_buffer_size > 0) {
int result = socket->SetSendBufferSize(send_buffer_size);
DCHECK_NE(net::ERR_IO_PENDING, result);
if (result != net::OK)
return result;
}
int receive_buffer_size =
ClampBufferSize(tcp_connected_socket_options.receive_buffer_size);
if (receive_buffer_size > 0) {
int result = socket->SetReceiveBufferSize(receive_buffer_size);
DCHECK_NE(net::ERR_IO_PENDING, result);
if (result != net::OK)
return result;
}
// No delay is set by default, so only update the setting if it's false.
if (!tcp_connected_socket_options.no_delay) {
// Unlike the above calls, TcpSocket::SetNoDelay() returns a bool rather
// than a network error code.
if (!socket->SetNoDelay(false))
return net::ERR_FAILED;
}
return net::OK;
}
} // namespace
const int TCPConnectedSocket::kMaxBufferSize = 128 * 1024;
TCPConnectedSocket::TCPConnectedSocket( TCPConnectedSocket::TCPConnectedSocket(
mojom::SocketObserverPtr observer, mojom::SocketObserverPtr observer,
net::NetLog* net_log, net::NetLog* net_log,
...@@ -60,24 +107,32 @@ TCPConnectedSocket::~TCPConnectedSocket() { ...@@ -60,24 +107,32 @@ TCPConnectedSocket::~TCPConnectedSocket() {
void TCPConnectedSocket::Connect( void TCPConnectedSocket::Connect(
const base::Optional<net::IPEndPoint>& local_addr, const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list, const net::AddressList& remote_addr_list,
mojom::TCPConnectedSocketOptionsPtr tcp_connected_socket_options,
mojom::NetworkContext::CreateTCPConnectedSocketCallback callback) { mojom::NetworkContext::CreateTCPConnectedSocketCallback callback) {
DCHECK(!socket_); DCHECK(!socket_);
DCHECK(callback); DCHECK(callback);
auto socket = client_socket_factory_->CreateTransportClientSocket( socket_ = client_socket_factory_->CreateTransportClientSocket(
remote_addr_list, nullptr /*socket_performance_watcher*/, net_log_, remote_addr_list, nullptr /*socket_performance_watcher*/, net_log_,
net::NetLogSource()); net::NetLogSource());
connect_callback_ = std::move(callback); connect_callback_ = std::move(callback);
int result = net::OK; int result = net::OK;
if (local_addr) if (local_addr)
result = socket->Bind(local_addr.value()); result = socket_->Bind(local_addr.value());
if (result == net::OK) { if (result == net::OK) {
result = socket->Connect(base::BindRepeating( if (tcp_connected_socket_options) {
socket_->SetBeforeConnectCallback(base::BindRepeating(
&ConfigureSocket, socket_.get(), *tcp_connected_socket_options));
}
result = socket_->Connect(base::BindRepeating(
&TCPConnectedSocket::OnConnectCompleted, base::Unretained(this))); &TCPConnectedSocket::OnConnectCompleted, base::Unretained(this)));
} }
socket_ = std::move(socket);
if (result == net::ERR_IO_PENDING) if (result == net::ERR_IO_PENDING)
return; return;
OnConnectCompleted(result); OnConnectCompleted(result);
} }
...@@ -88,6 +143,11 @@ void TCPConnectedSocket::UpgradeToTLS( ...@@ -88,6 +143,11 @@ void TCPConnectedSocket::UpgradeToTLS(
mojom::TLSClientSocketRequest request, mojom::TLSClientSocketRequest request,
mojom::SocketObserverPtr observer, mojom::SocketObserverPtr observer,
mojom::TCPConnectedSocket::UpgradeToTLSCallback callback) { mojom::TCPConnectedSocket::UpgradeToTLSCallback callback) {
if (!tls_socket_factory_) {
std::move(callback).Run(
net::ERR_NOT_IMPLEMENTED, mojo::ScopedDataPipeConsumerHandle(),
mojo::ScopedDataPipeProducerHandle(), base::nullopt /* ssl_info*/);
}
// Wait for data pipes to be closed by the client before doing the upgrade. // Wait for data pipes to be closed by the client before doing the upgrade.
if (socket_data_pump_) { if (socket_data_pump_) {
pending_upgrade_to_tls_callback_ = base::BindOnce( pending_upgrade_to_tls_callback_ = base::BindOnce(
...@@ -101,6 +161,29 @@ void TCPConnectedSocket::UpgradeToTLS( ...@@ -101,6 +161,29 @@ void TCPConnectedSocket::UpgradeToTLS(
std::move(request), std::move(observer), std::move(callback)); std::move(request), std::move(observer), std::move(callback));
} }
void TCPConnectedSocket::SetSendBufferSize(int send_buffer_size,
SetSendBufferSizeCallback callback) {
if (!socket_) {
// Fail is this method was called after upgrading to TLS.
std::move(callback).Run(net::ERR_UNEXPECTED);
return;
}
int result = socket_->SetSendBufferSize(ClampBufferSize(send_buffer_size));
std::move(callback).Run(result);
}
void TCPConnectedSocket::SetReceiveBufferSize(
int send_buffer_size,
SetSendBufferSizeCallback callback) {
if (!socket_) {
// Fail is this method was called after upgrading to TLS.
std::move(callback).Run(net::ERR_UNEXPECTED);
return;
}
int result = socket_->SetReceiveBufferSize(ClampBufferSize(send_buffer_size));
std::move(callback).Run(result);
}
void TCPConnectedSocket::SetNoDelay(bool no_delay, void TCPConnectedSocket::SetNoDelay(bool no_delay,
SetNoDelayCallback callback) { SetNoDelayCallback callback) {
if (!socket_) { if (!socket_) {
......
...@@ -36,6 +36,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) TCPConnectedSocket ...@@ -36,6 +36,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) TCPConnectedSocket
public SocketDataPump::Delegate, public SocketDataPump::Delegate,
public TLSSocketFactory::Delegate { public TLSSocketFactory::Delegate {
public: public:
// Max send/receive buffer size the consumer is allowed to set. Exposed for
// testing.
static const int kMaxBufferSize;
TCPConnectedSocket( TCPConnectedSocket(
mojom::SocketObserverPtr observer, mojom::SocketObserverPtr observer,
net::NetLog* net_log, net::NetLog* net_log,
...@@ -49,9 +53,11 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) TCPConnectedSocket ...@@ -49,9 +53,11 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) TCPConnectedSocket
mojo::ScopedDataPipeConsumerHandle send_pipe_handle, mojo::ScopedDataPipeConsumerHandle send_pipe_handle,
const net::NetworkTrafficAnnotationTag& traffic_annotation); const net::NetworkTrafficAnnotationTag& traffic_annotation);
~TCPConnectedSocket() override; ~TCPConnectedSocket() override;
void Connect( void Connect(
const base::Optional<net::IPEndPoint>& local_addr, const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list, const net::AddressList& remote_addr_list,
mojom::TCPConnectedSocketOptionsPtr tcp_connected_socket_options,
mojom::NetworkContext::CreateTCPConnectedSocketCallback callback); mojom::NetworkContext::CreateTCPConnectedSocketCallback callback);
// mojom::TCPConnectedSocket implementation. // mojom::TCPConnectedSocket implementation.
...@@ -62,6 +68,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) TCPConnectedSocket ...@@ -62,6 +68,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) TCPConnectedSocket
mojom::TLSClientSocketRequest request, mojom::TLSClientSocketRequest request,
mojom::SocketObserverPtr observer, mojom::SocketObserverPtr observer,
mojom::TCPConnectedSocket::UpgradeToTLSCallback callback) override; mojom::TCPConnectedSocket::UpgradeToTLSCallback callback) override;
void SetSendBufferSize(int send_buffer_size,
SetSendBufferSizeCallback callback) override;
void SetReceiveBufferSize(int send_buffer_size,
SetSendBufferSizeCallback callback) override;
void SetNoDelay(bool no_delay, SetNoDelayCallback callback) override; void SetNoDelay(bool no_delay, SetNoDelayCallback callback) override;
void SetKeepAlive(bool enable, void SetKeepAlive(bool enable,
int32_t delay_secs, int32_t delay_secs,
......
This diff is collapsed.
...@@ -91,6 +91,7 @@ class TestNetworkContext : public mojom::NetworkContext { ...@@ -91,6 +91,7 @@ class TestNetworkContext : public mojom::NetworkContext {
void CreateTCPConnectedSocket( void CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr, const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list, const net::AddressList& remote_addr_list,
mojom::TCPConnectedSocketOptionsPtr tcp_connected_socket_options,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest socket, mojom::TCPConnectedSocketRequest socket,
mojom::SocketObserverPtr observer, mojom::SocketObserverPtr observer,
......
...@@ -141,6 +141,7 @@ class TLSClientSocketTestBase { ...@@ -141,6 +141,7 @@ class TLSClientSocketTestBase {
int net_error = net::ERR_FAILED; int net_error = net::ERR_FAILED;
factory_->CreateTCPConnectedSocket( factory_->CreateTCPConnectedSocket(
base::nullopt /* local_addr */, remote_addr_list, base::nullopt /* local_addr */, remote_addr_list,
nullptr /* tcp_connected_socket_options */,
TRAFFIC_ANNOTATION_FOR_TESTS, std::move(request), TRAFFIC_ANNOTATION_FOR_TESTS, std::move(request),
pre_tls_observer()->GetObserverPtr(), pre_tls_observer()->GetObserverPtr(),
base::BindLambdaForTesting( base::BindLambdaForTesting(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment