Commit 32c4f747 authored by Trent Apted's avatar Trent Apted Committed by Commit Bot

Revert "Add TCP socket API to network service"

This reverts commit f35977d9.

Reason for revert: causes TCPSocketTest.ReadAndWriteMultiple to flake (timeout)

Bug: 821232

Original change's description:
> Add TCP socket API to network service
> 
> This CL adds TCP socket API to network service.
> This is partly based on mandoline implementation
> (https://codereview.chromium.org/1873463003/)
> 
> Two TCP socket interfaces are added.
> - TCPConnectedSocket
> - TCPServerSocket
> 
> TBR=miu@chromium.org
> 
> Bug: 721401
> Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
> Change-Id: I56e2702c02b9c86a72eba68c85391c3b017a4d64
> Reviewed-on: https://chromium-review.googlesource.com/868711
> Reviewed-by: Helen Li <xunjieli@chromium.org>
> Reviewed-by: Matt Menke <mmenke@chromium.org>
> Reviewed-by: Tom Sepez <tsepez@chromium.org>
> Reviewed-by: Ramin Halavati <rhalavati@chromium.org>
> Commit-Queue: Helen Li <xunjieli@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#542606}

TBR=miu@chromium.org,mmenke@chromium.org,tsepez@chromium.org,xunjieli@chromium.org,rhalavati@chromium.org

Change-Id: Id31caa2f5cc54993735586555e68bd3c345600bb
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 721401
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Reviewed-on: https://chromium-review.googlesource.com/958943Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Commit-Queue: Trent Apted <tapted@chromium.org>
Cr-Commit-Position: refs/heads/master@{#542696}
parent 74662183
...@@ -138,21 +138,8 @@ class MockNetworkContext final : public network::mojom::NetworkContext { ...@@ -138,21 +138,8 @@ class MockNetworkContext final : public network::mojom::NetworkContext {
std::move(receiver)); std::move(receiver));
OnUDPSocketCreated(); OnUDPSocketCreated();
} }
void CreateTCPServerSocket(
const net::IPEndPoint& local_addr, MockUdpSocket* udp_socket() const { return udp_socket_.get(); };
uint32_t backlog,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
network::mojom::TCPServerSocketRequest request,
CreateTCPServerSocketCallback callback) override {}
void CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
network::mojom::TCPConnectedSocketRequest request,
network::mojom::TCPConnectedSocketObserverPtr observer,
CreateTCPConnectedSocketCallback callback) override {}
MockUdpSocket* udp_socket() const { return udp_socket_.get(); }
private: private:
mojo::Binding<network::mojom::NetworkContext> binding_; mojo::Binding<network::mojom::NetworkContext> binding_;
......
...@@ -52,12 +52,6 @@ component("network_service") { ...@@ -52,12 +52,6 @@ component("network_service") {
"resource_scheduler_client.h", "resource_scheduler_client.h",
"restricted_cookie_manager.cc", "restricted_cookie_manager.cc",
"restricted_cookie_manager.h", "restricted_cookie_manager.h",
"socket_factory.cc",
"socket_factory.h",
"tcp_connected_socket.cc",
"tcp_connected_socket.h",
"tcp_server_socket.cc",
"tcp_server_socket.h",
"throttling/network_conditions.cc", "throttling/network_conditions.cc",
"throttling/network_conditions.h", "throttling/network_conditions.h",
"throttling/throttling_controller.cc", "throttling/throttling_controller.cc",
...@@ -72,6 +66,8 @@ component("network_service") { ...@@ -72,6 +66,8 @@ component("network_service") {
"throttling/throttling_upload_data_stream.h", "throttling/throttling_upload_data_stream.h",
"udp_socket.cc", "udp_socket.cc",
"udp_socket.h", "udp_socket.h",
"udp_socket_factory.cc",
"udp_socket_factory.h",
"upload_progress_tracker.cc", "upload_progress_tracker.cc",
"upload_progress_tracker.h", "upload_progress_tracker.h",
"url_loader.cc", "url_loader.cc",
...@@ -143,11 +139,11 @@ source_set("tests") { ...@@ -143,11 +139,11 @@ source_set("tests") {
"proxy_resolving_client_socket_unittest.cc", "proxy_resolving_client_socket_unittest.cc",
"resource_scheduler_unittest.cc", "resource_scheduler_unittest.cc",
"restricted_cookie_manager_unittest.cc", "restricted_cookie_manager_unittest.cc",
"tcp_socket_unittest.cc",
"test/test_url_loader_factory_unittest.cc", "test/test_url_loader_factory_unittest.cc",
"test_chunked_data_pipe_getter.cc", "test_chunked_data_pipe_getter.cc",
"test_chunked_data_pipe_getter.h", "test_chunked_data_pipe_getter.h",
"throttling/throttling_controller_unittest.cc", "throttling/throttling_controller_unittest.cc",
"udp_socket_factory_unittest.cc",
"udp_socket_unittest.cc", "udp_socket_unittest.cc",
"upload_progress_tracker_unittest.cc", "upload_progress_tracker_unittest.cc",
"url_loader_unittest.cc", "url_loader_unittest.cc",
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include "net/reporting/reporting_policy.h" #include "net/reporting/reporting_policy.h"
#include "net/ssl/channel_id_service.h" #include "net/ssl/channel_id_service.h"
#include "net/ssl/default_channel_id_store.h" #include "net/ssl/default_channel_id_store.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h" #include "net/url_request/url_request_context_builder.h"
#include "services/network/http_server_properties_pref_delegate.h" #include "services/network/http_server_properties_pref_delegate.h"
...@@ -50,6 +49,7 @@ ...@@ -50,6 +49,7 @@
#include "services/network/throttling/network_conditions.h" #include "services/network/throttling/network_conditions.h"
#include "services/network/throttling/throttling_controller.h" #include "services/network/throttling/throttling_controller.h"
#include "services/network/throttling/throttling_network_transaction_factory.h" #include "services/network/throttling/throttling_network_transaction_factory.h"
#include "services/network/udp_socket_factory.h"
#include "services/network/url_loader.h" #include "services/network/url_loader.h"
#include "services/network/url_loader_factory.h" #include "services/network/url_loader_factory.h"
#include "services/network/url_request_context_builder_mojo.h" #include "services/network/url_request_context_builder_mojo.h"
...@@ -92,8 +92,7 @@ NetworkContext::NetworkContext(NetworkService* network_service, ...@@ -92,8 +92,7 @@ NetworkContext::NetworkContext(NetworkService* network_service,
mojom::NetworkContextParamsPtr params) mojom::NetworkContextParamsPtr params)
: network_service_(network_service), : network_service_(network_service),
params_(std::move(params)), params_(std::move(params)),
binding_(this, std::move(request)), binding_(this, std::move(request)) {
socket_factory_(network_service_->net_log()) {
url_request_context_owner_ = MakeURLRequestContext(params_.get()); url_request_context_owner_ = MakeURLRequestContext(params_.get());
url_request_context_getter_ = url_request_context_getter_ =
url_request_context_owner_.url_request_context_getter; url_request_context_owner_.url_request_context_getter;
...@@ -116,8 +115,7 @@ NetworkContext::NetworkContext( ...@@ -116,8 +115,7 @@ NetworkContext::NetworkContext(
std::unique_ptr<URLRequestContextBuilderMojo> builder) std::unique_ptr<URLRequestContextBuilderMojo> builder)
: network_service_(network_service), : network_service_(network_service),
params_(std::move(params)), params_(std::move(params)),
binding_(this, std::move(request)), binding_(this, std::move(request)) {
socket_factory_(network_service_->net_log()) {
url_request_context_owner_ = ApplyContextParamsToBuilder( url_request_context_owner_ = ApplyContextParamsToBuilder(
builder.get(), params_.get(), network_service->quic_disabled(), builder.get(), params_.get(), network_service->quic_disabled(),
network_service->net_log()); network_service->net_log());
...@@ -138,9 +136,8 @@ NetworkContext::NetworkContext( ...@@ -138,9 +136,8 @@ NetworkContext::NetworkContext(
url_request_context_getter_(std::move(url_request_context_getter)), url_request_context_getter_(std::move(url_request_context_getter)),
binding_(this, std::move(request)), binding_(this, std::move(request)),
cookie_manager_(std::make_unique<CookieManager>( cookie_manager_(std::make_unique<CookieManager>(
url_request_context_getter_->GetURLRequestContext()->cookie_store())), url_request_context_getter_->GetURLRequestContext()
socket_factory_(network_service_ ? network_service_->net_log() ->cookie_store())) {
: nullptr) {
// May be nullptr in tests. // May be nullptr in tests.
if (network_service_) if (network_service_)
network_service_->RegisterNetworkContext(this); network_service_->RegisterNetworkContext(this);
...@@ -225,10 +222,7 @@ void NetworkContext::Cleanup() { ...@@ -225,10 +222,7 @@ void NetworkContext::Cleanup() {
} }
NetworkContext::NetworkContext(mojom::NetworkContextParamsPtr params) NetworkContext::NetworkContext(mojom::NetworkContextParamsPtr params)
: network_service_(nullptr), : network_service_(nullptr), params_(std::move(params)), binding_(this) {
params_(std::move(params)),
binding_(this),
socket_factory_(network_service_->net_log()) {
url_request_context_owner_ = MakeURLRequestContext(params_.get()); url_request_context_owner_ = MakeURLRequestContext(params_.get());
url_request_context_getter_ = url_request_context_getter_ =
url_request_context_owner_.url_request_context_getter; url_request_context_owner_.url_request_context_getter;
...@@ -492,32 +486,9 @@ void NetworkContext::SetNetworkConditions( ...@@ -492,32 +486,9 @@ void NetworkContext::SetNetworkConditions(
void NetworkContext::CreateUDPSocket(mojom::UDPSocketRequest request, void NetworkContext::CreateUDPSocket(mojom::UDPSocketRequest request,
mojom::UDPSocketReceiverPtr receiver) { mojom::UDPSocketReceiverPtr receiver) {
socket_factory_.CreateUDPSocket(std::move(request), std::move(receiver)); if (!udp_socket_factory_)
} udp_socket_factory_ = std::make_unique<UDPSocketFactory>();
udp_socket_factory_->CreateUDPSocket(std::move(request), std::move(receiver));
void NetworkContext::CreateTCPServerSocket(
const net::IPEndPoint& local_addr,
uint32_t backlog,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPServerSocketRequest request,
CreateTCPServerSocketCallback callback) {
socket_factory_.CreateTCPServerSocket(
local_addr, backlog,
static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation),
std::move(request), std::move(callback));
}
void NetworkContext::CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest request,
mojom::TCPConnectedSocketObserverPtr observer,
CreateTCPConnectedSocketCallback callback) {
socket_factory_.CreateTCPConnectedSocket(
local_addr, remote_addr_list,
static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation),
std::move(request), std::move(observer), std::move(callback));
} }
void NetworkContext::AddHSTSForTesting(const std::string& host, void NetworkContext::AddHSTSForTesting(const std::string& host,
......
...@@ -20,10 +20,8 @@ ...@@ -20,10 +20,8 @@
#include "services/network/cookie_manager.h" #include "services/network/cookie_manager.h"
#include "services/network/http_cache_data_remover.h" #include "services/network/http_cache_data_remover.h"
#include "services/network/public/mojom/network_service.mojom.h" #include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/mojom/tcp_socket.mojom.h"
#include "services/network/public/mojom/udp_socket.mojom.h" #include "services/network/public/mojom/udp_socket.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/socket_factory.h"
#include "services/network/url_request_context_owner.h" #include "services/network/url_request_context_owner.h"
namespace net { namespace net {
...@@ -35,6 +33,7 @@ namespace network { ...@@ -35,6 +33,7 @@ namespace network {
class NetworkService; class NetworkService;
class ResourceScheduler; class ResourceScheduler;
class ResourceSchedulerClient; class ResourceSchedulerClient;
class UDPSocketFactory;
class URLRequestContextBuilderMojo; class URLRequestContextBuilderMojo;
// A NetworkContext creates and manages access to a URLRequestContext. // A NetworkContext creates and manages access to a URLRequestContext.
...@@ -113,19 +112,6 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext ...@@ -113,19 +112,6 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
mojom::NetworkConditionsPtr conditions) override; mojom::NetworkConditionsPtr conditions) override;
void CreateUDPSocket(mojom::UDPSocketRequest request, void CreateUDPSocket(mojom::UDPSocketRequest request,
mojom::UDPSocketReceiverPtr receiver) override; mojom::UDPSocketReceiverPtr receiver) override;
void CreateTCPServerSocket(
const net::IPEndPoint& local_addr,
uint32_t backlog,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPServerSocketRequest request,
CreateTCPServerSocketCallback callback) override;
void CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest request,
mojom::TCPConnectedSocketObserverPtr observer,
CreateTCPConnectedSocketCallback callback) override;
void AddHSTSForTesting(const std::string& host, void AddHSTSForTesting(const std::string& host,
base::Time expiry, base::Time expiry,
bool include_subdomains, bool include_subdomains,
...@@ -183,7 +169,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext ...@@ -183,7 +169,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
std::unique_ptr<CookieManager> cookie_manager_; std::unique_ptr<CookieManager> cookie_manager_;
SocketFactory socket_factory_; std::unique_ptr<UDPSocketFactory> udp_socket_factory_;
std::vector<std::unique_ptr<HttpCacheDataRemover>> http_cache_data_removers_; std::vector<std::unique_ptr<HttpCacheDataRemover>> http_cache_data_removers_;
......
...@@ -70,7 +70,6 @@ mojom("mojom") { ...@@ -70,7 +70,6 @@ mojom("mojom") {
"proxy_config_with_annotation.mojom", "proxy_config_with_annotation.mojom",
"request_context_frame_type.mojom", "request_context_frame_type.mojom",
"restricted_cookie_manager.mojom", "restricted_cookie_manager.mojom",
"tcp_socket.mojom",
"url_loader.mojom", "url_loader.mojom",
"url_loader_factory.mojom", "url_loader_factory.mojom",
] ]
......
...@@ -6,15 +6,12 @@ module network.mojom; ...@@ -6,15 +6,12 @@ module network.mojom;
import "mojo/common/file_path.mojom"; import "mojo/common/file_path.mojom";
import "mojo/common/time.mojom"; import "mojo/common/time.mojom";
import "net/interfaces/address_list.mojom";
import "net/interfaces/ip_endpoint.mojom"; import "net/interfaces/ip_endpoint.mojom";
import "services/network/public/mojom/cookie_manager.mojom"; import "services/network/public/mojom/cookie_manager.mojom";
import "services/network/public/mojom/mutable_network_traffic_annotation_tag.mojom";
import "services/network/public/mojom/network_change_manager.mojom"; import "services/network/public/mojom/network_change_manager.mojom";
import "services/network/public/mojom/proxy_config.mojom"; import "services/network/public/mojom/proxy_config.mojom";
import "services/network/public/mojom/proxy_config_with_annotation.mojom"; import "services/network/public/mojom/proxy_config_with_annotation.mojom";
import "services/network/public/mojom/restricted_cookie_manager.mojom"; import "services/network/public/mojom/restricted_cookie_manager.mojom";
import "services/network/public/mojom/tcp_socket.mojom";
import "services/network/public/mojom/udp_socket.mojom"; import "services/network/public/mojom/udp_socket.mojom";
import "services/network/public/mojom/url_loader.mojom"; import "services/network/public/mojom/url_loader.mojom";
import "services/network/public/mojom/url_loader_factory.mojom"; import "services/network/public/mojom/url_loader_factory.mojom";
...@@ -190,46 +187,8 @@ interface NetworkContext { ...@@ -190,46 +187,8 @@ interface NetworkContext {
// is not interested in incoming data. // is not interested in incoming data.
// Any sockets that are created but are yet to be destroyed will be destroyed // Any sockets that are created but are yet to be destroyed will be destroyed
// when NetworkContext goes away. // when NetworkContext goes away.
CreateUDPSocket(UDPSocket& request, UDPSocketReceiver? receiver); CreateUDPSocket(network.mojom.UDPSocket& request,
network.mojom.UDPSocketReceiver? receiver);
// Creates a TCP server socket that listens on |local_addr|. The socket
// created can only be used for the purpose specified in |traffic_annotation|,
// and cannot be re-used for other purposes. Caller must specify an address
// family in |local_addr| to be either IPv4 or IPv6. If port in |local_addr|
// is 0, the OS will pick an available port. If address bytes are 0, the OS
// will pick a local address of the specified address family. |backlog| will
// be passed to the OS to set the size of accept queue.
// On success, the resulting local address will be written to |local_addr_out|
// and |result| is net::OK. On failure, |result| is a network error code.
//
// Any sockets that are created but are yet to be destroyed will be destroyed
// when NetworkContext goes away.
CreateTCPServerSocket(net.interfaces.IPEndPoint local_addr,
uint32 backlog,
MutableNetworkTrafficAnnotationTag traffic_annotation,
TCPServerSocket& socket)
=> (int32 result, net.interfaces.IPEndPoint? local_addr_out);
// Creates a TCP socket connected to |remote_addr|. |observer| will be used
// to listen for any network connection error on the newly established
// connection. The socket created can only be used for the purpose specified
// in |traffic_annotation|, and cannot be re-used for other purposes.
// |local_addr| should be set to null unless the caller wants to bind the
// socket to a specific address and port. On success, |result| is net::OK.
// Caller is to use |send_stream| to send data and |receive_stream| to receive
// data over the connection. On failure, |result| is a network error code.
//
// Any sockets that are created but are yet to be destroyed will be destroyed
// when NetworkContext goes away.
CreateTCPConnectedSocket(
net.interfaces.IPEndPoint? local_addr,
net.interfaces.AddressList remote_addr_list,
MutableNetworkTrafficAnnotationTag traffic_annotation,
TCPConnectedSocket& socket,
TCPConnectedSocketObserver observer)
=> (int32 result,
handle<data_pipe_consumer>? receive_stream,
handle<data_pipe_producer>? send_stream);
[Sync] [Sync]
// Adds explicitly-specified data as if it was processed from an // Adds explicitly-specified data as if it was processed from an
......
// Copyright 2018 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.
module network.mojom;
import "net/interfaces/ip_endpoint.mojom";
// Represents a connected TCP socket. Writes and Reads are through the data
// pipes supplied upon construction. Consumer should use
// TCPConnectedSocketObserver interface to get notified about any error occurred
// during reading or writing to data pipes. Consumer can close the socket by
// destroying the interface pointer.
interface TCPConnectedSocket {
// Gets the local address of this connected socket. On success, |net_error| is
// net::OK and |local_addr| contains the local address of the socket. On
// failure, |local_addr| is null and |net_error| is a net error code.
GetLocalAddress() => (int32 net_error, net.interfaces.IPEndPoint? local_addr);
};
// Interface to listen for network connection error on a TCPConnectedSocket.
// Because data pipe doesn't surface any network connection error, if a network
// error happens during a read or a write, consumer can find out about it by
// implementing this interface.
interface TCPConnectedSocketObserver {
// Called when an error occurs during reading from the network. The producer
// side of |receive_stream| will be closed.
OnReadError(int32 net_error);
// Called when an error occurs during sending to the network. The consumer
// side of |send_stream| will be closed.
OnWriteError(int32 net_error);
};
// Represents a TCP server socket that has been successfully bound to a local
// address. Caller can close the socket by destroying the interface pointer.
interface TCPServerSocket {
// Waits for an incoming connection request. On success, returns net::OK,
// |remote_addr| represents the peer address, |connected_socket| is the new
// connection established. Caller uses |send_stream| to send data and
// |receive_stream| for receiving data over the new connection. On failure,
// |net_error| is a net error code and other fields are null.
// Up to |backlog| Accept()s can be pending at a time. |backlog| is a
// number that is specified when requesting TCPServerSocket. If more than
// |backlog| number of Accept()s are outstanding,
// net::ERR_INSUFFICIENT_RESOUCES will be returned.
Accept(TCPConnectedSocketObserver observer)
=> (int32 net_error,
net.interfaces.IPEndPoint? remote_addr,
TCPConnectedSocket? connected_socket,
handle<data_pipe_consumer>? send_stream,
handle<data_pipe_producer>? receive_stream);
};
// Copyright 2018 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 "services/network/socket_factory.h"
#include <utility>
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_errors.h"
#include "net/log/net_log.h"
#include "services/network/tcp_connected_socket.h"
#include "services/network/udp_socket.h"
namespace network {
SocketFactory::SocketFactory(net::NetLog* net_log) : net_log_(net_log) {}
SocketFactory::~SocketFactory() {}
void SocketFactory::CreateUDPSocket(mojom::UDPSocketRequest request,
mojom::UDPSocketReceiverPtr receiver) {
udp_socket_bindings_.AddBinding(
std::make_unique<UDPSocket>(std::move(receiver), net_log_),
std::move(request));
}
void SocketFactory::CreateTCPServerSocket(
const net::IPEndPoint& local_addr,
int backlog,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPServerSocketRequest request,
mojom::NetworkContext::CreateTCPServerSocketCallback callback) {
auto socket =
std::make_unique<TCPServerSocket>(this, net_log_, traffic_annotation);
net::IPEndPoint local_addr_out;
int result = socket->Listen(local_addr, backlog, &local_addr_out);
if (result != net::OK) {
std::move(callback).Run(result, base::nullopt);
return;
}
tcp_server_socket_bindings_.AddBinding(std::move(socket), std::move(request));
std::move(callback).Run(result, local_addr_out);
}
void SocketFactory::CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest request,
mojom::TCPConnectedSocketObserverPtr observer,
mojom::NetworkContext::CreateTCPConnectedSocketCallback callback) {
auto socket = std::make_unique<TCPConnectedSocket>(
std::move(observer), net_log_, traffic_annotation);
TCPConnectedSocket* socket_raw = socket.get();
tcp_connected_socket_bindings_.AddBinding(std::move(socket),
std::move(request));
socket_raw->Connect(local_addr, remote_addr_list, std::move(callback));
}
void SocketFactory::OnAccept(std::unique_ptr<TCPConnectedSocket> socket,
mojom::TCPConnectedSocketRequest request) {
tcp_connected_socket_bindings_.AddBinding(std::move(socket),
std::move(request));
}
} // namespace network
// Copyright 2018 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 SERVICES_NETWORK_SOCKET_FACTORY_H_
#define SERVICES_NETWORK_SOCKET_FACTORY_H_
#include <memory>
#include <vector>
#include "base/component_export.h"
#include "base/macros.h"
#include "mojo/public/cpp/bindings/strong_binding_set.h"
#include "net/socket/tcp_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/mojom/tcp_socket.mojom.h"
#include "services/network/public/mojom/udp_socket.mojom.h"
#include "services/network/tcp_server_socket.h"
namespace net {
class NetLog;
} // namespace net
namespace network {
class UDPSocket;
class TCPConnectedSocket;
// Helper class that handles UDPSocketRequest. It takes care of destroying the
// UDPSocket implementation instances when mojo pipes are broken.
class COMPONENT_EXPORT(NETWORK_SERVICE) SocketFactory
: public TCPServerSocket::Delegate {
public:
// Constructs a SocketFactory. If |net_log| is non-null, it is used to
// log NetLog events when logging is enabled. |net_log| used to must outlive
// |this|.
explicit SocketFactory(net::NetLog* net_log);
virtual ~SocketFactory();
void CreateUDPSocket(mojom::UDPSocketRequest request,
mojom::UDPSocketReceiverPtr receiver);
void CreateTCPServerSocket(
const net::IPEndPoint& local_addr,
int backlog,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPServerSocketRequest request,
mojom::NetworkContext::CreateTCPServerSocketCallback callback);
void CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest request,
mojom::TCPConnectedSocketObserverPtr observer,
mojom::NetworkContext::CreateTCPConnectedSocketCallback callback);
private:
// TCPServerSocket::Delegate implementation:
void OnAccept(std::unique_ptr<TCPConnectedSocket> socket,
mojom::TCPConnectedSocketRequest request) override;
void OnConnectCompleted(int result);
net::NetLog* net_log_;
mojo::StrongBindingSet<mojom::UDPSocket> udp_socket_bindings_;
mojo::StrongBindingSet<mojom::TCPServerSocket> tcp_server_socket_bindings_;
mojo::StrongBindingSet<mojom::TCPConnectedSocket>
tcp_connected_socket_bindings_;
DISALLOW_COPY_AND_ASSIGN(SocketFactory);
};
} // namespace network
#endif // SERVICES_NETWORK_SOCKET_FACTORY_H_
// Copyright 2018 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 "services/network/tcp_connected_socket.h"
#include <utility>
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/numerics/safe_conversions.h"
#include "base/optional.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/log/net_log.h"
namespace network {
TCPConnectedSocket::TCPConnectedSocket(
mojom::TCPConnectedSocketObserverPtr observer,
net::NetLog* net_log,
const net::NetworkTrafficAnnotationTag& traffic_annotation)
: observer_(std::move(observer)),
net_log_(net_log),
readable_handle_watcher_(FROM_HERE,
mojo::SimpleWatcher::ArmingPolicy::MANUAL),
writable_handle_watcher_(FROM_HERE,
mojo::SimpleWatcher::ArmingPolicy::MANUAL),
traffic_annotation_(traffic_annotation) {
// TODO(xunjieli): Consider supporting null |observer_|, if there are
// consumers who do not care about read/write errors.
DCHECK(observer_);
}
TCPConnectedSocket::TCPConnectedSocket(
mojom::TCPConnectedSocketObserverPtr observer,
std::unique_ptr<net::StreamSocket> socket,
mojo::ScopedDataPipeProducerHandle receive_pipe_handle,
mojo::ScopedDataPipeConsumerHandle send_pipe_handle,
const net::NetworkTrafficAnnotationTag& traffic_annotation)
: observer_(std::move(observer)),
net_log_(nullptr),
socket_(std::move(socket)),
send_stream_(std::move(send_pipe_handle)),
readable_handle_watcher_(FROM_HERE,
mojo::SimpleWatcher::ArmingPolicy::MANUAL),
receive_stream_(std::move(receive_pipe_handle)),
writable_handle_watcher_(FROM_HERE,
mojo::SimpleWatcher::ArmingPolicy::MANUAL),
traffic_annotation_(traffic_annotation) {
StartWatching();
}
TCPConnectedSocket::~TCPConnectedSocket() {}
void TCPConnectedSocket::Connect(
const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list,
mojom::NetworkContext::CreateTCPConnectedSocketCallback callback) {
DCHECK(!socket_);
DCHECK(callback);
auto socket = std::make_unique<net::TCPClientSocket>(
remote_addr_list, nullptr /*socket_performance_watcher*/, net_log_,
net::NetLogSource());
connect_callback_ = std::move(callback);
int result = net::OK;
if (local_addr)
result = socket->Bind(local_addr.value());
if (result == net::OK) {
result = socket->Connect(base::BindRepeating(
&TCPConnectedSocket::OnConnectCompleted, base::Unretained(this)));
}
socket_ = std::move(socket);
if (result == net::ERR_IO_PENDING)
return;
OnConnectCompleted(result);
}
void TCPConnectedSocket::GetLocalAddress(GetLocalAddressCallback callback) {
DCHECK(socket_);
net::IPEndPoint local_addr;
int result = socket_->GetLocalAddress(&local_addr);
if (result != net::OK) {
std::move(callback).Run(result, base::nullopt);
return;
}
std::move(callback).Run(result, local_addr);
}
void TCPConnectedSocket::OnConnectCompleted(int result) {
DCHECK(!connect_callback_.is_null());
DCHECK(!receive_stream_.is_valid());
DCHECK(!send_stream_.is_valid());
if (result != net::OK) {
std::move(connect_callback_)
.Run(result, mojo::ScopedDataPipeConsumerHandle(),
mojo::ScopedDataPipeProducerHandle());
return;
}
mojo::DataPipe send_pipe;
mojo::DataPipe receive_pipe;
receive_stream_ = std::move(receive_pipe.producer_handle);
send_stream_ = std::move(send_pipe.consumer_handle);
StartWatching();
std::move(connect_callback_)
.Run(net::OK, std::move(receive_pipe.consumer_handle),
std::move(send_pipe.producer_handle));
}
void TCPConnectedSocket::StartWatching() {
readable_handle_watcher_.Watch(
send_stream_.get(),
MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
base::BindRepeating(&TCPConnectedSocket::OnSendStreamReadable,
base::Unretained(this)));
writable_handle_watcher_.Watch(
receive_stream_.get(),
MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
base::BindRepeating(&TCPConnectedSocket::OnReceiveStreamWritable,
base::Unretained(this)));
ReceiveMore();
SendMore();
}
void TCPConnectedSocket::ReceiveMore() {
DCHECK(receive_stream_.is_valid());
DCHECK(!pending_receive_);
uint32_t num_bytes;
MojoResult result = NetToMojoPendingBuffer::BeginWrite(
&receive_stream_, &pending_receive_, &num_bytes);
if (result == MOJO_RESULT_SHOULD_WAIT) {
writable_handle_watcher_.ArmOrNotify();
return;
}
if (result != MOJO_RESULT_OK) {
ShutdownReceive();
return;
}
DCHECK_EQ(MOJO_RESULT_OK, result);
DCHECK(pending_receive_);
scoped_refptr<net::IOBuffer> buf(
new NetToMojoIOBuffer(pending_receive_.get()));
int read_result = socket_->Read(
buf.get(), base::saturated_cast<int>(num_bytes),
base::BindRepeating(&TCPConnectedSocket::OnNetworkReadCompleted,
base::Unretained(this)));
if (read_result == net::ERR_IO_PENDING)
return;
OnNetworkReadCompleted(read_result);
}
void TCPConnectedSocket::OnReceiveStreamWritable(MojoResult result) {
if (result != MOJO_RESULT_OK) {
ShutdownReceive();
return;
}
ReceiveMore();
}
void TCPConnectedSocket::OnNetworkReadCompleted(int bytes_read) {
DCHECK(pending_receive_);
if (bytes_read < 0)
observer_->OnReadError(bytes_read);
if (bytes_read <= 0) {
ShutdownReceive();
return;
}
if (bytes_read > 0) {
receive_stream_ = pending_receive_->Complete(bytes_read);
pending_receive_ = nullptr;
ReceiveMore();
}
}
void TCPConnectedSocket::ShutdownReceive() {
writable_handle_watcher_.Cancel();
pending_receive_ = nullptr;
receive_stream_.reset();
}
void TCPConnectedSocket::SendMore() {
DCHECK(send_stream_.is_valid());
DCHECK(!pending_send_);
uint32_t num_bytes = 0;
MojoResult result = MojoToNetPendingBuffer::BeginRead(
&send_stream_, &pending_send_, &num_bytes);
if (result == MOJO_RESULT_SHOULD_WAIT) {
readable_handle_watcher_.ArmOrNotify();
return;
}
if (result != MOJO_RESULT_OK) {
ShutdownSend();
return;
}
DCHECK_EQ(MOJO_RESULT_OK, result);
DCHECK(pending_send_);
scoped_refptr<net::IOBuffer> buf(
new net::WrappedIOBuffer(pending_send_->buffer()));
int write_result = socket_->Write(
buf.get(), static_cast<int>(num_bytes),
base::BindRepeating(&TCPConnectedSocket::OnNetworkWriteCompleted,
base::Unretained(this)),
traffic_annotation_);
if (write_result == net::ERR_IO_PENDING)
return;
OnNetworkWriteCompleted(write_result);
}
void TCPConnectedSocket::OnSendStreamReadable(MojoResult result) {
if (result != MOJO_RESULT_OK) {
ShutdownSend();
return;
}
SendMore();
}
void TCPConnectedSocket::OnNetworkWriteCompleted(int bytes_written) {
DCHECK(pending_send_);
if (bytes_written < 0)
observer_->OnWriteError(bytes_written);
if (bytes_written <= 0) {
ShutdownSend();
return;
}
if (bytes_written > 0) {
// Partial write is possible.
pending_send_->CompleteRead(bytes_written);
send_stream_ = pending_send_->ReleaseHandle();
pending_send_ = nullptr;
SendMore();
}
}
void TCPConnectedSocket::ShutdownSend() {
readable_handle_watcher_.Cancel();
pending_send_ = nullptr;
send_stream_.reset();
}
} // namespace network
// Copyright 2018 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 SERVICES_NETWORK_TCP_CONNECTED_SOCKET_H_
#define SERVICES_NETWORK_TCP_CONNECTED_SOCKET_H_
#include <memory>
#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/simple_watcher.h"
#include "net/base/address_family.h"
#include "net/base/completion_callback.h"
#include "net/base/ip_endpoint.h"
#include "net/interfaces/address_family.mojom.h"
#include "net/interfaces/ip_endpoint.mojom.h"
#include "net/socket/tcp_client_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/net_adapters.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/mojom/tcp_socket.mojom.h"
namespace net {
class NetLog;
class StreamSocket;
} // namespace net
namespace network {
class COMPONENT_EXPORT(NETWORK_SERVICE) TCPConnectedSocket
: public mojom::TCPConnectedSocket {
public:
TCPConnectedSocket(
mojom::TCPConnectedSocketObserverPtr observer,
net::NetLog* net_log,
const net::NetworkTrafficAnnotationTag& traffic_annotation);
TCPConnectedSocket(
mojom::TCPConnectedSocketObserverPtr observer,
std::unique_ptr<net::StreamSocket> socket,
mojo::ScopedDataPipeProducerHandle receive_pipe_handle,
mojo::ScopedDataPipeConsumerHandle send_pipe_handle,
const net::NetworkTrafficAnnotationTag& traffic_annotation);
~TCPConnectedSocket() override;
void Connect(
const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list,
mojom::NetworkContext::CreateTCPConnectedSocketCallback callback);
// mojom::TCPConnectedSocket implementation.
void GetLocalAddress(GetLocalAddressCallback callback) override;
private:
// Invoked when net::TCPClientSocket::Connect() completes.
void OnConnectCompleted(int net_result);
// Helper to start watching |send_stream_| and |receive_stream_|.
void StartWatching();
// "Receiving" in this context means reading from |socket_| and writing to
// the Mojo |receive_stream_|.
void ReceiveMore();
void OnReceiveStreamWritable(MojoResult result);
void OnNetworkReadCompleted(int result);
void ShutdownReceive();
// "Writing" is reading from the Mojo |send_stream_| and writing to the
// |socket_|.
void SendMore();
void OnSendStreamReadable(MojoResult result);
void OnNetworkWriteCompleted(int result);
void ShutdownSend();
mojom::TCPConnectedSocketObserverPtr observer_;
net::NetLog* net_log_;
std::unique_ptr<net::StreamSocket> socket_;
mojom::NetworkContext::CreateTCPConnectedSocketCallback connect_callback_;
// The *stream handles will be null while there is an in-progress transation
// between net and mojo. During this time, the handle will be owned by the
// *PendingBuffer.
// For reading from the Mojo pipe and writing to the network.
mojo::ScopedDataPipeConsumerHandle send_stream_;
scoped_refptr<MojoToNetPendingBuffer> pending_send_;
mojo::SimpleWatcher readable_handle_watcher_;
// For reading from the network and writing to Mojo pipe.
mojo::ScopedDataPipeProducerHandle receive_stream_;
scoped_refptr<NetToMojoPendingBuffer> pending_receive_;
mojo::SimpleWatcher writable_handle_watcher_;
net::NetworkTrafficAnnotationTag traffic_annotation_;
DISALLOW_COPY_AND_ASSIGN(TCPConnectedSocket);
};
} // namespace network
#endif // SERVICES_NETWORK_TCP_CONNECTED_SOCKET_H_
// Copyright 2018 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 "services/network/tcp_server_socket.h"
#include <utility>
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/numerics/safe_conversions.h"
#include "base/optional.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/log/net_log.h"
#include "net/socket/tcp_server_socket.h"
#include "services/network/tcp_connected_socket.h"
namespace network {
TCPServerSocket::TCPServerSocket(
Delegate* delegate,
net::NetLog* net_log,
const net::NetworkTrafficAnnotationTag& traffic_annotation)
: delegate_(delegate),
socket_(
std::make_unique<net::TCPServerSocket>(net_log, net::NetLogSource())),
backlog_(0),
traffic_annotation_(traffic_annotation),
weak_factory_(this) {}
TCPServerSocket::~TCPServerSocket() {}
int TCPServerSocket::Listen(const net::IPEndPoint& local_addr,
int backlog,
net::IPEndPoint* local_addr_out) {
if (backlog == 0) {
// SocketPosix::Listen and TCPSocketWin::Listen DCHECKs on backlog > 0.
return net::ERR_INVALID_ARGUMENT;
}
backlog_ = backlog;
int net_error = socket_->Listen(local_addr, backlog);
if (net_error == net::OK)
socket_->GetLocalAddress(local_addr_out);
return net_error;
}
void TCPServerSocket::Accept(mojom::TCPConnectedSocketObserverPtr observer,
AcceptCallback callback) {
if (pending_accepts_queue_.size() >= static_cast<size_t>(backlog_)) {
std::move(callback).Run(net::ERR_INSUFFICIENT_RESOURCES, base::nullopt,
nullptr, mojo::ScopedDataPipeConsumerHandle(),
mojo::ScopedDataPipeProducerHandle());
return;
}
pending_accepts_queue_.push_back(std::make_unique<PendingAccept>(
std::move(callback), std::move(observer)));
if (pending_accepts_queue_.size() == 1)
ProcessNextAccept();
}
void TCPServerSocket::SetSocketForTest(
std::unique_ptr<net::ServerSocket> socket) {
socket_ = std::move(socket);
}
TCPServerSocket::PendingAccept::PendingAccept(
AcceptCallback callback,
mojom::TCPConnectedSocketObserverPtr observer)
: callback(std::move(callback)), observer(std::move(observer)) {}
TCPServerSocket::PendingAccept::~PendingAccept() {}
void TCPServerSocket::OnAcceptCompleted(int result) {
DCHECK_NE(net::ERR_IO_PENDING, result);
DCHECK(!pending_accepts_queue_.empty());
auto pending_accept = std::move(pending_accepts_queue_.front());
pending_accepts_queue_.erase(pending_accepts_queue_.begin());
net::IPEndPoint peer_addr;
if (result == net::OK) {
DCHECK(accepted_socket_);
result = accepted_socket_->GetPeerAddress(&peer_addr);
}
if (result == net::OK) {
mojo::DataPipe send_pipe;
mojo::DataPipe receive_pipe;
mojom::TCPConnectedSocketPtr socket;
auto connected_socket = std::make_unique<TCPConnectedSocket>(
std::move(pending_accept->observer),
base::WrapUnique(accepted_socket_.release()),
std::move(receive_pipe.producer_handle),
std::move(send_pipe.consumer_handle), traffic_annotation_);
delegate_->OnAccept(std::move(connected_socket),
mojo::MakeRequest(&socket));
std::move(pending_accept->callback)
.Run(result, peer_addr, std::move(socket),
std::move(receive_pipe.consumer_handle),
std::move(send_pipe.producer_handle));
} else {
std::move(pending_accept->callback)
.Run(result, base::nullopt, nullptr,
mojo::ScopedDataPipeConsumerHandle(),
mojo::ScopedDataPipeProducerHandle());
}
ProcessNextAccept();
}
void TCPServerSocket::ProcessNextAccept() {
if (pending_accepts_queue_.empty())
return;
int result =
socket_->Accept(&accepted_socket_,
base::BindRepeating(&TCPServerSocket::OnAcceptCompleted,
base::Unretained(this)));
if (result == net::ERR_IO_PENDING)
return;
OnAcceptCompleted(result);
}
} // namespace network
// Copyright 2018 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 SERVICES_NETWORK_TCP_SERVER_SOCKET_H_
#define SERVICES_NETWORK_TCP_SERVER_SOCKET_H_
#include <memory>
#include <vector>
#include "base/component_export.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "net/base/ip_endpoint.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/mojom/tcp_socket.mojom.h"
namespace net {
class NetLog;
class ServerSocket;
class StreamSocket;
} // namespace net
namespace network {
class TCPConnectedSocket;
class COMPONENT_EXPORT(NETWORK_SERVICE) TCPServerSocket
: public mojom::TCPServerSocket {
public:
// A delegate interface that is notified when new connections are established.
class Delegate {
public:
Delegate() {}
~Delegate() {}
// Invoked when a new connection is accepted. The delegate should take
// ownership of |socket| and set up binding for |request|.
virtual void OnAccept(std::unique_ptr<TCPConnectedSocket> socket,
mojom::TCPConnectedSocketRequest request) = 0;
};
// Constructs a TCPServerSocket. |delegate| must outlive |this|. When a new
// connection is accepted, |delegate| will be notified to take ownership of
// the connection.
TCPServerSocket(Delegate* delegate,
net::NetLog* net_log,
const net::NetworkTrafficAnnotationTag& traffic_annotation);
~TCPServerSocket() override;
int Listen(const net::IPEndPoint& local_addr,
int backlog,
net::IPEndPoint* local_addr_out);
// TCPServerSocket implementation.
void Accept(mojom::TCPConnectedSocketObserverPtr observer,
AcceptCallback callback) override;
// Replaces the underlying socket implementation with |socket| in tests.
void SetSocketForTest(std::unique_ptr<net::ServerSocket> socket);
private:
struct PendingAccept {
PendingAccept(AcceptCallback callback,
mojom::TCPConnectedSocketObserverPtr observer);
~PendingAccept();
AcceptCallback callback;
mojom::TCPConnectedSocketObserverPtr observer;
};
// Invoked when socket_->Accept() completes.
void OnAcceptCompleted(int result);
// Process the next Accept() from |pending_accepts_queue_|.
void ProcessNextAccept();
Delegate* delegate_;
std::unique_ptr<net::ServerSocket> socket_;
int backlog_;
std::vector<std::unique_ptr<PendingAccept>> pending_accepts_queue_;
std::unique_ptr<net::StreamSocket> accepted_socket_;
net::NetworkTrafficAnnotationTag traffic_annotation_;
base::WeakPtrFactory<TCPServerSocket> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(TCPServerSocket);
};
} // namespace network
#endif // SERVICES_NETWORK_TCP_SERVER_SOCKET_H_
This diff is collapsed.
...@@ -137,15 +137,22 @@ UDPSocket::PendingSendRequest::PendingSendRequest() {} ...@@ -137,15 +137,22 @@ UDPSocket::PendingSendRequest::PendingSendRequest() {}
UDPSocket::PendingSendRequest::~PendingSendRequest() {} UDPSocket::PendingSendRequest::~PendingSendRequest() {}
UDPSocket::UDPSocket(mojom::UDPSocketReceiverPtr receiver, net::NetLog* net_log) UDPSocket::UDPSocket(mojom::UDPSocketRequest request,
: net_log_(net_log), mojom::UDPSocketReceiverPtr receiver)
is_bound_(false), : is_bound_(false),
is_connected_(false), is_connected_(false),
receiver_(std::move(receiver)), receiver_(std::move(receiver)),
remaining_recv_slots_(0) {} remaining_recv_slots_(0),
binding_(this) {
binding_.Bind(std::move(request));
}
UDPSocket::~UDPSocket() {} UDPSocket::~UDPSocket() {}
void UDPSocket::set_connection_error_handler(base::OnceClosure handler) {
binding_.set_connection_error_handler(std::move(handler));
}
void UDPSocket::Connect(const net::IPEndPoint& remote_addr, void UDPSocket::Connect(const net::IPEndPoint& remote_addr,
mojom::UDPSocketOptionsPtr options, mojom::UDPSocketOptionsPtr options,
ConnectCallback callback) { ConnectCallback callback) {
...@@ -288,7 +295,7 @@ std::unique_ptr<UDPSocket::SocketWrapper> UDPSocket::CreateSocketWrapper() ...@@ -288,7 +295,7 @@ std::unique_ptr<UDPSocket::SocketWrapper> UDPSocket::CreateSocketWrapper()
const { const {
return std::make_unique<SocketWrapperImpl>( return std::make_unique<SocketWrapperImpl>(
net::DatagramSocket::RANDOM_BIND, base::BindRepeating(&base::RandInt), net::DatagramSocket::RANDOM_BIND, base::BindRepeating(&base::RandInt),
net_log_, net::NetLogSource()); nullptr, net::NetLogSource());
} }
bool UDPSocket::IsConnectedOrBound() const { bool UDPSocket::IsConnectedOrBound() const {
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include "base/containers/span.h" #include "base/containers/span.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "net/base/address_family.h" #include "net/base/address_family.h"
#include "net/base/completion_callback.h" #include "net/base/completion_callback.h"
#include "net/base/ip_endpoint.h" #include "net/base/ip_endpoint.h"
...@@ -24,7 +26,6 @@ ...@@ -24,7 +26,6 @@
namespace net { namespace net {
class IOBuffer; class IOBuffer;
class IOBufferWithSize; class IOBufferWithSize;
class NetLog;
} // namespace net } // namespace net
namespace network { namespace network {
...@@ -69,9 +70,13 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) UDPSocket : public mojom::UDPSocket { ...@@ -69,9 +70,13 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) UDPSocket : public mojom::UDPSocket {
const net::CompletionCallback& callback) = 0; const net::CompletionCallback& callback) = 0;
}; };
UDPSocket(mojom::UDPSocketReceiverPtr receiver, net::NetLog* net_log); UDPSocket(mojom::UDPSocketRequest request,
mojom::UDPSocketReceiverPtr receiver);
~UDPSocket() override; ~UDPSocket() override;
// Sets connection error handler.
void set_connection_error_handler(base::OnceClosure handler);
// UDPSocket implementation. // UDPSocket implementation.
void Connect(const net::IPEndPoint& remote_addr, void Connect(const net::IPEndPoint& remote_addr,
mojom::UDPSocketOptionsPtr options, mojom::UDPSocketOptionsPtr options,
...@@ -132,8 +137,6 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) UDPSocket : public mojom::UDPSocket { ...@@ -132,8 +137,6 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) UDPSocket : public mojom::UDPSocket {
void OnRecvFromCompleted(uint32_t buffer_size, int net_result); void OnRecvFromCompleted(uint32_t buffer_size, int net_result);
void OnSendToCompleted(int net_result); void OnSendToCompleted(int net_result);
net::NetLog* net_log_;
// Whether a Bind() has been successfully executed. // Whether a Bind() has been successfully executed.
bool is_bound_; bool is_bound_;
...@@ -163,6 +166,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) UDPSocket : public mojom::UDPSocket { ...@@ -163,6 +166,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) UDPSocket : public mojom::UDPSocket {
base::circular_deque<std::unique_ptr<PendingSendRequest>> base::circular_deque<std::unique_ptr<PendingSendRequest>>
pending_send_requests_; pending_send_requests_;
mojo::Binding<mojom::UDPSocket> binding_;
DISALLOW_COPY_AND_ASSIGN(UDPSocket); DISALLOW_COPY_AND_ASSIGN(UDPSocket);
}; };
......
// Copyright 2018 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 "services/network/udp_socket_factory.h"
#include <utility>
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "net/base/net_errors.h"
#include "services/network/udp_socket.h"
namespace network {
UDPSocketFactory::UDPSocketFactory() {}
UDPSocketFactory::~UDPSocketFactory() {}
void UDPSocketFactory::CreateUDPSocket(mojom::UDPSocketRequest request,
mojom::UDPSocketReceiverPtr receiver) {
auto socket =
std::make_unique<UDPSocket>(std::move(request), std::move(receiver));
// base::Unretained is safe as the destruction of |this| will also destroy
// |udp_sockets_| which owns this socket.
socket->set_connection_error_handler(
base::BindOnce(&UDPSocketFactory::OnPipeBroken, base::Unretained(this),
base::Unretained(socket.get())));
udp_sockets_.push_back(std::move(socket));
}
void UDPSocketFactory::OnPipeBroken(UDPSocket* socket) {
udp_sockets_.erase(
std::find_if(udp_sockets_.begin(), udp_sockets_.end(),
[socket](const std::unique_ptr<network::UDPSocket>& ptr) {
return ptr.get() == socket;
}));
}
} // namespace network
// Copyright 2018 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 SERVICES_NETWORK_UDP_SOCKET_FACTORY_H_
#define SERVICES_NETWORK_UDP_SOCKET_FACTORY_H_
#include <memory>
#include <vector>
#include "base/component_export.h"
#include "base/macros.h"
#include "services/network/public/mojom/udp_socket.mojom.h"
namespace network {
class UDPSocket;
// Helper class that handles UDPSocketRequest. It takes care of destroying the
// UDPSocket implementation instances when mojo pipes are broken.
class COMPONENT_EXPORT(NETWORK_SERVICE) UDPSocketFactory {
public:
UDPSocketFactory();
virtual ~UDPSocketFactory();
void CreateUDPSocket(mojom::UDPSocketRequest request,
mojom::UDPSocketReceiverPtr receiver);
protected:
// Handles connection errors. This is virtual for testing.
virtual void OnPipeBroken(UDPSocket* client);
private:
std::vector<std::unique_ptr<UDPSocket>> udp_sockets_;
DISALLOW_COPY_AND_ASSIGN(UDPSocketFactory);
};
} // namespace network
#endif // SERVICES_NETWORK_UDP_SOCKET_FACTORY_H_
// Copyright 2017 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 <utility>
#include "services/network/udp_socket_factory.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "net/base/net_errors.h"
#include "services/network/public/mojom/udp_socket.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace network {
class UDPSocketFactoryTest : public testing::Test {
public:
UDPSocketFactoryTest() {}
~UDPSocketFactoryTest() override {}
private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
DISALLOW_COPY_AND_ASSIGN(UDPSocketFactoryTest);
};
class TestUDPSocketFactory : public UDPSocketFactory {
public:
TestUDPSocketFactory() {}
~TestUDPSocketFactory() override {}
void WaitUntilPipeBroken() { run_loop_.Run(); }
private:
// UDPSocketFactory implementation:
void OnPipeBroken(UDPSocket* client) override {
UDPSocketFactory::OnPipeBroken(client);
run_loop_.Quit();
}
base::RunLoop run_loop_;
};
// Tests that when client end of the pipe is closed, the factory implementation
// cleans up the server side of the pipe.
TEST_F(UDPSocketFactoryTest, ConnectionError) {
TestUDPSocketFactory factory;
mojom::UDPSocketReceiverPtr receiver_interface_ptr;
mojom::UDPSocketPtr socket_ptr;
factory.CreateUDPSocket(mojo::MakeRequest(&socket_ptr),
std::move(receiver_interface_ptr));
// Close client side of the pipe.
socket_ptr.reset();
factory.WaitUntilPipeBroken();
}
} // namespace network
This diff is collapsed.
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