diff options
21 files changed, 669 insertions, 6 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 2c6d513..b21ac00 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -4080,6 +4080,12 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_FLAGS_WEBGL_DESCRIPTION" desc="Description of the 'WebGL' lab."> Enables canvas elements to use 3D graphics via the WebGL API. </message> + <message name="IDS_FLAGS_P2P_API_NAME" desc="Name of the 'P2P API' lab."> + P2P API + </message> + <message name="IDS_FLAGS_P2P_API_DESCRIPTION" desc="Description of the 'P2P API' lab."> + Enables P2P Pepper API and P2P JavaScript API. The API is under development, and doesn't work yet. + </message> <message name="IDS_FLAGS_PRINT_PREVIEW_NAME" desc="Name of the 'Print Preview' lab."> Print Preview </message> diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index d06ed4d..54f5e55 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc @@ -254,6 +254,13 @@ const Experiment kExperiments[] = { kOsAll, SINGLE_VALUE_TYPE(switches::kEnableHistoryQuickProvider) }, + { + "p2papi", + IDS_FLAGS_P2P_API_NAME, + IDS_FLAGS_P2P_API_DESCRIPTION, + kOsAll, + SINGLE_VALUE_TYPE(switches::kEnableP2PApi) + }, }; const Experiment* experiments = kExperiments; diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index baba77e..2648751 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -78,6 +78,7 @@ #include "content/browser/renderer_host/database_message_filter.h" #include "content/browser/renderer_host/file_utilities_message_filter.h" #include "content/browser/renderer_host/gpu_message_filter.h" +#include "content/browser/renderer_host/p2p_sockets_host.h" #include "content/browser/renderer_host/pepper_file_message_filter.h" #include "content/browser/renderer_host/pepper_message_filter.h" #include "content/browser/renderer_host/render_message_filter.h" @@ -485,6 +486,9 @@ void BrowserRenderProcessHost::CreateMessageFilters() { g_browser_process->resource_dispatcher_host(), NewCallbackWithReturnValue( widget_helper_.get(), &RenderWidgetHelper::GetNextRoutingID))); + + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableP2PApi)) + channel_->AddFilter(new P2PSocketsHost()); } int BrowserRenderProcessHost::GetNextRoutingID() { @@ -686,6 +690,7 @@ void BrowserRenderProcessHost::PropagateBrowserCommandLineToRenderer( switches::kEnableLogging, switches::kEnableNaCl, switches::kEnableOpenMax, + switches::kEnableP2PApi, switches::kEnablePepperTesting, switches::kEnablePrintPreview, switches::kEnableRemoting, diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 37f6cc8..f33971a 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -218,8 +218,7 @@ '../base/base.gyp:base', '../base/base.gyp:base_i18n', '../build/temp_gyp/googleurl.gyp:googleurl', - # Don't include now since it's empty and so will cause a linker error. - #'../content/content.gyp:content_common', + '../content/content.gyp:content_common', '../ipc/ipc.gyp:ipc', '../net/net.gyp:net', '../printing/printing.gyp:printing', diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 0be38c8..60be9b6 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -577,6 +577,9 @@ const char kEnableRemoting[] = "enable-remoting"; const char kEnableResourceContentSettings[] = "enable-resource-content-settings"; +// Enable Pepper and JavaScript P2P API. +const char kEnableP2PApi[] = "enable-p2papi"; + // Enable speculative TCP/IP preconnection. const char kEnablePreconnect[] = "enable-preconnect"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 6b8e757..a9078d2 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -166,6 +166,7 @@ extern const char kEnableMemoryInfo[]; extern const char kEnableMonitorProfile[]; extern const char kEnableNaCl[]; extern const char kEnableNaClDebug[]; +extern const char kEnableP2PApi[]; extern const char kEnablePreconnect[]; extern const char kEnablePreparsedJsCaching[]; extern const char kEnablePrintPreview[]; diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 3e0f9ba..a102bd7 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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. @@ -72,9 +72,9 @@ class SkBitmap; class URLPattern; struct ContextMenuParams; struct EditCommand; +struct RendererPreferences; struct ResourceResponseHead; struct SyncLoadResult; -struct RendererPreferences; struct WebDropData; struct WebMenuItem; struct WebPreferences; diff --git a/content/browser/renderer_host/p2p_socket_host.cc b/content/browser/renderer_host/p2p_socket_host.cc new file mode 100644 index 0000000..0645e7b --- /dev/null +++ b/content/browser/renderer_host/p2p_socket_host.cc @@ -0,0 +1,11 @@ +// Copyright (c) 2011 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 "content/browser/renderer_host/p2p_socket_host.h" + +P2PSocketHost::P2PSocketHost(P2PSocketsHost* host, int routing_id, int id) + : host_(host), routing_id_(routing_id), id_(id) { +} + +P2PSocketHost::~P2PSocketHost() { } diff --git a/content/browser/renderer_host/p2p_socket_host.h b/content/browser/renderer_host/p2p_socket_host.h new file mode 100644 index 0000000..8692888 --- /dev/null +++ b/content/browser/renderer_host/p2p_socket_host.h @@ -0,0 +1,39 @@ +// Copyright (c) 2011 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 CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_H_ +#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_H_ + +#include "content/common/p2p_sockets.h" + +class P2PSocketsHost; + +// Base class for P2P sockets used by P2PSocketsHost. +class P2PSocketHost { + public: + // Creates P2PSocketHost for the current platform. Must be + // implemented in a platform-specific file. + static P2PSocketHost* Create(P2PSocketsHost* host, int routing_id, int id, + P2PSocketType type); + + virtual ~P2PSocketHost(); + + // Initalizes the socket. Returns false when initiazations fails. + virtual bool Init() = 0; + + // Sends |data| on the socket to |socket_address|. + virtual void Send(P2PSocketAddress socket_address, + const std::vector<char>& data) = 0; + + protected: + P2PSocketHost(P2PSocketsHost* host, int routing_id, int id); + + P2PSocketsHost* host_; + int routing_id_; + int id_; + + DISALLOW_COPY_AND_ASSIGN(P2PSocketHost); +}; + +#endif // CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_H_ diff --git a/content/browser/renderer_host/p2p_socket_host_posix.cc b/content/browser/renderer_host/p2p_socket_host_posix.cc new file mode 100644 index 0000000..f9ae31f --- /dev/null +++ b/content/browser/renderer_host/p2p_socket_host_posix.cc @@ -0,0 +1,260 @@ +// Copyright (c) 2011 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 "content/browser/renderer_host/p2p_socket_host_posix.h" + +#include <errno.h> +#include <net/if.h> +#include <netinet/in.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/utsname.h> +#include <unistd.h> + +#include "content/browser/renderer_host/p2p_sockets_host.h" +#include "content/common/p2p_messages.h" +#include "net/base/net_util.h" + +namespace { + +// This method returns address of the first IPv4 enabled network +// interface it finds ignoring the loopback interface. This address is +// used for all sockets. +// +// TODO(sergeyu): This approach works only in the simplest case when +// host has only one network connection. Instead of binding all +// connections to this interface we must provide list of interfaces to +// the renderer, and let the PortAllocater in the renderer process +// choose local address. +bool GetLocalAddress(sockaddr_in* addr) { + int fd; + if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + LOG(ERROR) << "socket() failed: " << fd; + return false; + } + + struct ifconf ifc; + ifc.ifc_len = 64 * sizeof(struct ifreq); + scoped_array<char> ifc_buffer(new char[ifc.ifc_len]); + ifc.ifc_buf = ifc_buffer.get(); + + int result = ioctl(fd, SIOCGIFCONF, &ifc); + if (result < 0) { + LOG(ERROR) << "GetLocalAddress: ioctl returned error:" << result; + close(fd); + return false; + } + CHECK_LT(ifc.ifc_len, static_cast<int>(64 * sizeof(struct ifreq))); + + struct ifreq* ptr = reinterpret_cast<struct ifreq*>(ifc.ifc_buf); + struct ifreq* end = + reinterpret_cast<struct ifreq*>(ifc.ifc_buf + ifc.ifc_len); + + bool found = false; + while (ptr < end) { + struct sockaddr_in* inaddr = + reinterpret_cast<struct sockaddr_in*>(&ptr->ifr_ifru.ifru_addr); + if (inaddr->sin_family == AF_INET && + strncmp(ptr->ifr_name, "lo", 2) != 0) { + memcpy(addr, inaddr, sizeof(sockaddr_in)); + found = true; + break; + } + + ptr++; + } + + close(fd); + + return found; +} + +bool SocketAddressToSockAddr(P2PSocketAddress address, sockaddr_in* addr) { + // TODO(sergeyu): Add IPv6 support. + if (address.address.size() != 4) { + return false; + } + + addr->sin_family = AF_INET; + memcpy(&addr->sin_addr, &address.address[0], 4); + addr->sin_port = htons(address.port); + return true; +} + +bool SockAddrToSocketAddress(sockaddr_in* addr, + P2PSocketAddress* address) { + if (addr->sin_family != AF_INET) { + LOG(ERROR) << "SockAddrToSocketAddress: only IPv4 addresses are supported"; + // TODO(sergeyu): Add IPv6 support. + return false; + } + + address->address.resize(4); + memcpy(&address->address[0], &addr->sin_addr, 4); + address->port = ntohs(addr->sin_port); + + return true; +} + +} // namespace + +P2PSocketHostPosix::P2PSocketHostPosix( + P2PSocketsHost* host, int routing_id, int id) + : P2PSocketHost(host, routing_id, id), + state_(STATE_UNINITIALIZED), socket_(0), read_watcher_(this) { +} + +P2PSocketHostPosix::~P2PSocketHostPosix() { + if (state_ == STATE_OPEN) { + DCHECK_NE(socket_, 0); + close(socket_); + } +} + +bool P2PSocketHostPosix::Init() { + socket_ = socket(AF_INET, SOCK_DGRAM, 0); + if (socket_ < 0) { + LOG(ERROR) << "Failed to create socket: " << socket_; + OnError(); + return false; + } + + int result = net::SetNonBlocking(socket_); + if (result < 0) { + LOG(ERROR) << "Failed to set O_NONBLOCK flag: " << result; + OnError(); + return false; + } + + sockaddr_in addr; + if (!GetLocalAddress(&addr)) { + LOG(ERROR) << "Failed to get local network address."; + OnError(); + return false; + } + + result = bind(socket_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)); + if (result < 0) { + LOG(ERROR) << "bind() failed: " << result; + OnError(); + return false; + } + + if (!MessageLoopForIO::current()->WatchFileDescriptor( + socket_, true, MessageLoopForIO::WATCH_READ, + &read_socket_watcher_, &read_watcher_)) { + LOG(ERROR) << "WatchFileDescriptor failed on read, errno: " << errno; + OnError(); + return false; + } + + socklen_t addrlen = sizeof(addr); + result = getsockname(socket_, reinterpret_cast<sockaddr*>(&addr), + &addrlen); + if (result < 0) { + LOG(ERROR) << "P2PSocket::Init(): unable to get local addr: " + << result; + OnError(); + return false; + } + + P2PSocketAddress address; + if (!SockAddrToSocketAddress(&addr, &address)) { + OnError(); + return false; + } + + VLOG(1) << "getsockname() returned " + << net::NetAddressToString( + reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) + << ":" << address.port; + + state_ = STATE_OPEN; + + host_->Send(new P2PMsg_OnSocketCreated(routing_id_, id_, address)); + + return true; +} + +void P2PSocketHostPosix::OnError() { + if (socket_ != 0) { + close(socket_); + socket_ = 0; + } + + if (state_ == STATE_UNINITIALIZED || state_ == STATE_OPEN) { + host_->Send(new P2PMsg_OnError(routing_id_, id_)); + } + + state_ = STATE_ERROR; +} + +void P2PSocketHostPosix::DidCompleteRead() { + if (state_ != STATE_OPEN) { + return; + } + + std::vector<char> data; + data.resize(4096); + sockaddr_in addr; + socklen_t addr_len = sizeof(addr); + int result = recvfrom(socket_, &data[0], data.size(), 0, + reinterpret_cast<sockaddr*>(&addr), &addr_len); + if (result > 0) { + data.resize(result); + VLOG(2) << "received " << result << " bytes from " + << net::NetAddressToString( + reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) + << ":" << ntohs(addr.sin_port); + P2PSocketAddress address; + if (!SockAddrToSocketAddress(&addr, &address)) { + // Address conversion fails only if we receive a non-IPv4 + // packet, which should never happen because the socket is IPv4. + NOTREACHED(); + return; + } + + host_->Send(new P2PMsg_OnDataReceived(routing_id_, id_, + address, data)); + } else if (result < 0) { + LOG(ERROR) << "recvfrom() returned error: " << result; + OnError(); + } +} + +void P2PSocketHostPosix::Send(P2PSocketAddress socket_address, + const std::vector<char>& data) { + sockaddr_in addr; + SocketAddressToSockAddr(socket_address, &addr); + int result = sendto(socket_, &data[0], data.size(), 0, + reinterpret_cast<sockaddr*>(&addr), sizeof(addr)); + if (result < 0) { + LOG(ERROR) << "Send failed."; + } else { + VLOG(2) << "Sent " << result << " bytes to " + << net::NetAddressToString( + reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) + << ":" << ntohs(addr.sin_port); + } +} + +// static +P2PSocketHost* P2PSocketHost::Create( + P2PSocketsHost* host, int routing_id, int id, P2PSocketType type) { + switch (type) { + case P2P_SOCKET_UDP: + return new P2PSocketHostPosix(host, routing_id, id); + + case P2P_SOCKET_TCP_SERVER: + // TODO(sergeyu): Implement TCP sockets support. + return NULL; + + case P2P_SOCKET_TCP_CLIENT: + return NULL; + } + + NOTREACHED(); + return NULL; +} diff --git a/content/browser/renderer_host/p2p_socket_host_posix.h b/content/browser/renderer_host/p2p_socket_host_posix.h new file mode 100644 index 0000000..14dbc87 --- /dev/null +++ b/content/browser/renderer_host/p2p_socket_host_posix.h @@ -0,0 +1,58 @@ +// Copyright (c) 2011 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 CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_POSIX_H_ +#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_POSIX_H_ + +#include "content/common/p2p_sockets.h" + +#include "base/message_loop.h" +#include "content/browser/renderer_host/p2p_socket_host.h" + +class P2PSocketHostPosix : public P2PSocketHost { + public: + P2PSocketHostPosix(P2PSocketsHost* host, int routing_id, int id); + virtual ~P2PSocketHostPosix(); + + virtual bool Init(); + virtual void Send(P2PSocketAddress socket_address, + const std::vector<char>& data); + + private: + enum State { + STATE_UNINITIALIZED, + STATE_OPEN, + STATE_ERROR, + }; + + // MessageLoopForIO::Watcher implementation used to catch read + // events from the socket. + class ReadWatcher : public MessageLoopForIO::Watcher { + public: + explicit ReadWatcher(P2PSocketHostPosix* socket) : socket_(socket) { } + + // MessageLoopForIO::Watcher methods + virtual void OnFileCanReadWithoutBlocking(int /* fd */) { + socket_->DidCompleteRead(); + } + virtual void OnFileCanWriteWithoutBlocking(int /* fd */) {} + + private: + P2PSocketHostPosix* socket_; + + DISALLOW_COPY_AND_ASSIGN(ReadWatcher); + }; + + void DidCompleteRead(); + void OnError(); + + State state_; + int socket_; + MessageLoopForIO::FileDescriptorWatcher read_socket_watcher_; + ReadWatcher read_watcher_; + + DISALLOW_COPY_AND_ASSIGN(P2PSocketHostPosix); +}; + +#endif // CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_POSIX_H_ diff --git a/content/browser/renderer_host/p2p_socket_host_win.cc b/content/browser/renderer_host/p2p_socket_host_win.cc new file mode 100644 index 0000000..6516935 --- /dev/null +++ b/content/browser/renderer_host/p2p_socket_host_win.cc @@ -0,0 +1,12 @@ +// Copyright (c) 2011 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 "content/browser/renderer_host/p2p_socket_host_win.h" + +// static +P2PSocketHost* P2PSocketHost::Create( + P2PSocketsHost* host, int routing_id, int id, P2PSocketType type) { + // TODO(sergeyu): Implement P2PSocketHost on windows. + return NULL; +} diff --git a/content/browser/renderer_host/p2p_socket_host_win.h b/content/browser/renderer_host/p2p_socket_host_win.h new file mode 100644 index 0000000..e9f0f95 --- /dev/null +++ b/content/browser/renderer_host/p2p_socket_host_win.h @@ -0,0 +1,12 @@ +// Copyright (c) 2011 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 CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_WIN_H_ +#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_WIN_H_ + +#include "content/browser/renderer_host/p2p_socket_host.h" + +// TODO(sergeyu): Implement P2PSocketHost on Windows. + +#endif // CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKET_HOST_WIN_H_ diff --git a/content/browser/renderer_host/p2p_sockets_host.cc b/content/browser/renderer_host/p2p_sockets_host.cc new file mode 100644 index 0000000..310bd1d --- /dev/null +++ b/content/browser/renderer_host/p2p_sockets_host.cc @@ -0,0 +1,81 @@ +// Copyright (c) 2011 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 "content/browser/renderer_host/p2p_sockets_host.h" + +#include "content/browser/renderer_host/p2p_socket_host.h" +#include "content/common/p2p_messages.h" + +P2PSocketsHost::P2PSocketsHost() { +} + +P2PSocketsHost::~P2PSocketsHost() { +} + +void P2PSocketsHost::OnChannelClosing() { + BrowserMessageFilter::OnChannelClosing(); + + // Since the IPC channel is gone, close pending connections. + for (IDMap<P2PSocketHost>::iterator i(&sockets_); !i.IsAtEnd(); i.Advance()) { + sockets_.Remove(i.GetCurrentKey()); + } +} + +void P2PSocketsHost::OnDestruct() const { + BrowserThread::DeleteOnIOThread::Destruct(this); +} + +bool P2PSocketsHost::OnMessageReceived(const IPC::Message& message, + bool* message_was_ok) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP_EX(P2PSocketsHost, message, *message_was_ok) + IPC_MESSAGE_HANDLER(P2PHostMsg_CreateSocket, OnCreateSocket) + IPC_MESSAGE_HANDLER(P2PHostMsg_Send, OnSend) + IPC_MESSAGE_HANDLER(P2PHostMsg_DestroySocket, OnDestroySocket) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP_EX() + return handled; +} + +void P2PSocketsHost::OnCreateSocket( + const IPC::Message& msg, P2PSocketType type, int socket_id, + P2PSocketAddress remote_address) { + if (sockets_.Lookup(socket_id)) { + LOG(ERROR) << "Received P2PHostMsg_CreateSocket for socket " + "that already exists."; + return; + } + + if (type != P2P_SOCKET_UDP) { + Send(new P2PMsg_OnError(msg.routing_id(), socket_id)); + return; + } + + scoped_ptr<P2PSocketHost> socket( + P2PSocketHost::Create(this, msg.routing_id(), socket_id, type)); + + if (!socket.get()) { + Send(new P2PMsg_OnError(msg.routing_id(), socket_id)); + return; + } + + if (socket->Init()) { + sockets_.AddWithID(socket.release(), socket_id); + } +} + +void P2PSocketsHost::OnSend(const IPC::Message& msg, int socket_id, + P2PSocketAddress socket_address, + const std::vector<char>& data) { + P2PSocketHost* socket = sockets_.Lookup(socket_id); + if (!socket) { + LOG(ERROR) << "Received P2PHostMsg_Send for invalid socket_id."; + return; + } + socket->Send(socket_address, data); +} + +void P2PSocketsHost::OnDestroySocket(const IPC::Message& msg, int socket_id) { + sockets_.Remove(socket_id); +} diff --git a/content/browser/renderer_host/p2p_sockets_host.h b/content/browser/renderer_host/p2p_sockets_host.h new file mode 100644 index 0000000..9d965eb --- /dev/null +++ b/content/browser/renderer_host/p2p_sockets_host.h @@ -0,0 +1,38 @@ +// Copyright (c) 2011 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 CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKETS_HOST_H_ +#define CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKETS_HOST_H_ + +#include "base/id_map.h" +#include "content/browser/browser_message_filter.h" +#include "content/common/p2p_sockets.h" + +class P2PSocketHost; + +class P2PSocketsHost : public BrowserMessageFilter { + public: + P2PSocketsHost(); + virtual ~P2PSocketsHost(); + + // BrowserMessageFilter overrides. + virtual void OnChannelClosing(); + virtual void OnDestruct() const; + virtual bool OnMessageReceived(const IPC::Message& message, + bool* message_was_ok); + + private: + void OnCreateSocket(const IPC::Message& msg, P2PSocketType type, + int socket_id, P2PSocketAddress remote_address); + void OnSend(const IPC::Message& msg, int socket_id, + P2PSocketAddress socket_address, + const std::vector<char>& data); + void OnDestroySocket(const IPC::Message& msg, int socket_id); + + IDMap<P2PSocketHost> sockets_; + + DISALLOW_COPY_AND_ASSIGN(P2PSocketsHost); +}; + +#endif // CONTENT_BROWSER_RENDERER_HOST_P2P_SOCKETS_HOST_H_ diff --git a/content/common/p2p_messages.cc b/content/common/p2p_messages.cc new file mode 100644 index 0000000..82c5983 --- /dev/null +++ b/content/common/p2p_messages.cc @@ -0,0 +1,31 @@ +// Copyright (c) 2011 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. + +#define IPC_MESSAGE_IMPL +#include "content/common/p2p_messages.h" + +namespace IPC { + +void ParamTraits<P2PSocketAddress>::Write(Message* m, const param_type& p) { + WriteParam(m, p.address); + WriteParam(m, p.port); +} + +bool ParamTraits<P2PSocketAddress>::Read(const Message* m, + void** iter, + param_type* p) { + return + ReadParam(m, iter, &p->address) && + ReadParam(m, iter, &p->port); +} + +void ParamTraits<P2PSocketAddress>::Log(const param_type& p, std::string* l) { + l->append("("); + LogParam(p.address, l); + l->append(", "); + LogParam(p.port, l); + l->append(")"); +} + +} // namespace IPC diff --git a/content/common/p2p_messages.h b/content/common/p2p_messages.h new file mode 100644 index 0000000..6ab75df --- /dev/null +++ b/content/common/p2p_messages.h @@ -0,0 +1,62 @@ +// Copyright (c) 2011 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. + +// IPC messages for the P2P Transport API. + +#ifndef CONTENT_COMMON_P2P_MESSAGES_H_ +#define CONTENT_COMMON_P2P_MESSAGES_H_ + +#include "content/common/p2p_sockets.h" +#include "ipc/ipc_message_macros.h" + +#define IPC_MESSAGE_START P2PMsgStart + +// P2P Socket messages sent from the browser to the renderer. + +IPC_MESSAGE_ROUTED2(P2PMsg_OnSocketCreated, + int /* socket_id */, + P2PSocketAddress /* socket_address */) + +IPC_MESSAGE_ROUTED1(P2PMsg_OnError, + int /* socket_id */) + +IPC_MESSAGE_ROUTED3(P2PMsg_OnDataReceived, + int /* socket_id */, + P2PSocketAddress /* socket_address */, + std::vector<char> /* data */) + +// P2P Socket messages sent from the renderer to the browser. + +IPC_MESSAGE_ROUTED3(P2PHostMsg_CreateSocket, + P2PSocketType /* type */, + int /* socket_id */, + P2PSocketAddress /* remote_address */) + +// TODO(sergeyu): Use shared memory to pass the data. +IPC_MESSAGE_ROUTED3(P2PHostMsg_Send, + int /* socket_id */, + P2PSocketAddress /* socket_address */, + std::vector<char> /* data */) + +IPC_MESSAGE_ROUTED1(P2PHostMsg_DestroySocket, + int /* socket_id */) + +namespace IPC { + +template <> +struct ParamTraits<P2PSocketAddress> { + typedef P2PSocketAddress param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* p); + static void Log(const param_type& p, std::string* l); +}; + +template <> +struct SimilarTypeTraits<P2PSocketType> { + typedef int Type; +}; + +} // namespace IPC + +#endif // CONTENT_COMMON_P2P_MESSAGES_H_ diff --git a/content/common/p2p_sockets.h b/content/common/p2p_sockets.h new file mode 100644 index 0000000..5406f02 --- /dev/null +++ b/content/common/p2p_sockets.h @@ -0,0 +1,27 @@ +// Copyright (c) 2011 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. + +// This file defines some basic types used by the P2P-related IPC +// messages. + +#ifndef CONTENT_COMMON_P2P_SOCKETS_H_ +#define CONTENT_COMMON_P2P_SOCKETS_H_ + +#include "net/base/net_util.h" + +// Pair of IP address and port number. +struct P2PSocketAddress { + P2PSocketAddress() : port(0) { } + net::IPAddressNumber address; + int port; +}; + +// Type of P2P Socket. +enum P2PSocketType { + P2P_SOCKET_UDP, + P2P_SOCKET_TCP_SERVER, + P2P_SOCKET_TCP_CLIENT, +}; + +#endif // CONTENT_COMMON_P2P_SOCKETS_H_ diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 2650e10..6bc18b5 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -8,8 +8,7 @@ 'target_name': 'content_browser', 'type': '<(library)', 'dependencies': [ - # Don't include now since it's empty and so will cause a linker error. - #'content_common', + 'content_common', '../app/app.gyp:app_resources', '../ppapi/ppapi.gyp:ppapi_proxy', '../skia/skia.gyp:skia', @@ -205,6 +204,14 @@ 'browser/renderer_host/pepper_file_message_filter.h', 'browser/renderer_host/pepper_message_filter.cc', 'browser/renderer_host/pepper_message_filter.h', + 'browser/renderer_host/p2p_socket_host.cc', + 'browser/renderer_host/p2p_socket_host.h', + 'browser/renderer_host/p2p_socket_host_posix.cc', + 'browser/renderer_host/p2p_socket_host_posix.h', + 'browser/renderer_host/p2p_socket_host_win.cc', + 'browser/renderer_host/p2p_socket_host_win.h', + 'browser/renderer_host/p2p_sockets_host.cc', + 'browser/renderer_host/p2p_sockets_host.h', 'browser/renderer_host/redirect_to_file_resource_handler.cc', 'browser/renderer_host/redirect_to_file_resource_handler.h', 'browser/renderer_host/render_message_filter.cc', diff --git a/content/content_common.gypi b/content/content_common.gypi index 0ef8194..5e50dcd 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi @@ -14,6 +14,9 @@ '..', ], 'sources': [ + "common/p2p_messages.cc", + "common/p2p_messages.h", + "common/p2p_sockets.h", ], 'conditions': [ ['OS=="win"', { diff --git a/ipc/ipc_message_utils.h b/ipc/ipc_message_utils.h index 9c1752d..1b669f1 100644 --- a/ipc/ipc_message_utils.h +++ b/ipc/ipc_message_utils.h @@ -69,6 +69,7 @@ enum IPCMessageStart { PepperMsgStart, AutoFillMsgStart, SafeBrowsingMsgStart, + P2PMsgStart, }; class DictionaryValue; |