summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/generated_resources.grd6
-rw-r--r--chrome/browser/about_flags.cc7
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc5
-rw-r--r--chrome/chrome_common.gypi3
-rw-r--r--chrome/common/chrome_switches.cc3
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/render_messages.h4
-rw-r--r--content/browser/renderer_host/p2p_socket_host.cc11
-rw-r--r--content/browser/renderer_host/p2p_socket_host.h39
-rw-r--r--content/browser/renderer_host/p2p_socket_host_posix.cc260
-rw-r--r--content/browser/renderer_host/p2p_socket_host_posix.h58
-rw-r--r--content/browser/renderer_host/p2p_socket_host_win.cc12
-rw-r--r--content/browser/renderer_host/p2p_socket_host_win.h12
-rw-r--r--content/browser/renderer_host/p2p_sockets_host.cc81
-rw-r--r--content/browser/renderer_host/p2p_sockets_host.h38
-rw-r--r--content/common/p2p_messages.cc31
-rw-r--r--content/common/p2p_messages.h62
-rw-r--r--content/common/p2p_sockets.h27
-rw-r--r--content/content_browser.gypi11
-rw-r--r--content/content_common.gypi3
-rw-r--r--ipc/ipc_message_utils.h1
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;