blob: e6c3bf90572cf987ebbf75720555211f0a230f5d [file] [log] [blame]
// 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 <string>
#include <utility>
#include "base/optional.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/type_converter.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_errors.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/log/net_log.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
#include "net/ssl/ssl_config.h"
#include "net/ssl/ssl_config_service.h"
#include "net/url_request/url_request_context.h"
#include "services/network/ssl_config_type_converter.h"
#include "services/network/tls_client_socket.h"
#include "services/network/udp_socket.h"
namespace network {
SocketFactory::SocketFactory(net::NetLog* net_log,
net::URLRequestContext* url_request_context)
: net_log_(net_log),
client_socket_factory_(nullptr),
tls_socket_factory_(url_request_context, nullptr /*http_context*/) {
if (url_request_context->GetNetworkSessionContext()) {
client_socket_factory_ =
url_request_context->GetNetworkSessionContext()->client_socket_factory;
}
if (!client_socket_factory_)
client_socket_factory_ = net::ClientSocketFactory::GetDefaultFactory();
}
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,
mojom::TCPConnectedSocketOptionsPtr tcp_connected_socket_options,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest request,
mojom::SocketObserverPtr observer,
mojom::NetworkContext::CreateTCPConnectedSocketCallback callback) {
auto socket = std::make_unique<TCPConnectedSocket>(
std::move(observer), net_log_, &tls_socket_factory_,
client_socket_factory_, 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(tcp_connected_socket_options),
std::move(callback));
}
void SocketFactory::CreateTCPBoundSocket(
const net::IPEndPoint& local_addr,
const net::NetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPBoundSocketRequest request,
mojom::NetworkContext::CreateTCPBoundSocketCallback callback) {
auto socket =
std::make_unique<TCPBoundSocket>(this, net_log_, traffic_annotation);
net::IPEndPoint local_addr_out;
int result = socket->Bind(local_addr, &local_addr_out);
if (result != net::OK) {
std::move(callback).Run(result, base::nullopt);
return;
}
socket->set_id(tcp_bound_socket_bindings_.AddBinding(std::move(socket),
std::move(request)));
std::move(callback).Run(result, local_addr_out);
}
void SocketFactory::DestroyBoundSocket(mojo::BindingId bound_socket_id) {
tcp_bound_socket_bindings_.RemoveBinding(bound_socket_id);
}
void SocketFactory::OnBoundSocketListening(
mojo::BindingId bound_socket_id,
std::unique_ptr<TCPServerSocket> server_socket,
mojom::TCPServerSocketRequest server_socket_request) {
tcp_server_socket_bindings_.AddBinding(std::move(server_socket),
std::move(server_socket_request));
tcp_bound_socket_bindings_.RemoveBinding(bound_socket_id);
}
void SocketFactory::OnBoundSocketConnected(
mojo::BindingId bound_socket_id,
std::unique_ptr<TCPConnectedSocket> connected_socket,
mojom::TCPConnectedSocketRequest connected_socket_request) {
tcp_connected_socket_bindings_.AddBinding(
std::move(connected_socket), std::move(connected_socket_request));
tcp_bound_socket_bindings_.RemoveBinding(bound_socket_id);
}
void SocketFactory::OnAccept(std::unique_ptr<TCPConnectedSocket> socket,
mojom::TCPConnectedSocketRequest request) {
tcp_connected_socket_bindings_.AddBinding(std::move(socket),
std::move(request));
}
} // namespace network