Commit 5dc35e99 authored by John Abd-El-Malek's avatar John Abd-El-Malek Committed by Commit Bot

Convert P2P IPCs to Mojo.

Bug: 800212
Cq-Include-Trybots: luci.chromium.try:linux_mojo
Change-Id: I5d200862e81809af793d28b7751729a1824be76c
Reviewed-on: https://chromium-review.googlesource.com/1156566
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarSergey Ulanov <sergeyu@chromium.org>
Reviewed-by: default avatarNasko Oskov <nasko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580378}
parent 9296cc2f
......@@ -6,6 +6,7 @@
#include "chrome/common/common_param_traits_macros.h"
#include "chrome/common/instant_struct_traits.h"
#include "services/network/public/cpp/p2p_param_traits.h"
#undef CHROME_COMMON_MAC_APP_SHIM_MESSAGES_H_
#include "chrome/common/mac/app_shim_messages.h"
#ifndef CHROME_COMMON_MAC_APP_SHIM_MESSAGES_H_
......
......@@ -7,25 +7,27 @@
#include <stdint.h>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
#include "content/browser/renderer_host/p2p/socket_host_throttler.h"
#include "content/common/p2p_socket_type.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/base/network_change_notifier.h"
#include "services/network/public/cpp/p2p_socket_type.h"
#include "services/network/public/mojom/p2p.mojom.h"
namespace net {
struct MutableNetworkTrafficAnnotationTag;
class URLRequestContextGetter;
}
......@@ -38,17 +40,15 @@ namespace content {
class P2PSocketHost;
class P2PSocketDispatcherHost
: public content::BrowserMessageFilter,
public net::NetworkChangeNotifier::NetworkChangeObserver {
: public base::RefCountedThreadSafe<P2PSocketDispatcherHost,
BrowserThread::DeleteOnIOThread>,
public net::NetworkChangeNotifier::NetworkChangeObserver,
public network::mojom::P2PSocketManager {
public:
explicit P2PSocketDispatcherHost(net::URLRequestContextGetter* url_context);
P2PSocketDispatcherHost(int render_process_id,
net::URLRequestContextGetter* url_context);
// content::BrowserMessageFilter overrides.
void OnChannelClosing() override;
void OnDestruct() const override;
bool OnMessageReceived(const IPC::Message& message) override;
// net::NetworkChangeNotifier::NetworkChangeObserver interface.
// net::NetworkChangeNotifier::NetworkChangeObserver overrides.
void OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) override;
// Starts the RTP packet header dumping. Must be called on the IO thread.
......@@ -60,63 +60,60 @@ class P2PSocketDispatcherHost
// Stops the RTP packet header dumping. Must be Called on the UI thread.
void StopRtpDumpOnUIThread(bool incoming, bool outgoing);
protected:
~P2PSocketDispatcherHost() override;
void BindRequest(network::mojom::P2PSocketManagerRequest request);
void AddAcceptedConnection(
std::unique_ptr<P2PSocketHost> accepted_connection);
void SocketDestroyed(P2PSocketHost* socket);
private:
friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
friend class base::RefCountedThreadSafe<P2PSocketDispatcherHost>;
friend class base::DeleteHelper<P2PSocketDispatcherHost>;
friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
typedef std::map<int, std::unique_ptr<P2PSocketHost>> SocketsMap;
~P2PSocketDispatcherHost() override;
class DnsRequest;
P2PSocketHost* LookupSocket(int socket_id);
// Handlers for the messages coming from the renderer.
void OnStartNetworkNotifications();
void OnStopNetworkNotifications();
void OnGetHostAddress(const std::string& host_name, int32_t request_id);
void OnCreateSocket(P2PSocketType type,
int socket_id,
const net::IPEndPoint& local_address,
const P2PPortRange& port_range,
const P2PHostAndIPEndPoint& remote_address);
void OnAcceptIncomingTcpConnection(int listen_socket_id,
const net::IPEndPoint& remote_address,
int connected_socket_id);
void OnSend(
int socket_id,
const std::vector<char>& data,
const P2PPacketInfo& packet_info,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation);
void OnSetOption(int socket_id, P2PSocketOption option, int value);
void OnDestroySocket(int socket_id);
void DoGetNetworkList();
void SendNetworkList(const net::NetworkInterfaceList& list,
const net::IPAddress& default_ipv4_local_address,
const net::IPAddress& default_ipv6_local_address);
// network::mojom::P2PSocketManager overrides:
void StartNetworkNotifications(
network::mojom::P2PNetworkNotificationClientPtr client) override;
void GetHostAddress(const std::string& host_name,
network::mojom::P2PSocketManager::GetHostAddressCallback
callback) override;
void CreateSocket(network::P2PSocketType type,
const net::IPEndPoint& local_address,
const network::P2PPortRange& port_range,
const network::P2PHostAndIPEndPoint& remote_address,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest request) override;
void NetworkNotificationClientConnectionError();
// This connects a UDP socket to a public IP address and gets local
// address. Since it binds to the "any" address (0.0.0.0 or ::) internally, it
// retrieves the default local address.
net::IPAddress GetDefaultLocalAddress(int family);
void OnAddressResolved(DnsRequest* request,
const net::IPAddressList& addresses);
void OnAddressResolved(
DnsRequest* request,
network::mojom::P2PSocketManager::GetHostAddressCallback callback,
const net::IPAddressList& addresses);
void StopRtpDumpOnIOThread(bool incoming, bool outgoing);
int render_process_id_;
scoped_refptr<net::URLRequestContextGetter> url_context_;
// Initialized on browser IO thread.
std::unique_ptr<network::ProxyResolvingClientSocketFactory>
proxy_resolving_socket_factory_;
SocketsMap sockets_;
bool monitoring_networks_;
base::flat_map<P2PSocketHost*, std::unique_ptr<P2PSocketHost>> sockets_;
std::set<std::unique_ptr<DnsRequest>> dns_requests_;
P2PMessageThrottler throttler_;
......@@ -132,6 +129,10 @@ class P2PSocketDispatcherHost
// default local address involves creating a dummy socket.
const scoped_refptr<base::SequencedTaskRunner> network_list_task_runner_;
mojo::Binding<network::mojom::P2PSocketManager> binding_;
network::mojom::P2PNetworkNotificationClientPtr network_notification_client_;
DISALLOW_COPY_AND_ASSIGN(P2PSocketDispatcherHost);
};
......
......@@ -6,6 +6,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/sys_byteorder.h"
#include "content/browser/renderer_host/p2p/socket_dispatcher_host.h"
#include "content/browser/renderer_host/p2p/socket_host_tcp.h"
#include "content/browser/renderer_host/p2p/socket_host_tcp_server.h"
#include "content/browser/renderer_host/p2p/socket_host_udp.h"
......@@ -37,12 +38,12 @@ const uint32_t kStunMagicCookie = 0x2112A442;
const size_t kMinRtcpHeaderLength = 8;
const size_t kDtlsRecordHeaderLength = 13;
bool IsDtlsPacket(const char* data, size_t length) {
bool IsDtlsPacket(const int8_t* data, size_t length) {
const uint8_t* u = reinterpret_cast<const uint8_t*>(data);
return (length >= kDtlsRecordHeaderLength && (u[0] > 19 && u[0] < 64));
}
bool IsRtcpPacket(const char* data, size_t length) {
bool IsRtcpPacket(const int8_t* data, size_t length) {
if (length < kMinRtcpHeaderLength) {
return false;
}
......@@ -80,11 +81,13 @@ static SocketErrorCode MapNetErrorToSocketErrorCode(int net_err) {
namespace content {
P2PSocketHost::P2PSocketHost(IPC::Sender* message_sender,
int socket_id,
P2PSocketHost::P2PSocketHost(P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
ProtocolType protocol_type)
: message_sender_(message_sender),
id_(socket_id),
: socket_dispatcher_host_(socket_dispatcher_host),
client_(std::move(client)),
binding_(this, std::move(socket)),
state_(STATE_UNINITIALIZED),
dump_incoming_rtp_packet_(false),
dump_outgoing_rtp_packet_(false),
......@@ -94,6 +97,8 @@ P2PSocketHost::P2PSocketHost(IPC::Sender* message_sender,
send_bytes_delayed_max_(0),
send_bytes_delayed_cur_(0),
weak_ptr_factory_(this) {
binding_.set_connection_error_handler(base::BindOnce(
&P2PSocketHost::OnConnectionError, base::Unretained(this)));
}
P2PSocketHost::~P2PSocketHost() {
......@@ -115,13 +120,16 @@ P2PSocketHost::~P2PSocketHost() {
delay_rate);
}
}
if (socket_dispatcher_host_)
socket_dispatcher_host_->SocketDestroyed(this);
}
// Verifies that the packet |data| has a valid STUN header.
// static
bool P2PSocketHost::GetStunPacketType(
const char* data, int data_size, StunMessageType* type) {
bool P2PSocketHost::GetStunPacketType(const int8_t* data,
int data_size,
StunMessageType* type) {
if (data_size < kStunHeaderSize) {
return false;
}
......@@ -179,36 +187,40 @@ void P2PSocketHost::ReportSocketError(int result, const char* histogram_name) {
// static
P2PSocketHost* P2PSocketHost::Create(
IPC::Sender* message_sender,
int socket_id,
P2PSocketType type,
P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
network::P2PSocketType type,
net::URLRequestContextGetter* url_context,
network::ProxyResolvingClientSocketFactory* proxy_resolving_socket_factory,
P2PMessageThrottler* throttler) {
switch (type) {
case P2P_SOCKET_UDP:
case network::P2P_SOCKET_UDP:
return new P2PSocketHostUdp(
message_sender, socket_id, throttler,
url_context->GetURLRequestContext()->net_log());
case P2P_SOCKET_TCP_SERVER:
return new P2PSocketHostTcpServer(
message_sender, socket_id, P2P_SOCKET_TCP_CLIENT);
case P2P_SOCKET_STUN_TCP_SERVER:
return new P2PSocketHostTcpServer(
message_sender, socket_id, P2P_SOCKET_STUN_TCP_CLIENT);
case P2P_SOCKET_TCP_CLIENT:
case P2P_SOCKET_SSLTCP_CLIENT:
case P2P_SOCKET_TLS_CLIENT:
return new P2PSocketHostTcp(message_sender, socket_id, type, url_context,
socket_dispatcher_host, std::move(client), std::move(socket),
throttler, url_context->GetURLRequestContext()->net_log());
case network::P2P_SOCKET_TCP_SERVER:
return new P2PSocketHostTcpServer(socket_dispatcher_host,
std::move(client), std::move(socket),
network::P2P_SOCKET_TCP_CLIENT);
case network::P2P_SOCKET_STUN_TCP_SERVER:
return new P2PSocketHostTcpServer(socket_dispatcher_host,
std::move(client), std::move(socket),
network::P2P_SOCKET_STUN_TCP_CLIENT);
case network::P2P_SOCKET_TCP_CLIENT:
case network::P2P_SOCKET_SSLTCP_CLIENT:
case network::P2P_SOCKET_TLS_CLIENT:
return new P2PSocketHostTcp(socket_dispatcher_host, std::move(client),
std::move(socket), type, url_context,
proxy_resolving_socket_factory);
case P2P_SOCKET_STUN_TCP_CLIENT:
case P2P_SOCKET_STUN_SSLTCP_CLIENT:
case P2P_SOCKET_STUN_TLS_CLIENT:
return new P2PSocketHostStunTcp(message_sender, socket_id, type,
url_context,
case network::P2P_SOCKET_STUN_TCP_CLIENT:
case network::P2P_SOCKET_STUN_SSLTCP_CLIENT:
case network::P2P_SOCKET_STUN_TLS_CLIENT:
return new P2PSocketHostStunTcp(socket_dispatcher_host, std::move(client),
std::move(socket), type, url_context,
proxy_resolving_socket_factory);
}
......@@ -252,7 +264,15 @@ void P2PSocketHost::StopRtpDump(bool incoming, bool outgoing) {
}
}
void P2PSocketHost::DumpRtpPacket(const char* packet,
network::mojom::P2PSocketClientPtr P2PSocketHost::ReleaseClientForTesting() {
return std::move(client_);
}
network::mojom::P2PSocketRequest P2PSocketHost::ReleaseBindingForTesting() {
return binding_.Unbind();
}
void P2PSocketHost::DumpRtpPacket(const int8_t* packet,
size_t length,
bool incoming) {
if (IsDtlsPacket(packet, length) || IsRtcpPacket(packet, length)) {
......@@ -329,4 +349,8 @@ void P2PSocketHost::DecrementDelayedBytes(uint32_t size) {
DCHECK_GE(send_bytes_delayed_cur_, 0);
}
void P2PSocketHost::OnConnectionError() {
delete this;
}
} // namespace content
......@@ -13,15 +13,13 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "content/common/p2p_socket_type.h"
#include "content/public/browser/render_process_host.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/ip_endpoint.h"
#include "net/socket/datagram_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
namespace IPC {
class Sender;
}
#include "services/network/public/cpp/p2p_socket_type.h"
#include "services/network/public/mojom/p2p.mojom.h"
namespace net {
class URLRequestContextGetter;
......@@ -31,27 +29,26 @@ namespace network {
class ProxyResolvingClientSocketFactory;
}
namespace rtc {
struct PacketOptions;
}
namespace content {
class P2PSocketDispatcherHost;
class P2PMessageThrottler;
// Base class for P2P sockets.
class CONTENT_EXPORT P2PSocketHost {
class CONTENT_EXPORT P2PSocketHost : public network::mojom::P2PSocket {
public:
static const int kStunHeaderSize = 20;
static const size_t kMaximumPacketSize = 32768;
// Creates P2PSocketHost of the specific type.
static P2PSocketHost* Create(IPC::Sender* message_sender,
int socket_id,
P2PSocketType type,
static P2PSocketHost* Create(P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
network::P2PSocketType type,
net::URLRequestContextGetter* url_context,
network::ProxyResolvingClientSocketFactory*
proxy_resolving_socket_factory,
P2PMessageThrottler* throttler);
virtual ~P2PSocketHost();
~P2PSocketHost() override;
// Initalizes the socket. Returns false when initialization fails.
// |min_port| and |max_port| specify the valid range of allowed ports.
......@@ -65,21 +62,7 @@ class CONTENT_EXPORT P2PSocketHost {
virtual bool Init(const net::IPEndPoint& local_address,
uint16_t min_port,
uint16_t max_port,
const P2PHostAndIPEndPoint& remote_address) = 0;
// Sends |data| on the socket to |to|.
virtual void Send(
const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
uint64_t packet_id,
const net::NetworkTrafficAnnotationTag traffic_annotation) = 0;
virtual std::unique_ptr<P2PSocketHost> AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address,
int id) = 0;
virtual bool SetOption(P2PSocketOption option, int value) = 0;
const network::P2PHostAndIPEndPoint& remote_address) = 0;
void StartRtpDump(
bool incoming,
......@@ -87,6 +70,9 @@ class CONTENT_EXPORT P2PSocketHost {
const RenderProcessHost::WebRtcRtpPacketCallback& packet_callback);
void StopRtpDump(bool incoming, bool outgoing);
network::mojom::P2PSocketClientPtr ReleaseClientForTesting();
network::mojom::P2PSocketRequest ReleaseBindingForTesting();
protected:
friend class P2PSocketHostTcpTestBase;
......@@ -126,20 +112,22 @@ class CONTENT_EXPORT P2PSocketHost {
STATE_ERROR,
};
P2PSocketHost(IPC::Sender* message_sender,
int socket_id,
P2PSocketHost(P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
ProtocolType protocol_type);
// Verifies that the packet |data| has a valid STUN header. In case
// of success stores type of the message in |type|.
static bool GetStunPacketType(const char* data, int data_size,
static bool GetStunPacketType(const int8_t* data,
int data_size,
StunMessageType* type);
static bool IsRequestOrResponse(StunMessageType type);
static void ReportSocketError(int result, const char* histogram_name);
// Calls |packet_dump_callback_| to record the RTP header.
void DumpRtpPacket(const char* packet, size_t length, bool incoming);
void DumpRtpPacket(const int8_t* packet, size_t length, bool incoming);
// A helper to dump the packet on the IO thread.
void DumpRtpPacketOnIOThread(std::unique_ptr<uint8_t[]> packet_header,
......@@ -153,8 +141,9 @@ class CONTENT_EXPORT P2PSocketHost {
void IncrementDelayedBytes(uint32_t size);
void DecrementDelayedBytes(uint32_t size);
IPC::Sender* message_sender_;
int id_;
P2PSocketDispatcherHost* socket_dispatcher_host_;
network::mojom::P2PSocketClientPtr client_;
mojo::Binding<network::mojom::P2PSocket> binding_;
State state_;
bool dump_incoming_rtp_packet_;
bool dump_outgoing_rtp_packet_;
......@@ -163,6 +152,7 @@ class CONTENT_EXPORT P2PSocketHost {
ProtocolType protocol_type_;
private:
void OnConnectionError();
// Track total delayed packets for calculating how many packets are
// delayed by system at the end of call.
uint32_t send_packets_delayed_total_;
......
......@@ -15,10 +15,10 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/browser/renderer_host/p2p/socket_host.h"
#include "content/common/p2p_socket_type.h"
#include "net/base/completion_callback.h"
#include "net/base/ip_endpoint.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/p2p_socket_type.h"
namespace network {
class ProxyResolvingClientSocketFactory;
......@@ -35,9 +35,10 @@ namespace content {
class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost {
public:
P2PSocketHostTcpBase(IPC::Sender* message_sender,
int socket_id,
P2PSocketType type,
P2PSocketHostTcpBase(P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
network::P2PSocketType type,
net::URLRequestContextGetter* url_context,
network::ProxyResolvingClientSocketFactory*
proxy_resolving_socket_factory);
......@@ -50,16 +51,18 @@ class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost {
bool Init(const net::IPEndPoint& local_address,
uint16_t min_port,
uint16_t max_port,
const P2PHostAndIPEndPoint& remote_address) override;
void Send(const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
uint64_t packet_id,
const net::NetworkTrafficAnnotationTag traffic_annotation) override;
std::unique_ptr<P2PSocketHost> AcceptIncomingTcpConnection(
const network::P2PHostAndIPEndPoint& remote_address) override;
// network::mojom::P2PSocket implementation:
void AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address,
int id) override;
bool SetOption(P2PSocketOption option, int value) override;
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket) override;
void Send(const std::vector<int8_t>& data,
const network::P2PPacketInfo& packet_info,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
override;
void SetOption(network::P2PSocketOption option, int32_t value) override;
protected:
struct SendBuffer {
......@@ -79,12 +82,12 @@ class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost {
virtual int ProcessInput(char* input, int input_len) = 0;
virtual void DoSend(
const net::IPEndPoint& to,
const std::vector<char>& data,
const std::vector<int8_t>& data,
const rtc::PacketOptions& options,
const net::NetworkTrafficAnnotationTag traffic_annotation) = 0;
void WriteOrQueue(SendBuffer& send_buffer);
void OnPacket(const std::vector<char>& data);
void OnPacket(const std::vector<int8_t>& data);
void OnError();
private:
......@@ -106,7 +109,7 @@ class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost {
void OnOpen();
bool DoSendSocketCreateMsg();
P2PHostAndIPEndPoint remote_address_;
network::P2PHostAndIPEndPoint remote_address_;
std::unique_ptr<net::StreamSocket> socket_;
scoped_refptr<net::GrowableIOBuffer> read_buffer_;
......@@ -116,7 +119,7 @@ class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost {
bool write_pending_;
bool connected_;
P2PSocketType type_;
network::P2PSocketType type_;
scoped_refptr<net::URLRequestContextGetter> url_context_;
network::ProxyResolvingClientSocketFactory* proxy_resolving_socket_factory_;
......@@ -125,9 +128,10 @@ class CONTENT_EXPORT P2PSocketHostTcpBase : public P2PSocketHost {
class CONTENT_EXPORT P2PSocketHostTcp : public P2PSocketHostTcpBase {
public:
P2PSocketHostTcp(IPC::Sender* message_sender,
int socket_id,
P2PSocketType type,
P2PSocketHostTcp(P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
network::P2PSocketType type,
net::URLRequestContextGetter* url_context,
network::ProxyResolvingClientSocketFactory*
proxy_resolving_socket_factory);
......@@ -138,7 +142,7 @@ class CONTENT_EXPORT P2PSocketHostTcp : public P2PSocketHostTcpBase {
int ProcessInput(char* input, int input_len) override;
void DoSend(
const net::IPEndPoint& to,
const std::vector<char>& data,
const std::vector<int8_t>& data,
const rtc::PacketOptions& options,
const net::NetworkTrafficAnnotationTag traffic_annotation) override;
......@@ -152,9 +156,10 @@ class CONTENT_EXPORT P2PSocketHostTcp : public P2PSocketHostTcpBase {
// Formatting of messages is defined in RFC5766.
class CONTENT_EXPORT P2PSocketHostStunTcp : public P2PSocketHostTcpBase {
public:
P2PSocketHostStunTcp(IPC::Sender* message_sender,
int socket_id,
P2PSocketType type,
P2PSocketHostStunTcp(P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
network::P2PSocketType type,
net::URLRequestContextGetter* url_context,
network::ProxyResolvingClientSocketFactory*
proxy_resolving_socket_factory);
......@@ -165,12 +170,12 @@ class CONTENT_EXPORT P2PSocketHostStunTcp : public P2PSocketHostTcpBase {
int ProcessInput(char* input, int input_len) override;
void DoSend(
const net::IPEndPoint& to,
const std::vector<char>& data,
const std::vector<int8_t>& data,
const rtc::PacketOptions& options,
const net::NetworkTrafficAnnotationTag traffic_annotation) override;
private:
int GetExpectedPacketSize(const char* data, int len, int* pad_bytes);
int GetExpectedPacketSize(const int8_t* data, int len, int* pad_bytes);
DISALLOW_COPY_AND_ASSIGN(P2PSocketHostStunTcp);
};
......
......@@ -8,12 +8,13 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "content/browser/renderer_host/p2p/socket_dispatcher_host.h"
#include "content/browser/renderer_host/p2p/socket_host_tcp.h"
#include "content/common/p2p_messages.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_source.h"
#include "net/socket/stream_socket.h"
#include "services/network/public/cpp/p2p_param_traits.h"
namespace {
const int kListenBacklog = 5;
......@@ -21,10 +22,15 @@ const int kListenBacklog = 5;
namespace content {
P2PSocketHostTcpServer::P2PSocketHostTcpServer(IPC::Sender* message_sender,
int socket_id,
P2PSocketType client_type)
: P2PSocketHost(message_sender, socket_id, P2PSocketHost::TCP),
P2PSocketHostTcpServer::P2PSocketHostTcpServer(
P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
network::P2PSocketType client_type)
: P2PSocketHost(socket_dispatcher_host,
std::move(client),
std::move(socket),
P2PSocketHost::TCP),
client_type_(client_type),
socket_(new net::TCPServerSocket(nullptr, net::NetLogSource())),
accept_callback_(base::BindRepeating(&P2PSocketHostTcpServer::OnAccepted,
......@@ -38,10 +44,11 @@ P2PSocketHostTcpServer::~P2PSocketHostTcpServer() {
}
// TODO(guidou): Add support for port range.
bool P2PSocketHostTcpServer::Init(const net::IPEndPoint& local_address,
uint16_t min_port,
uint16_t max_port,
const P2PHostAndIPEndPoint& remote_address) {
bool P2PSocketHostTcpServer::Init(
const net::IPEndPoint& local_address,
uint16_t min_port,
uint16_t max_port,
const network::P2PHostAndIPEndPoint& remote_address) {
DCHECK_EQ(state_, STATE_UNINITIALIZED);
int result = socket_->Listen(local_address, kListenBacklog);
......@@ -63,17 +70,46 @@ bool P2PSocketHostTcpServer::Init(const net::IPEndPoint& local_address,
state_ = STATE_OPEN;
// NOTE: Remote address can be empty as socket is just listening
// in this state.
message_sender_->Send(new P2PMsg_OnSocketCreated(
id_, local_address_, remote_address.ip_address));
client_->SocketCreated(local_address_, remote_address.ip_address);
DoAccept();
return true;
}
std::unique_ptr<P2PSocketHostTcpBase>
P2PSocketHostTcpServer::AcceptIncomingTcpConnectionInternal(
const net::IPEndPoint& remote_address,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest request) {
auto it = accepted_sockets_.find(remote_address);
if (it == accepted_sockets_.end())
return nullptr;
std::unique_ptr<net::StreamSocket> socket = std::move(it->second);
accepted_sockets_.erase(it);
std::unique_ptr<P2PSocketHostTcpBase> result;
if (client_type_ == network::P2P_SOCKET_TCP_CLIENT) {
result.reset(new P2PSocketHostTcp(socket_dispatcher_host_,
std::move(client), std::move(request),
client_type_, nullptr, nullptr));
} else {
result.reset(new P2PSocketHostStunTcp(socket_dispatcher_host_,
std::move(client), std::move(request),
client_type_, nullptr, nullptr));
}
if (!result->InitAccepted(remote_address, std::move(socket)))
return nullptr;
return result;
}
void P2PSocketHostTcpServer::OnError() {
socket_.reset();
if (state_ == STATE_UNINITIALIZED || state_ == STATE_OPEN)
message_sender_->Send(new P2PMsg_OnError(id_));
if (state_ == STATE_UNINITIALIZED || state_ == STATE_OPEN) {
binding_.Close();
client_.reset();
}
state_ = STATE_ERROR;
}
......@@ -103,8 +139,7 @@ void P2PSocketHostTcpServer::HandleAcceptResult(int result) {
return;
}
accepted_sockets_[address] = std::move(accept_socket_);
message_sender_->Send(
new P2PMsg_OnIncomingTcpConnection(id_, address));
client_->IncomingTcpConnection(address);
}
void P2PSocketHostTcpServer::OnAccepted(int result) {
......@@ -113,44 +148,28 @@ void P2PSocketHostTcpServer::OnAccepted(int result) {
DoAccept();
}
void P2PSocketHostTcpServer::Send(
const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
uint64_t packet_id,
const net::NetworkTrafficAnnotationTag traffic_annotation) {
NOTREACHED();
OnError();
}
std::unique_ptr<P2PSocketHost>
P2PSocketHostTcpServer::AcceptIncomingTcpConnection(
void P2PSocketHostTcpServer::AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address,
int id) {
auto it = accepted_sockets_.find(remote_address);
if (it == accepted_sockets_.end())
return nullptr;
std::unique_ptr<net::StreamSocket> socket = std::move(it->second);
accepted_sockets_.erase(it);
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest request) {
std::unique_ptr<P2PSocketHostTcpBase> socket =
AcceptIncomingTcpConnectionInternal(remote_address, std::move(client),
std::move(request));
if (socket)
socket_dispatcher_host_->AddAcceptedConnection(std::move(socket));
}
std::unique_ptr<P2PSocketHostTcpBase> result;
if (client_type_ == P2P_SOCKET_TCP_CLIENT) {
result.reset(new P2PSocketHostTcp(message_sender_, id, client_type_,
nullptr, nullptr));
} else {
result.reset(new P2PSocketHostStunTcp(message_sender_, id, client_type_,
nullptr, nullptr));
}
if (!result->InitAccepted(remote_address, std::move(socket)))
return nullptr;
return std::move(result);
void P2PSocketHostTcpServer::Send(
const std::vector<int8_t>& data,
const network::P2PPacketInfo& packet_info,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
NOTREACHED();
delete this;
}
bool P2PSocketHostTcpServer::SetOption(P2PSocketOption option,
int value) {
void P2PSocketHostTcpServer::SetOption(network::P2PSocketOption option,
int32_t value) {
// Currently we don't have use case tcp server sockets are used for p2p.
return false;
}
} // namespace content
......@@ -15,43 +15,52 @@
#include "base/macros.h"
#include "content/browser/renderer_host/p2p/socket_host.h"
#include "content/common/content_export.h"
#include "content/common/p2p_socket_type.h"
#include "ipc/ipc_sender.h"
#include "net/base/completion_repeating_callback.h"
#include "net/socket/tcp_server_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/p2p_socket_type.h"
namespace net {
class StreamSocket;
} // namespace net
namespace content {
class P2PSocketHostTcpBase;
class CONTENT_EXPORT P2PSocketHostTcpServer : public P2PSocketHost {
public:
P2PSocketHostTcpServer(IPC::Sender* message_sender,
int socket_id,
P2PSocketType client_type);
P2PSocketHostTcpServer(P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
network::P2PSocketType client_type);
~P2PSocketHostTcpServer() override;
// P2PSocketHost overrides.
bool Init(const net::IPEndPoint& local_address,
uint16_t min_port,
uint16_t max_port,
const P2PHostAndIPEndPoint& remote_address) override;
void Send(const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
uint64_t packet_id,
const net::NetworkTrafficAnnotationTag traffic_annotation) override;
std::unique_ptr<P2PSocketHost> AcceptIncomingTcpConnection(
const network::P2PHostAndIPEndPoint& remote_address) override;
// network::mojom::P2PSocket implementation:
void AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address,
int id) override;
bool SetOption(P2PSocketOption option, int value) override;
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest request) override;
void Send(const std::vector<int8_t>& data,
const network::P2PPacketInfo& packet_info,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
override;
void SetOption(network::P2PSocketOption option, int32_t value) override;
private:
friend class P2PSocketHostTcpServerTest;
std::unique_ptr<P2PSocketHostTcpBase> AcceptIncomingTcpConnectionInternal(
const net::IPEndPoint& remote_address,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest request);
void OnError();
void DoAccept();
......@@ -60,7 +69,7 @@ class CONTENT_EXPORT P2PSocketHostTcpServer : public P2PSocketHost {
// Callback for Accept().
void OnAccepted(int result);
const P2PSocketType client_type_;
const network::P2PSocketType client_type_;
std::unique_ptr<net::ServerSocket> socket_;
net::IPEndPoint local_address_;
......
......@@ -9,6 +9,8 @@
#include <list>
#include <utility>
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "content/browser/renderer_host/p2p/socket_host_tcp.h"
#include "content/browser/renderer_host/p2p/socket_host_test_utils.h"
#include "net/base/completion_once_callback.h"
......@@ -85,31 +87,50 @@ namespace content {
class P2PSocketHostTcpServerTest : public testing::Test {
protected:
void SetUp() override {
network::mojom::P2PSocketClientPtr socket_client;
auto socket_client_request = mojo::MakeRequest(&socket_client);
network::mojom::P2PSocketPtr socket;
auto socket_request = mojo::MakeRequest(&socket);
fake_client_.reset(new FakeSocketClient(std::move(socket),
std::move(socket_client_request)));
socket_ = new FakeServerSocket();
socket_host_.reset(
new P2PSocketHostTcpServer(&sender_, 0, P2P_SOCKET_TCP_CLIENT));
socket_host_.reset(new P2PSocketHostTcpServer(
nullptr, std::move(socket_client), std::move(socket_request),
network::P2P_SOCKET_TCP_CLIENT));
socket_host_->socket_.reset(socket_);
EXPECT_CALL(
sender_,
Send(MatchMessage(static_cast<uint32_t>(P2PMsg_OnSocketCreated::ID))))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
EXPECT_CALL(*fake_client_.get(), SocketCreated(_, _)).Times(1);
P2PHostAndIPEndPoint dest;
network::P2PHostAndIPEndPoint dest;
dest.ip_address = ParseAddress(kTestIpAddress1, kTestPort1);
socket_host_->Init(ParseAddress(kTestLocalIpAddress, 0), 0, 0, dest);
EXPECT_TRUE(socket_->listening());
base::RunLoop().RunUntilIdle();
}
// Needed by the chilt classes because only this class is a friend
// Needed by the child classes because only this class is a friend
// of P2PSocketHostTcp.
net::StreamSocket* GetSocketFormTcpSocketHost(P2PSocketHostTcp* host) {
net::StreamSocket* GetSocketFormTcpSocketHost(P2PSocketHostTcpBase* host) {
return host->socket_.get();
}
MockIPCSender sender_;
std::unique_ptr<P2PSocketHostTcpBase> AcceptIncomingTcpConnection(
const net::IPEndPoint& address) {
network::mojom::P2PSocketClientPtr socket_client;
auto socket_client_request = mojo::MakeRequest(&socket_client);
network::mojom::P2PSocketPtr socket;
auto socket_request = mojo::MakeRequest(&socket);
return socket_host_->AcceptIncomingTcpConnectionInternal(
address, std::move(socket_client), std::move(socket_request));
}
base::test::ScopedTaskEnvironment scoped_task_environment_;
FakeServerSocket* socket_; // Owned by |socket_host_|.
std::unique_ptr<FakeSocketClient> fake_client_;
std::unique_ptr<P2PSocketHostTcpServer> socket_host_;
};
......@@ -120,17 +141,16 @@ TEST_F(P2PSocketHostTcpServerTest, Accept) {
net::IPEndPoint addr = ParseAddress(kTestIpAddress1, kTestPort1);
incoming->SetPeerAddress(addr);
EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr)))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
EXPECT_CALL(*fake_client_.get(), IncomingTcpConnection(addr)).Times(1);
socket_->AddIncoming(incoming);
const int kAcceptedSocketId = 1;
std::unique_ptr<P2PSocketHost> new_host(
socket_host_->AcceptIncomingTcpConnection(addr, kAcceptedSocketId));
std::unique_ptr<P2PSocketHostTcpBase> new_host(
AcceptIncomingTcpConnection(addr));
ASSERT_TRUE(new_host.get() != nullptr);
EXPECT_EQ(incoming, GetSocketFormTcpSocketHost(
reinterpret_cast<P2PSocketHostTcp*>(new_host.get())));
EXPECT_EQ(incoming, GetSocketFormTcpSocketHost(new_host.get()));
new_host.release(); // Deletes itself on connection error.
base::RunLoop().RunUntilIdle();
}
// Accept 2 simultaneous connections.
......@@ -144,26 +164,25 @@ TEST_F(P2PSocketHostTcpServerTest, Accept2) {
net::IPEndPoint addr2 = ParseAddress(kTestIpAddress2, kTestPort2);
incoming2->SetPeerAddress(addr2);
EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr1)))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
EXPECT_CALL(sender_, Send(MatchIncomingSocketMessage(addr2)))
.WillOnce(DoAll(DeleteArg<0>(), Return(true)));
EXPECT_CALL(*fake_client_.get(), IncomingTcpConnection(addr1)).Times(1);
EXPECT_CALL(*fake_client_.get(), IncomingTcpConnection(addr2)).Times(1);
socket_->AddIncoming(incoming1);
socket_->AddIncoming(incoming2);
const int kAcceptedSocketId1 = 1;
const int kAcceptedSocketId2 = 2;
std::unique_ptr<P2PSocketHost> new_host1(
socket_host_->AcceptIncomingTcpConnection(addr1, kAcceptedSocketId1));
std::unique_ptr<P2PSocketHostTcpBase> new_host1(
AcceptIncomingTcpConnection(addr1));
ASSERT_TRUE(new_host1.get() != nullptr);
EXPECT_EQ(incoming1, GetSocketFormTcpSocketHost(
reinterpret_cast<P2PSocketHostTcp*>(new_host1.get())));
std::unique_ptr<P2PSocketHost> new_host2(
socket_host_->AcceptIncomingTcpConnection(addr2, kAcceptedSocketId2));
std::unique_ptr<P2PSocketHostTcpBase> new_host2(
AcceptIncomingTcpConnection(addr2));
ASSERT_TRUE(new_host2.get() != nullptr);
EXPECT_EQ(incoming2, GetSocketFormTcpSocketHost(
reinterpret_cast<P2PSocketHostTcp*>(new_host2.get())));
new_host1.release(); // Deletes itself on connection error.
new_host2.release(); // Deletes itself on connection error.
base::RunLoop().RunUntilIdle();
}
} // namespace content
......@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/sys_byteorder.h"
#include "base/test/bind_test_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/completion_callback.h"
#include "net/base/io_buffer.h"
......@@ -178,7 +179,17 @@ int64_t FakeSocket::GetTotalReceivedBytes() const {
return 0;
}
void CreateRandomPacket(std::vector<char>* packet) {
FakeSocketClient::FakeSocketClient(
network::mojom::P2PSocketPtr socket,
network::mojom::P2PSocketClientRequest client_request)
: socket_(std::move(socket)), binding_(this, std::move(client_request)) {
binding_.set_connection_error_handler(
base::BindLambdaForTesting([&]() { connection_error_ = true; }));
}
FakeSocketClient::~FakeSocketClient() {}
void CreateRandomPacket(std::vector<int8_t>* packet) {
size_t size = kStunHeaderSize + rand() % 1000;
packet->resize(size);
for (size_t i = 0; i < size; i++) {
......@@ -189,7 +200,7 @@ void CreateRandomPacket(std::vector<char>* packet) {
(*packet)[0] = (*packet)[0] | 0x80;
}
static void CreateStunPacket(std::vector<char>* packet, uint16_t type) {
static void CreateStunPacket(std::vector<int8_t>* packet, uint16_t type) {
CreateRandomPacket(packet);
*reinterpret_cast<uint16_t*>(&*packet->begin()) = base::HostToNet16(type);
*reinterpret_cast<uint16_t*>(&*packet->begin() + 2) =
......@@ -198,15 +209,15 @@ static void CreateStunPacket(std::vector<char>* packet, uint16_t type) {
base::HostToNet32(kStunMagicCookie);
}
void CreateStunRequest(std::vector<char>* packet) {
void CreateStunRequest(std::vector<int8_t>* packet) {
CreateStunPacket(packet, kStunBindingRequest);
}
void CreateStunResponse(std::vector<char>* packet) {
void CreateStunResponse(std::vector<int8_t>* packet) {
CreateStunPacket(packet, kStunBindingResponse);
}
void CreateStunError(std::vector<char>* packet) {
void CreateStunError(std::vector<int8_t>* packet) {
CreateStunPacket(packet, kStunBindingError);
}
......
......@@ -11,12 +11,14 @@
#include <tuple>
#include <vector>
#include "content/common/p2p_messages.h"
#include "ipc/ipc_sender.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/net_errors.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/stream_socket.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/network/public/cpp/p2p_param_traits.h"
#include "services/network/public/mojom/p2p.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -98,10 +100,34 @@ class FakeSocket : public net::StreamSocket {
net::NetLogWithSource net_log_;
};
void CreateRandomPacket(std::vector<char>* packet);
void CreateStunRequest(std::vector<char>* packet);
void CreateStunResponse(std::vector<char>* packet);
void CreateStunError(std::vector<char>* packet);
class FakeSocketClient : public network::mojom::P2PSocketClient {
public:
FakeSocketClient(network::mojom::P2PSocketPtr socket,
network::mojom::P2PSocketClientRequest client_request);
~FakeSocketClient() override;
// network::mojom::P2PSocketClient interface.
MOCK_METHOD2(SocketCreated,
void(const net::IPEndPoint&, const net::IPEndPoint&));
MOCK_METHOD1(SendComplete, void(const network::P2PSendPacketMetrics&));
MOCK_METHOD1(IncomingTcpConnection, void(const net::IPEndPoint&));
MOCK_METHOD3(DataReceived,
void(const net::IPEndPoint&,
const std::vector<int8_t>&,
base::TimeTicks));
bool connection_error() { return connection_error_; }
private:
network::mojom::P2PSocketPtr socket_;
mojo::Binding<network::mojom::P2PSocketClient> binding_;
bool connection_error_ = false;
};
void CreateRandomPacket(std::vector<int8_t>* packet);
void CreateStunRequest(std::vector<int8_t>* packet);
void CreateStunResponse(std::vector<int8_t>* packet);
void CreateStunError(std::vector<int8_t>* packet);
net::IPEndPoint ParseAddress(const std::string& ip_str, uint16_t port);
......@@ -109,32 +135,10 @@ MATCHER_P(MatchMessage, type, "") {
return arg->type() == type;
}
MATCHER_P(MatchPacketMessage, packet_content, "") {
if (arg->type() != P2PMsg_OnDataReceived::ID)
return false;
P2PMsg_OnDataReceived::Param params;
P2PMsg_OnDataReceived::Read(arg, &params);
return std::get<2>(params) == packet_content;
}
MATCHER_P(MatchIncomingSocketMessage, address, "") {
if (arg->type() != P2PMsg_OnIncomingTcpConnection::ID)
return false;
P2PMsg_OnIncomingTcpConnection::Param params;
P2PMsg_OnIncomingTcpConnection::Read(
arg, &params);
return std::get<1>(params) == address;
}
MATCHER_P2(MatchSendPacketMetrics, rtc_packet_id, test_start_time, "") {
if (arg->type() != P2PMsg_OnSendComplete::ID)
return false;
P2PMsg_OnSendComplete::Param params;
P2PMsg_OnSendComplete::Read(arg, &params);
return std::get<1>(params).rtc_packet_id == rtc_packet_id &&
std::get<1>(params).send_time >= test_start_time &&
std::get<1>(params).send_time <= base::TimeTicks::Now();
return arg.rtc_packet_id == rtc_packet_id &&
arg.send_time >= test_start_time &&
arg.send_time <= base::TimeTicks::Now();
}
#endif // CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_TEST_UTILS_H_
......@@ -19,11 +19,11 @@
#include "base/memory/ref_counted.h"
#include "content/browser/renderer_host/p2p/socket_host.h"
#include "content/common/content_export.h"
#include "content/common/p2p_socket_type.h"
#include "net/base/ip_endpoint.h"
#include "net/socket/diff_serv_code_point.h"
#include "net/socket/udp_server_socket.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/p2p_socket_type.h"
#include "third_party/webrtc/rtc_base/asyncpacketsocket.h"
namespace net {
......@@ -39,13 +39,15 @@ class CONTENT_EXPORT P2PSocketHostUdp : public P2PSocketHost {
typedef base::Callback<std::unique_ptr<net::DatagramServerSocket>(
net::NetLog* net_log)>
DatagramServerSocketFactory;
P2PSocketHostUdp(IPC::Sender* message_sender,
int socket_id,
P2PSocketHostUdp(P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
P2PMessageThrottler* throttler,
net::NetLog* net_log,
const DatagramServerSocketFactory& socket_factory);
P2PSocketHostUdp(IPC::Sender* message_sender,
int socket_id,
P2PSocketHostUdp(P2PSocketDispatcherHost* socket_dispatcher_host,
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket,
P2PMessageThrottler* throttler,
net::NetLog* net_log);
~P2PSocketHostUdp() override;
......@@ -54,16 +56,18 @@ class CONTENT_EXPORT P2PSocketHostUdp : public P2PSocketHost {
bool Init(const net::IPEndPoint& local_address,
uint16_t min_port,
uint16_t max_port,
const P2PHostAndIPEndPoint& remote_address) override;
void Send(const net::IPEndPoint& to,
const std::vector<char>& data,
const rtc::PacketOptions& options,
uint64_t packet_id,
const net::NetworkTrafficAnnotationTag traffic_annotation) override;
std::unique_ptr<P2PSocketHost> AcceptIncomingTcpConnection(
const network::P2PHostAndIPEndPoint& remote_address) override;
// network::mojom::P2PSocket implementation:
void AcceptIncomingTcpConnection(
const net::IPEndPoint& remote_address,
int id) override;
bool SetOption(P2PSocketOption option, int value) override;
network::mojom::P2PSocketClientPtr client,
network::mojom::P2PSocketRequest socket) override;
void Send(const std::vector<int8_t>& data,
const network::P2PPacketInfo& packet_info,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
override;
void SetOption(network::P2PSocketOption option, int32_t value) override;
private:
friend class P2PSocketHostUdpTest;
......@@ -72,7 +76,7 @@ class CONTENT_EXPORT P2PSocketHostUdp : public P2PSocketHost {
struct PendingPacket {
PendingPacket(const net::IPEndPoint& to,
const std::vector<char>& content,
const std::vector<int8_t>& content,
const rtc::PacketOptions& options,
uint64_t id,
const net::NetworkTrafficAnnotationTag traffic_annotation);
......
......@@ -1851,8 +1851,7 @@ void RenderProcessHostImpl::CreateMessageFilters() {
#endif
p2p_socket_dispatcher_host_ =
new P2PSocketDispatcherHost(request_context.get());
AddFilter(p2p_socket_dispatcher_host_.get());
new P2PSocketDispatcherHost(GetID(), request_context.get());
AddFilter(new TraceMessageFilter(GetID()));
AddFilter(new ResolveProxyMsgHelper(GetID()));
......@@ -2039,6 +2038,9 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
base::Unretained(storage_partition_impl_->GetAppCacheService()),
GetID()));
registry->AddInterface(base::BindRepeating(
&P2PSocketDispatcherHost::BindRequest, p2p_socket_dispatcher_host_));
AddUIThreadInterface(registry.get(), base::Bind(&FieldTrialRecorder::Create));
associated_interfaces_ =
......
......@@ -223,8 +223,6 @@ source_set("common") {
"notifications/notification_struct_traits.cc",
"notifications/notification_struct_traits.h",
"origin_util.cc",
"p2p_messages.h",
"p2p_socket_type.h",
"page_messages.h",
"page_state_serialization.cc",
"page_state_serialization.h",
......@@ -361,8 +359,6 @@ source_set("common") {
"//third_party/angle:angle_gpu_info_util",
"//third_party/boringssl",
"//third_party/icu",
"//third_party/webrtc/rtc_base:rtc_base",
"//third_party/webrtc_overrides",
"//ui/base",
"//ui/base/ime",
"//ui/display",
......
......@@ -97,12 +97,6 @@
#error "Failed to include content/common/input/sync_compositor_messages.h"
#endif
#undef CONTENT_COMMON_P2P_MESSAGES_H_
#include "content/common/p2p_messages.h"
#ifndef CONTENT_COMMON_P2P_MESSAGES_H_
#error "Failed to include content/common/p2p_messages.h"
#endif
#if defined(OS_ANDROID)
#undef CONTENT_COMMON_GIN_JAVA_BRIDGE_MESSAGES_H_
#include "content/common/gin_java_bridge_messages.h"
......
......@@ -39,6 +39,7 @@ traits_headers = [
"//content/common/input/touch_action_optional_struct_traits.h",
"//content/common/view_messages.h",
"//content/public/common/common_param_traits.h",
"//services/network/public/cpp/p2p_param_traits.h",
]
public_deps = [
# NOTE: These dependencies are here to satisfy gn check because
......
......@@ -69,6 +69,7 @@
"media.mojom.VideoDecodePerfHistory",
"memory_coordinator.mojom.MemoryCoordinatorHandle",
"metrics.mojom.SingleSampleMetricsProvider",
"network.mojom.P2PSocketManager",
"network.mojom.URLLoaderFactory",
"resource_coordinator.mojom.ProcessCoordinationUnit",
"ui.mojom.Gpu",
......
......@@ -10,60 +10,10 @@
#include "content/public/common/content_constants.h"
#include "content/public/common/page_state.h"
#include "content/public/common/referrer.h"
#include "net/base/ip_address.h"
#include "net/base/ip_endpoint.h"
#include "net/http/http_util.h"
namespace IPC {
void ParamTraits<net::IPEndPoint>::Write(base::Pickle* m, const param_type& p) {
WriteParam(m, p.address());
WriteParam(m, p.port());
}
bool ParamTraits<net::IPEndPoint>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
net::IPAddress address;
uint16_t port;
if (!ReadParam(m, iter, &address) || !ReadParam(m, iter, &port))
return false;
if (!address.empty() && !address.IsValid())
return false;
*p = net::IPEndPoint(address, port);
return true;
}
void ParamTraits<net::IPEndPoint>::Log(const param_type& p, std::string* l) {
LogParam("IPEndPoint:" + p.ToString(), l);
}
void ParamTraits<net::IPAddress>::Write(base::Pickle* m, const param_type& p) {
base::StackVector<uint8_t, 16> bytes;
for (uint8_t byte : p.bytes())
bytes->push_back(byte);
WriteParam(m, bytes);
}
bool ParamTraits<net::IPAddress>::Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p) {
base::StackVector<uint8_t, 16> bytes;
if (!ReadParam(m, iter, &bytes))
return false;
if (bytes->size() && bytes->size() != net::IPAddress::kIPv4AddressSize &&
bytes->size() != net::IPAddress::kIPv6AddressSize) {
return false;
}
*p = net::IPAddress(bytes->data(), bytes->size());
return true;
}
void ParamTraits<net::IPAddress>::Log(const param_type& p, std::string* l) {
LogParam("IPAddress:" + (p.empty() ? "(empty)" : p.ToString()), l);
}
void ParamTraits<content::PageState>::Write(base::Pickle* m,
const param_type& p) {
WriteParam(m, p.ToEncodedData());
......
......@@ -35,33 +35,8 @@ namespace content {
class PageState;
}
namespace net {
class IPAddress;
class IPEndPoint;
}
namespace IPC {
template <>
struct CONTENT_EXPORT ParamTraits<net::IPEndPoint> {
typedef net::IPEndPoint param_type;
static void Write(base::Pickle* m, const param_type& p);
static bool Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p);
static void Log(const param_type& p, std::string* l);
};
template <>
struct CONTENT_EXPORT ParamTraits<net::IPAddress> {
typedef net::IPAddress param_type;
static void Write(base::Pickle* m, const param_type& p);
static bool Read(const base::Pickle* m,
base::PickleIterator* iter,
param_type* p);
static void Log(const param_type& p, std::string* l);
};
template <>
struct CONTENT_EXPORT ParamTraits<content::PageState> {
typedef content::PageState param_type;
......
......@@ -15,7 +15,6 @@
#include "content/public/common/web_preferences.h"
#include "content/public/common/webplugininfo_param_traits.h"
#include "ipc/ipc_message_macros.h"
#include "net/base/network_change_notifier.h"
#include "services/network/public/cpp/network_ipc_param_traits.h"
#include "third_party/blink/public/platform/modules/permissions/permission_status.mojom.h"
#include "third_party/blink/public/platform/web_history_scroll_restoration_type.h"
......@@ -44,8 +43,6 @@ IPC_ENUM_TRAITS_VALIDATE(ui::PageTransition,
((value &
ui::PageTransition::PAGE_TRANSITION_CORE_MASK) <=
ui::PageTransition::PAGE_TRANSITION_LAST_CORE))
IPC_ENUM_TRAITS_MAX_VALUE(net::NetworkChangeNotifier::ConnectionType,
net::NetworkChangeNotifier::CONNECTION_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(content::ConsoleMessageLevel,
content::CONSOLE_MESSAGE_LEVEL_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(blink::WebFrameSerializerCacheControlPolicy,
......
......@@ -493,22 +493,6 @@ void PeerConnectionDependencyFactory::TryScheduleStunProbeTrial() {
if (!cmd_line->HasSwitch(switches::kWebRtcStunProbeTrialParameter))
return;
// The underneath IPC channel has to be connected before sending any IPC
// message.
if (!p2p_socket_dispatcher_->connected()) {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(
&PeerConnectionDependencyFactory::TryScheduleStunProbeTrial,
base::Unretained(this)),
base::TimeDelta::FromSeconds(1));
return;
}
// GetPcFactory could trigger an IPC message. If done before
// |p2p_socket_dispatcher_| is connected, that'll put the
// |p2p_socket_dispatcher_| in a bad state such that no other IPC message can
// be processed.
GetPcFactory();
const std::string params =
......
......@@ -7,9 +7,7 @@
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/common/p2p_messages.h"
#include "content/renderer/p2p/socket_dispatcher.h"
#include "jingle/glue/utils.h"
......@@ -17,78 +15,37 @@ namespace content {
P2PAsyncAddressResolver::P2PAsyncAddressResolver(
P2PSocketDispatcher* dispatcher)
: dispatcher_(dispatcher),
ipc_task_runner_(dispatcher->task_runner()),
delegate_task_runner_(base::ThreadTaskRunnerHandle::Get()),
state_(STATE_CREATED),
request_id_(0),
registered_(false) {
: dispatcher_(dispatcher), state_(STATE_CREATED) {
AddRef(); // Balanced in Destroy().
}
P2PAsyncAddressResolver::~P2PAsyncAddressResolver() {
DCHECK(state_ == STATE_CREATED || state_ == STATE_FINISHED);
DCHECK(!registered_);
}
void P2PAsyncAddressResolver::Start(const rtc::SocketAddress& host_name,
const DoneCallback& done_callback) {
DCHECK(delegate_task_runner_->BelongsToCurrentThread());
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_EQ(STATE_CREATED, state_);
state_ = STATE_SENT;
ipc_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&P2PAsyncAddressResolver::DoSendRequest, this,
host_name, done_callback));
done_callback_ = done_callback;
dispatcher_->GetP2PSocketManager()->GetHostAddress(
host_name.hostname(), base::BindOnce(&P2PAsyncAddressResolver::OnResponse,
base::Unretained(this)));
}
void P2PAsyncAddressResolver::Cancel() {
DCHECK(delegate_task_runner_->BelongsToCurrentThread());
DCHECK(thread_checker_.CalledOnValidThread());
if (state_ != STATE_FINISHED) {
if (state_ != STATE_FINISHED)
state_ = STATE_FINISHED;
ipc_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&P2PAsyncAddressResolver::DoUnregister, this));
}
done_callback_.Reset();
}
void P2PAsyncAddressResolver::DoSendRequest(
const rtc::SocketAddress& host_name,
const DoneCallback& done_callback) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
done_callback_ = done_callback;
request_id_ = dispatcher_->RegisterHostAddressRequest(this);
registered_ = true;
dispatcher_->SendP2PMessage(
new P2PHostMsg_GetHostAddress(host_name.hostname(), request_id_));
}
void P2PAsyncAddressResolver::DoUnregister() {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
if (registered_) {
dispatcher_->UnregisterHostAddressRequest(request_id_);
registered_ = false;
}
done_callback_.Reset();
}
void P2PAsyncAddressResolver::OnResponse(const net::IPAddressList& addresses) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
DCHECK(registered_);
dispatcher_->UnregisterHostAddressRequest(request_id_);
registered_ = false;
delegate_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&P2PAsyncAddressResolver::DeliverResponse, this,
addresses));
}
void P2PAsyncAddressResolver::DeliverResponse(
const net::IPAddressList& addresses) {
DCHECK(delegate_task_runner_->BelongsToCurrentThread());
DCHECK(thread_checker_.CalledOnValidThread());
if (state_ == STATE_SENT) {
state_ = STATE_FINISHED;
base::ResetAndReturn(&done_callback_).Run(addresses);
......
......@@ -12,14 +12,11 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "net/base/ip_address.h"
#include "third_party/webrtc/rtc_base/asyncresolverinterface.h"
namespace base {
class SingleThreadTaskRunner;
} // namespace base
namespace content {
class P2PSocketDispatcher;
......@@ -51,23 +48,13 @@ class P2PAsyncAddressResolver
virtual ~P2PAsyncAddressResolver();
void DoSendRequest(const rtc::SocketAddress& host_name,
const DoneCallback& done_callback);
void DoUnregister();
void OnResponse(const net::IPAddressList& address);
void DeliverResponse(const net::IPAddressList& address);
P2PSocketDispatcher* dispatcher_;
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> delegate_task_runner_;
base::ThreadChecker thread_checker_;
// State must be accessed from delegate thread only.
State state_;
// Accessed on the IPC thread only.
int32_t request_id_;
bool registered_;
std::vector<rtc::IPAddress> addresses_;
DoneCallback done_callback_;
DISALLOW_COPY_AND_ASSIGN(P2PAsyncAddressResolver);
......
This diff is collapsed.
......@@ -9,9 +9,8 @@
#include <vector>
#include "base/memory/ref_counted.h"
#include "content/common/p2p_socket_type.h"
#include "net/base/ip_endpoint.h"
#include "services/network/public/cpp/p2p_socket_type.h"
namespace rtc {
struct PacketOptions;
......@@ -22,17 +21,17 @@ namespace content {
class P2PSocketClientDelegate;
// P2P socket that routes all calls over IPC.
// Note that while ref-counting is thread-safe, all methods must be
// called on the same thread.
class P2PSocketClient : public base::RefCountedThreadSafe<P2PSocketClient> {
class P2PSocketClient {
public:
virtual ~P2PSocketClient() {}
// Send the |data| to the |address| using Differentiated Services Code Point
// |dscp|. Return value is the unique packet_id for this packet.
virtual uint64_t Send(const net::IPEndPoint& address,
const std::vector<char>& data,
const std::vector<int8_t>& data,
const rtc::PacketOptions& options) = 0;
virtual void SetOption(P2PSocketOption option, int value) = 0;
virtual void SetOption(network::P2PSocketOption option, int value) = 0;
// Must be called before the socket is destroyed.
virtual void Close() = 0;
......@@ -42,11 +41,6 @@ class P2PSocketClient : public base::RefCountedThreadSafe<P2PSocketClient> {
protected:
P2PSocketClient() {}
virtual ~P2PSocketClient() {}
private:
// Calls destructor.
friend class base::RefCountedThreadSafe<P2PSocketClient>;
};
} // namespace content
......
......@@ -7,9 +7,8 @@
#include <vector>
#include "base/memory/ref_counted.h"
#include "content/common/p2p_socket_type.h"
#include "net/base/ip_endpoint.h"
#include "services/network/public/cpp/p2p_socket_type.h"
namespace content {
......@@ -27,18 +26,20 @@ class P2PSocketClientDelegate {
// For a socket that is listening on incoming TCP connectsion, this
// function is called when a new client connects.
virtual void OnIncomingTcpConnection(const net::IPEndPoint& address,
P2PSocketClient* client) = 0;
virtual void OnIncomingTcpConnection(
const net::IPEndPoint& address,
std::unique_ptr<P2PSocketClient> client) = 0;
// Called once for each Send() call after the send is complete.
virtual void OnSendComplete(const P2PSendPacketMetrics& send_metrics) = 0;
virtual void OnSendComplete(
const network::P2PSendPacketMetrics& send_metrics) = 0;
// Called if an non-retryable error occurs.
virtual void OnError() = 0;
// Called when data is received on the socket.
virtual void OnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data,
const std::vector<int8_t>& data,
const base::TimeTicks& timestamp) = 0;
};
......
This diff is collapsed.
......@@ -11,13 +11,15 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/p2p_socket_type.h"
#include "base/threading/thread_checker.h"
#include "content/renderer/p2p/socket_client.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/ip_endpoint.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/p2p_socket_type.h"
#include "services/network/public/mojom/p2p.mojom.h"
namespace base {
class SingleThreadTaskRunner;
class TimeTicks;
} // namespace base
......@@ -25,36 +27,35 @@ namespace content {
class P2PSocketDispatcher;
// P2P socket that routes all calls over IPC.
// P2P socket that routes all calls over Mojo.
//
// The object runs on two threads: IPC thread and delegate thread. The
// IPC thread is used to interact with P2PSocketDispatcher. All
// callbacks to the user of this class are called on the delegate
// thread which is specified in Init().
class P2PSocketClientImpl : public P2PSocketClient {
// The object runs on the WebRTC worker thread.
class P2PSocketClientImpl : public P2PSocketClient,
public network::mojom::P2PSocketClient {
public:
explicit P2PSocketClientImpl(
P2PSocketClientImpl(
P2PSocketDispatcher* dispatcher,
const net::NetworkTrafficAnnotationTag& traffic_annotation);
~P2PSocketClientImpl() override;
// Initialize socket of the specified |type| and connected to the
// specified |address|. |address| matters only when |type| is set to
// P2P_SOCKET_TCP_CLIENT.
virtual void Init(P2PSocketType type,
virtual void Init(network::P2PSocketType type,
const net::IPEndPoint& local_address,
uint16_t min_port,
uint16_t max_port,
const P2PHostAndIPEndPoint& remote_address,
const network::P2PHostAndIPEndPoint& remote_address,
P2PSocketClientDelegate* delegate);
// Send the |data| to the |address| using Differentiated Services Code Point
// |dscp|. Return value is the unique packet_id for this packet.
uint64_t Send(const net::IPEndPoint& address,
const std::vector<char>& data,
const std::vector<int8_t>& data,
const rtc::PacketOptions& options) override;
// Setting socket options.
void SetOption(P2PSocketOption option, int value) override;
void SetOption(network::P2PSocketOption option, int value) override;
// Must be called before the socket is destroyed. The delegate may
// not be called after |closed_task| is executed.
......@@ -75,53 +76,26 @@ class P2PSocketClientImpl : public P2PSocketClient {
friend class P2PSocketDispatcher;
~P2PSocketClientImpl() override;
// Message handlers that run on IPC thread.
void OnSocketCreated(const net::IPEndPoint& local_address,
const net::IPEndPoint& remote_address);
void OnIncomingTcpConnection(const net::IPEndPoint& address);
void OnSendComplete(const P2PSendPacketMetrics& send_metrics);
void OnError();
void OnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data,
const base::TimeTicks& timestamp);
// Proxy methods that deliver messages to the delegate thread.
void DeliverOnSocketCreated(const net::IPEndPoint& local_address,
const net::IPEndPoint& remote_address);
void DeliverOnIncomingTcpConnection(
const net::IPEndPoint& address,
scoped_refptr<P2PSocketClient> new_client);
void DeliverOnSendComplete(const P2PSendPacketMetrics& send_metrics);
void DeliverOnError();
void DeliverOnDataReceived(const net::IPEndPoint& address,
const std::vector<char>& data,
const base::TimeTicks& timestamp);
// Helper function to be called by Send to handle different threading
// condition.
void SendWithPacketId(const net::IPEndPoint& address,
const std::vector<char>& data,
const std::vector<int8_t>& data,
const rtc::PacketOptions& options,
uint64_t packet_id);
// Scheduled on the IPC thread to finish initialization.
void DoInit(P2PSocketType type,
const net::IPEndPoint& local_address,
uint16_t min_port,
uint16_t max_port,
const P2PHostAndIPEndPoint& remote_address);
// Scheduled on the IPC thread to finish closing the connection.
void DoClose();
// network::mojom::P2PSocketClient interface.
void SocketCreated(const net::IPEndPoint& local_address,
const net::IPEndPoint& remote_address) override;
void SendComplete(const network::P2PSendPacketMetrics& send_metrics) override;
void IncomingTcpConnection(const net::IPEndPoint& socket_address) override;
void DataReceived(const net::IPEndPoint& socket_address,
const std::vector<int8_t>& data,
base::TimeTicks timestamp) override;
// Called by the dispatcher when it is destroyed.
void Detach();
void OnConnectionError();
P2PSocketDispatcher* dispatcher_;
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> delegate_task_runner_;
base::ThreadChecker thread_checker_;
int socket_id_;
P2PSocketClientDelegate* delegate_;
State state_;
......@@ -131,6 +105,9 @@ class P2PSocketClientImpl : public P2PSocketClient {
uint32_t random_socket_id_;
uint32_t next_packet_id_;
network::mojom::P2PSocketPtr socket_;
mojo::Binding<network::mojom::P2PSocketClient> binding_;
DISALLOW_COPY_AND_ASSIGN(P2PSocketClientImpl);
};
......
......@@ -7,36 +7,37 @@
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "content/child/child_process.h"
#include "content/common/p2p_messages.h"
#include "content/renderer/p2p/host_address_request.h"
#include "content/child/child_thread_impl.h"
#include "content/public/common/service_names.mojom.h"
#include "content/renderer/p2p/network_list_observer.h"
#include "content/renderer/p2p/socket_client_impl.h"
#include "content/renderer/render_view_impl.h"
#include "ipc/ipc_sender.h"
#include "services/network/public/cpp/p2p_param_traits.h"
#include "services/service_manager/public/cpp/connector.h"
namespace content {
P2PSocketDispatcher::P2PSocketDispatcher(
base::SingleThreadTaskRunner* ipc_task_runner)
: ipc_task_runner_(ipc_task_runner),
network_notifications_started_(false),
P2PSocketDispatcher::P2PSocketDispatcher()
: main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
network_list_observers_(
new base::ObserverListThreadSafe<NetworkListObserver>()),
sender_(nullptr) {}
network_notification_client_binding_(this) {
network::mojom::P2PSocketManagerPtr p2p_socket_manager;
p2p_socket_manager_request_ = mojo::MakeRequest(&p2p_socket_manager);
thread_safe_p2p_socket_manager_ =
network::mojom::ThreadSafeP2PSocketManagerPtr::Create(
std::move(p2p_socket_manager));
}
P2PSocketDispatcher::~P2PSocketDispatcher() {
network_list_observers_->AssertEmpty();
for (base::IDMap<P2PSocketClientImpl*>::iterator i(&clients_); !i.IsAtEnd();
i.Advance()) {
i.GetCurrentValue()->Detach();
}
}
void P2PSocketDispatcher::AddNetworkListObserver(
NetworkListObserver* network_list_observer) {
network_list_observers_->AddObserver(network_list_observer);
network_notifications_started_ = true;
SendP2PMessage(new P2PHostMsg_StartNetworkNotifications());
main_task_runner_->PostTask(
FROM_HERE,
base::Bind(&P2PSocketDispatcher::RequestNetworkEventsIfNecessary, this));
}
void P2PSocketDispatcher::RemoveNetworkListObserver(
......@@ -44,160 +45,46 @@ void P2PSocketDispatcher::RemoveNetworkListObserver(
network_list_observers_->RemoveObserver(network_list_observer);
}
void P2PSocketDispatcher::Send(IPC::Message* message) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
if (!sender_) {
DLOG(WARNING) << "P2PSocketDispatcher::Send() - Sender closed.";
delete message;
return;
}
sender_->Send(message);
}
bool P2PSocketDispatcher::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(P2PSocketDispatcher, message)
IPC_MESSAGE_HANDLER(P2PMsg_NetworkListChanged, OnNetworkListChanged)
IPC_MESSAGE_HANDLER(P2PMsg_GetHostAddressResult, OnGetHostAddressResult)
IPC_MESSAGE_HANDLER(P2PMsg_OnSocketCreated, OnSocketCreated)
IPC_MESSAGE_HANDLER(P2PMsg_OnIncomingTcpConnection, OnIncomingTcpConnection)
IPC_MESSAGE_HANDLER(P2PMsg_OnSendComplete, OnSendComplete)
IPC_MESSAGE_HANDLER(P2PMsg_OnError, OnError)
IPC_MESSAGE_HANDLER(P2PMsg_OnDataReceived, OnDataReceived)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void P2PSocketDispatcher::OnFilterAdded(IPC::Channel* channel) {
DVLOG(1) << "P2PSocketDispatcher::OnFilterAdded()";
sender_ = channel;
}
void P2PSocketDispatcher::OnFilterRemoved() {
sender_ = nullptr;
}
void P2PSocketDispatcher::OnChannelConnected(int32_t peer_id) {
connected_ = true;
}
void P2PSocketDispatcher::OnChannelClosing() {
sender_ = nullptr;
connected_ = false;
}
base::SingleThreadTaskRunner* P2PSocketDispatcher::task_runner() {
return ipc_task_runner_.get();
}
int P2PSocketDispatcher::RegisterClient(P2PSocketClientImpl* client) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
return clients_.Add(client);
}
void P2PSocketDispatcher::UnregisterClient(int id) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
clients_.Remove(id);
}
void P2PSocketDispatcher::SendP2PMessage(IPC::Message* msg) {
if (!ipc_task_runner_->BelongsToCurrentThread()) {
ipc_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&P2PSocketDispatcher::Send, this, msg));
return;
}
Send(msg);
}
int P2PSocketDispatcher::RegisterHostAddressRequest(
P2PAsyncAddressResolver* request) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
return host_address_requests_.Add(request);
network::mojom::P2PSocketManager* P2PSocketDispatcher::GetP2PSocketManager() {
main_task_runner_->PostTask(
FROM_HERE,
base::Bind(&P2PSocketDispatcher::RequestInterfaceIfNecessary, this));
return thread_safe_p2p_socket_manager_->get();
}
void P2PSocketDispatcher::UnregisterHostAddressRequest(int id) {
DCHECK(ipc_task_runner_->BelongsToCurrentThread());
host_address_requests_.Remove(id);
}
void P2PSocketDispatcher::OnNetworkListChanged(
const net::NetworkInterfaceList& networks,
void P2PSocketDispatcher::NetworkListChanged(
const std::vector<net::NetworkInterface>& networks,
const net::IPAddress& default_ipv4_local_address,
const net::IPAddress& default_ipv6_local_address) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
networks_ = networks;
default_ipv4_local_address_ = default_ipv4_local_address;
default_ipv6_local_address_ = default_ipv6_local_address;
network_list_observers_->Notify(
FROM_HERE, &NetworkListObserver::OnNetworkListChanged, networks,
default_ipv4_local_address, default_ipv6_local_address);
}
void P2PSocketDispatcher::OnGetHostAddressResult(
int32_t request_id,
const net::IPAddressList& addresses) {
P2PAsyncAddressResolver* request = host_address_requests_.Lookup(request_id);
if (!request) {
DVLOG(1) << "Received P2P message for socket that doesn't exist.";
void P2PSocketDispatcher::RequestInterfaceIfNecessary() {
if (!p2p_socket_manager_request_.is_pending())
return;
}
request->OnResponse(addresses);
}
void P2PSocketDispatcher::OnSocketCreated(
int socket_id,
const net::IPEndPoint& local_address,
const net::IPEndPoint& remote_address) {
P2PSocketClientImpl* client = GetClient(socket_id);
if (client) {
client->OnSocketCreated(local_address, remote_address);
}
}
void P2PSocketDispatcher::OnIncomingTcpConnection(
int socket_id, const net::IPEndPoint& address) {
P2PSocketClientImpl* client = GetClient(socket_id);
if (client) {
client->OnIncomingTcpConnection(address);
}
}
void P2PSocketDispatcher::OnSendComplete(
int socket_id,
const P2PSendPacketMetrics& send_metrics) {
P2PSocketClientImpl* client = GetClient(socket_id);
if (client) {
client->OnSendComplete(send_metrics);
}
}
void P2PSocketDispatcher::OnError(int socket_id) {
P2PSocketClientImpl* client = GetClient(socket_id);
if (client) {
client->OnError();
}
}
void P2PSocketDispatcher::OnDataReceived(
int socket_id, const net::IPEndPoint& address,
const std::vector<char>& data,
const base::TimeTicks& timestamp) {
P2PSocketClientImpl* client = GetClient(socket_id);
if (client) {
client->OnDataReceived(address, data, timestamp);
}
}
P2PSocketClientImpl* P2PSocketDispatcher::GetClient(int socket_id) {
P2PSocketClientImpl* client = clients_.Lookup(socket_id);
if (client == nullptr) {
// This may happen if the socket was closed, but the browser side
// hasn't processed the close message by the time it sends the
// message to the renderer.
DVLOG(1) << "Received P2P message for socket that doesn't exist.";
return nullptr;
ChildThreadImpl::current()->GetConnector()->BindInterface(
mojom::kBrowserServiceName, std::move(p2p_socket_manager_request_));
}
void P2PSocketDispatcher::RequestNetworkEventsIfNecessary() {
if (network_notification_client_binding_.is_bound()) {
network_list_observers_->Notify(
FROM_HERE, &NetworkListObserver::OnNetworkListChanged, networks_,
default_ipv4_local_address_, default_ipv6_local_address_);
} else {
network::mojom::P2PNetworkNotificationClientPtr network_notification_client;
network_notification_client_binding_.Bind(
mojo::MakeRequest(&network_notification_client));
GetP2PSocketManager()->StartNetworkNotifications(
std::move(network_notification_client));
}
return client;
}
} // namespace content
......@@ -27,35 +27,35 @@
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/containers/id_map.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/observer_list_threadsafe.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
#include "content/common/p2p_socket_type.h"
#include "content/renderer/p2p/network_list_manager.h"
#include "ipc/message_filter.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h"
#include "net/base/ip_address.h"
#include "net/base/network_interfaces.h"
#include "services/network/public/cpp/p2p_socket_type.h"
#include "services/network/public/mojom/p2p.mojom.h"
namespace base {
class SingleThreadTaskRunner;
} // namespace base
namespace net {
class IPEndPoint;
} // namespace net
namespace content {
class NetworkListObserver;
class P2PAsyncAddressResolver;
class P2PSocketClientImpl;
class CONTENT_EXPORT P2PSocketDispatcher : public IPC::MessageFilter,
public NetworkListManager {
// This class is created on the main thread, but is used primarily on the
// WebRTC worker threads.
class CONTENT_EXPORT P2PSocketDispatcher
: public base::RefCountedThreadSafe<P2PSocketDispatcher>,
public NetworkListManager,
public network::mojom::P2PNetworkNotificationClient {
public:
explicit P2PSocketDispatcher(base::SingleThreadTaskRunner* ipc_task_runner);
P2PSocketDispatcher();
// NetworkListManager interface:
void AddNetworkListObserver(
......@@ -63,67 +63,38 @@ class CONTENT_EXPORT P2PSocketDispatcher : public IPC::MessageFilter,
void RemoveNetworkListObserver(
NetworkListObserver* network_list_observer) override;
bool connected() { return connected_; }
network::mojom::P2PSocketManager* GetP2PSocketManager();
private:
friend class base::RefCountedThreadSafe<P2PSocketDispatcher>;
protected:
~P2PSocketDispatcher() override;
private:
friend class P2PAsyncAddressResolver;
friend class P2PSocketClientImpl;
// Send a message asynchronously.
virtual void Send(IPC::Message* message);
// IPC::MessageFilter override. Called on IO thread.
bool OnMessageReceived(const IPC::Message& message) override;
void OnFilterAdded(IPC::Channel* channel) override;
void OnFilterRemoved() override;
void OnChannelClosing() override;
void OnChannelConnected(int32_t peer_pid) override;
base::SingleThreadTaskRunner* task_runner();
// Called by P2PSocketClient.
int RegisterClient(P2PSocketClientImpl* client);
void UnregisterClient(int id);
void SendP2PMessage(IPC::Message* msg);
// Called by DnsRequest.
int RegisterHostAddressRequest(P2PAsyncAddressResolver* request);
void UnregisterHostAddressRequest(int id);
// Incoming message handlers.
void OnNetworkListChanged(const net::NetworkInterfaceList& networks,
const net::IPAddress& default_ipv4_local_address,
const net::IPAddress& default_ipv6_local_address);
void OnGetHostAddressResult(int32_t request_id,
const net::IPAddressList& addresses);
void OnSocketCreated(int socket_id,
const net::IPEndPoint& local_address,
const net::IPEndPoint& remote_address);
void OnIncomingTcpConnection(int socket_id, const net::IPEndPoint& address);
void OnSendComplete(int socket_id, const P2PSendPacketMetrics& send_metrics);
void OnError(int socket_id);
void OnDataReceived(int socket_id, const net::IPEndPoint& address,
const std::vector<char>& data,
const base::TimeTicks& timestamp);
P2PSocketClientImpl* GetClient(int socket_id);
scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;
base::IDMap<P2PSocketClientImpl*> clients_;
base::IDMap<P2PAsyncAddressResolver*> host_address_requests_;
bool network_notifications_started_;
// network::mojom::P2PNetworkNotificationClient interface.
void NetworkListChanged(
const std::vector<net::NetworkInterface>& networks,
const net::IPAddress& default_ipv4_local_address,
const net::IPAddress& default_ipv6_local_address) override;
void RequestInterfaceIfNecessary();
void RequestNetworkEventsIfNecessary();
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
scoped_refptr<base::ObserverListThreadSafe<NetworkListObserver>>
network_list_observers_;
IPC::Sender* sender_;
network::mojom::P2PSocketManagerRequest p2p_socket_manager_request_;
scoped_refptr<network::mojom::ThreadSafeP2PSocketManagerPtr>
thread_safe_p2p_socket_manager_;
// Cached from last |NetworkListChanged| call.
std::vector<net::NetworkInterface> networks_;
net::IPAddress default_ipv4_local_address_;
net::IPAddress default_ipv6_local_address_;
// To indicate whether IPC could be invoked on this dispatcher.
bool connected_ = false;
mojo::Binding<network::mojom::P2PNetworkNotificationClient>
network_notification_client_binding_;
DISALLOW_COPY_AND_ASSIGN(P2PSocketDispatcher);
};
......
......@@ -819,8 +819,7 @@ void RenderThreadImpl::Init(
peer_connection_tracker_.reset(new PeerConnectionTracker());
AddObserver(peer_connection_tracker_.get());
p2p_socket_dispatcher_ = new P2PSocketDispatcher(GetIOTaskRunner().get());
AddFilter(p2p_socket_dispatcher_.get());
p2p_socket_dispatcher_ = new P2PSocketDispatcher();
peer_connection_factory_.reset(
new PeerConnectionDependencyFactory(p2p_socket_dispatcher_.get()));
......
This diff is collapsed.
......@@ -16,9 +16,6 @@ bool StructTraits<net::interfaces::IPEndPointDataView, net::IPEndPoint>::Read(
if (!data.ReadAddress(&address))
return false;
if (!address.IsValid())
return false;
*out = net::IPEndPoint(address, data.port());
return true;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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