Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(497)

Unified Diff: content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc

Issue 19005006: Switched proxy for TCPServerSocketPrivate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync, fix. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..48c8291cab9889d9b5b3bb61cf801118442882ce
--- /dev/null
+++ b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc
@@ -0,0 +1,318 @@
+// Copyright 2013 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/pepper/pepper_tcp_server_socket_message_filter.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/logging.h"
+#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
+#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/common/socket_permission_request.h"
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
+#include "net/base/net_util.h"
+#include "net/socket/tcp_client_socket.h"
+#include "net/socket/tcp_server_socket.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/private/ppb_net_address_private.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/error_conversion.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/shared_impl/api_id.h"
+#include "ppapi/shared_impl/private/net_address_private_impl.h"
+
+using ppapi::NetAddressPrivateImpl;
+using ppapi::host::NetErrorToPepperError;
+
+namespace {
+
+size_t g_num_instances = 0;
+
+} // namespace
+
+namespace content {
+
+PepperTCPServerSocketMessageFilter::PepperTCPServerSocketMessageFilter(
+ BrowserPpapiHostImpl* host,
+ PP_Instance instance,
+ bool private_api,
+ const scoped_refptr<PepperMessageFilter>& pepper_message_filter)
+ : state_(STATE_BEFORE_LISTENING),
+ pepper_message_filter_(pepper_message_filter),
+ external_plugin_(host->external_plugin()),
+ private_api_(private_api),
+ render_process_id_(0),
+ render_view_id_(0) {
+ ++g_num_instances;
+ DCHECK(host);
+ if (!host->GetRenderViewIDsForInstance(instance,
+ &render_process_id_,
+ &render_view_id_)) {
+ NOTREACHED();
+ }
+}
+
+PepperTCPServerSocketMessageFilter::~PepperTCPServerSocketMessageFilter() {
+ --g_num_instances;
+}
+
+// static
+size_t PepperTCPServerSocketMessageFilter::GetNumInstances() {
+ return g_num_instances;
+}
+
+scoped_refptr<base::TaskRunner>
+PepperTCPServerSocketMessageFilter::OverrideTaskRunnerForMessage(
+ const IPC::Message& message) {
+ switch (message.type()) {
+ case PpapiHostMsg_TCPServerSocket_Listen::ID:
+ return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
+ case PpapiHostMsg_TCPServerSocket_Accept::ID:
+ case PpapiHostMsg_TCPServerSocket_StopListening::ID:
+ return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
+ }
+ return NULL;
+}
+
+int32_t PepperTCPServerSocketMessageFilter::OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) {
+ IPC_BEGIN_MESSAGE_MAP(PepperTCPServerSocketMessageFilter, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(
+ PpapiHostMsg_TCPServerSocket_Listen, OnMsgListen)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(
+ PpapiHostMsg_TCPServerSocket_Accept, OnMsgAccept)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
+ PpapiHostMsg_TCPServerSocket_StopListening, OnMsgStopListening)
+ IPC_END_MESSAGE_MAP()
+ return PP_ERROR_FAILED;
+}
+
+int32_t PepperTCPServerSocketMessageFilter::OnMsgListen(
+ const ppapi::host::HostMessageContext* context,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(context);
+
+ SocketPermissionRequest request =
+ pepper_socket_utils::CreateSocketPermissionRequest(
+ content::SocketPermissionRequest::TCP_LISTEN, addr);
+ if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_,
+ private_api_,
+ request,
+ render_process_id_,
+ render_view_id_)) {
+ return PP_ERROR_NOACCESS;
+ }
+
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&PepperTCPServerSocketMessageFilter::DoListen, this,
+ context->MakeReplyMessageContext(), addr, backlog));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PepperTCPServerSocketMessageFilter::OnMsgAccept(
+ const ppapi::host::HostMessageContext* context,
+ uint32 plugin_dispatcher_id) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(context);
+
+ if (state_ != STATE_LISTENING)
+ return PP_ERROR_FAILED;
+
+ state_ = STATE_ACCEPT_IN_PROGRESS;
+ ppapi::host::ReplyMessageContext reply_context(
+ context->MakeReplyMessageContext());
+ int net_result = socket_->Accept(
+ &socket_buffer_,
+ base::Bind(&PepperTCPServerSocketMessageFilter::OnAcceptCompleted,
+ base::Unretained(this),
+ reply_context, plugin_dispatcher_id));
+ if (net_result != net::ERR_IO_PENDING)
+ OnAcceptCompleted(reply_context, plugin_dispatcher_id, net_result);
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t PepperTCPServerSocketMessageFilter::OnMsgStopListening(
+ const ppapi::host::HostMessageContext* context) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(context);
+
+ state_ = STATE_CLOSED;
+ socket_.reset();
+ return PP_OK;
+}
+
+void PepperTCPServerSocketMessageFilter::DoListen(
+ const ppapi::host::ReplyMessageContext& context,
+ const PP_NetAddress_Private& addr,
+ int32_t backlog) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ net::IPAddressNumber address;
+ int port;
+ if (state_ != STATE_BEFORE_LISTENING ||
+ !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
+ SendListenError(context, PP_ERROR_FAILED);
+ state_ = STATE_CLOSED;
+ return;
+ }
+
+ state_ = STATE_LISTEN_IN_PROGRESS;
+
+ socket_.reset(new net::TCPServerSocket(NULL, net::NetLog::Source()));
+ int net_result = socket_->Listen(net::IPEndPoint(address, port), backlog);
+ if (net_result != net::ERR_IO_PENDING)
+ OnListenCompleted(context, net_result);
+}
+
+void PepperTCPServerSocketMessageFilter::OnListenCompleted(
+ const ppapi::host::ReplyMessageContext& context,
+ int net_result) {
+ if (state_ != STATE_LISTEN_IN_PROGRESS) {
+ SendListenError(context, PP_ERROR_FAILED);
+ state_ = STATE_CLOSED;
+ return;
+ }
+ if (net_result != net::OK) {
+ SendListenError(context, NetErrorToPepperError(net_result));
+ state_ = STATE_BEFORE_LISTENING;
+ return;
+ }
+
+ DCHECK(socket_.get());
+
+ net::IPEndPoint end_point;
+ PP_NetAddress_Private addr;
+
+ int32_t pp_result =
+ NetErrorToPepperError(socket_->GetLocalAddress(&end_point));
+ if (pp_result != PP_OK) {
+ SendListenError(context, pp_result);
+ state_ = STATE_BEFORE_LISTENING;
+ return;
+ }
+ if (!NetAddressPrivateImpl::IPEndPointToNetAddress(end_point.address(),
+ end_point.port(),
+ &addr)) {
+ SendListenError(context, PP_ERROR_FAILED);
+ state_ = STATE_BEFORE_LISTENING;
+ return;
+ }
+
+ SendListenReply(context, PP_OK, addr);
+ state_ = STATE_LISTENING;
+}
+
+void PepperTCPServerSocketMessageFilter::OnAcceptCompleted(
+ const ppapi::host::ReplyMessageContext& context,
+ uint32 plugin_dispatcher_id,
+ int net_result) {
+ if (state_ != STATE_ACCEPT_IN_PROGRESS) {
+ SendAcceptError(context, PP_ERROR_FAILED);
+ state_ = STATE_CLOSED;
+ return;
+ }
+
+ state_ = STATE_LISTENING;
+
+ if (net_result != net::OK) {
+ SendAcceptError(context, NetErrorToPepperError(net_result));
+ return;
+ }
+
+ DCHECK(socket_buffer_.get());
+
+ scoped_ptr<net::StreamSocket> socket(socket_buffer_.release());
+ net::IPEndPoint ip_end_point_local;
+ net::IPEndPoint ip_end_point_remote;
+ PP_NetAddress_Private local_addr = NetAddressPrivateImpl::kInvalidNetAddress;
+ PP_NetAddress_Private remote_addr = NetAddressPrivateImpl::kInvalidNetAddress;
+
+ int32_t pp_result =
+ NetErrorToPepperError(socket->GetLocalAddress(&ip_end_point_local));
+ if (pp_result != PP_OK) {
+ SendAcceptError(context, pp_result);
+ return;
+ }
+ if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
+ ip_end_point_local.address(),
+ ip_end_point_local.port(),
+ &local_addr)) {
+ SendAcceptError(context, PP_ERROR_FAILED);
+ return;
+ }
+ pp_result =
+ NetErrorToPepperError(socket->GetPeerAddress(&ip_end_point_remote));
+ if (pp_result != PP_OK) {
+ SendAcceptError(context, pp_result);
+ return;
+ }
+ if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
+ ip_end_point_remote.address(),
+ ip_end_point_remote.port(),
+ &remote_addr)) {
+ SendAcceptError(context, PP_ERROR_FAILED);
+ return;
+ }
+ if (!pepper_message_filter_.get() || plugin_dispatcher_id == 0) {
+ SendAcceptError(context, PP_ERROR_FAILED);
+ return;
+ }
+ uint32 accepted_socket_id = pepper_message_filter_->AddAcceptedTCPSocket(
+ ppapi::API_ID_PPB_TCPSOCKET_PRIVATE,
+ plugin_dispatcher_id,
+ socket.release());
+ if (accepted_socket_id != 0) {
+ SendAcceptReply(context, PP_OK, accepted_socket_id, local_addr,
+ remote_addr);
+ } else {
+ SendAcceptError(context, PP_ERROR_NOSPACE);
+ }
+}
+
+void PepperTCPServerSocketMessageFilter::SendListenReply(
+ const ppapi::host::ReplyMessageContext& context,
+ int32_t pp_result,
+ const PP_NetAddress_Private& local_addr) {
+ ppapi::host::ReplyMessageContext reply_context(context);
+ reply_context.params.set_result(pp_result);
+ SendReply(reply_context,
+ PpapiPluginMsg_TCPServerSocket_ListenReply(local_addr));
+}
+
+void PepperTCPServerSocketMessageFilter::SendListenError(
+ const ppapi::host::ReplyMessageContext& context,
+ int32_t pp_result) {
+ SendListenReply(context, pp_result,
+ NetAddressPrivateImpl::kInvalidNetAddress);
+}
+
+void PepperTCPServerSocketMessageFilter::SendAcceptReply(
+ const ppapi::host::ReplyMessageContext& context,
+ int32_t pp_result,
+ uint32 accepted_socket_id,
+ const PP_NetAddress_Private& local_addr,
+ const PP_NetAddress_Private& remote_addr) {
+ ppapi::host::ReplyMessageContext reply_context(context);
+ reply_context.params.set_result(pp_result);
+ SendReply(reply_context, PpapiPluginMsg_TCPServerSocket_AcceptReply(
+ accepted_socket_id, local_addr, remote_addr));
+}
+
+void PepperTCPServerSocketMessageFilter::SendAcceptError(
+ const ppapi::host::ReplyMessageContext& context,
+ int32_t pp_result) {
+ SendAcceptReply(context,
+ pp_result,
+ 0,
+ NetAddressPrivateImpl::kInvalidNetAddress,
+ NetAddressPrivateImpl::kInvalidNetAddress);
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698