Index: chrome/browser/renderer_host/pepper_message_filter.cc |
=================================================================== |
--- chrome/browser/renderer_host/pepper_message_filter.cc (revision 75488) |
+++ chrome/browser/renderer_host/pepper_message_filter.cc (working copy) |
@@ -1,280 +0,0 @@ |
-// 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 "chrome/browser/renderer_host/pepper_message_filter.h" |
- |
-#include "base/basictypes.h" |
-#include "base/process_util.h" |
-#include "base/threading/worker_pool.h" |
-#include "chrome/browser/browser_thread.h" |
-#include "chrome/browser/net/chrome_url_request_context.h" |
-#include "chrome/browser/profiles/profile.h" |
-#include "chrome/browser/renderer_host/browser_render_process_host.h" |
-#include "chrome/common/pepper_messages.h" |
-#include "net/base/address_list.h" |
-#include "net/base/host_port_pair.h" |
-#include "net/base/host_resolver.h" |
-#include "net/url_request/url_request_context.h" |
-#include "webkit/plugins/ppapi/ppb_flash_impl.h" |
- |
-#if defined(ENABLE_FLAPPER_HACKS) |
-#include <netdb.h> |
-#include <string.h> |
-#include <sys/socket.h> |
-#include <sys/types.h> |
-#include <unistd.h> |
- |
-// Make sure the storage in |PP_Flash_NetAddress| is big enough. (Do it here |
-// since the data is opaque elsewhere.) |
-COMPILE_ASSERT(sizeof(reinterpret_cast<PP_Flash_NetAddress*>(0)->data) >= |
- sizeof(sockaddr_storage), PP_Flash_NetAddress_data_too_small); |
-#endif // ENABLE_FLAPPER_HACKS |
- |
-const PP_Flash_NetAddress kInvalidNetAddress = { 0 }; |
- |
-PepperMessageFilter::PepperMessageFilter(Profile* profile) |
- : profile_(profile), |
- request_context_(profile_->GetRequestContext()) { |
-} |
- |
-PepperMessageFilter::~PepperMessageFilter() {} |
- |
-bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg, |
- bool* message_was_ok) { |
-#if defined(ENABLE_FLAPPER_HACKS) |
- bool handled = true; |
- IPC_BEGIN_MESSAGE_MAP_EX(PepperMessageFilter, msg, *message_was_ok) |
- IPC_MESSAGE_HANDLER(PepperMsg_ConnectTcp, OnConnectTcp) |
- IPC_MESSAGE_HANDLER(PepperMsg_ConnectTcpAddress, OnConnectTcpAddress) |
- IPC_MESSAGE_UNHANDLED(handled = false) |
- IPC_END_MESSAGE_MAP_EX() |
- return handled; |
-#else |
- return false; |
-#endif // ENABLE_FLAPPER_HACKS |
-} |
- |
-#if defined(ENABLE_FLAPPER_HACKS) |
- |
-namespace { |
- |
-bool ValidateNetAddress(const PP_Flash_NetAddress& addr) { |
- if (addr.size < sizeof(sa_family_t)) |
- return false; |
- |
- // TODO(viettrungluu): more careful validation? |
- // Just do a size check for AF_INET. |
- if (reinterpret_cast<const sockaddr*>(addr.data)->sa_family == AF_INET && |
- addr.size >= sizeof(sockaddr_in)) |
- return true; |
- |
- // Ditto for AF_INET6. |
- if (reinterpret_cast<const sockaddr*>(addr.data)->sa_family == AF_INET6 && |
- addr.size >= sizeof(sockaddr_in6)) |
- return true; |
- |
- // Reject everything else. |
- return false; |
-} |
- |
-PP_Flash_NetAddress SockaddrToNetAddress(const struct sockaddr* sa, |
- socklen_t sa_length) { |
- PP_Flash_NetAddress addr; |
- CHECK_LE(sa_length, sizeof(addr.data)); |
- addr.size = sa_length; |
- memcpy(addr.data, sa, addr.size); |
- return addr; |
-} |
- |
-int ConnectTcpSocket(const PP_Flash_NetAddress& addr, |
- PP_Flash_NetAddress* local_addr_out, |
- PP_Flash_NetAddress* remote_addr_out) { |
- *local_addr_out = kInvalidNetAddress; |
- *remote_addr_out = kInvalidNetAddress; |
- |
- const struct sockaddr* sa = |
- reinterpret_cast<const struct sockaddr*>(addr.data); |
- socklen_t sa_len = addr.size; |
- int fd = socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP); |
- if (fd == -1) |
- return -1; |
- if (connect(fd, sa, sa_len) != 0) { |
- close(fd); |
- return -1; |
- } |
- |
- // Get the local address. |
- socklen_t local_length = sizeof(local_addr_out->data); |
- if (getsockname(fd, reinterpret_cast<struct sockaddr*>(local_addr_out->data), |
- &local_length) == -1 || |
- local_length > sizeof(local_addr_out->data)) { |
- close(fd); |
- return -1; |
- } |
- |
- // The remote address is just the address we connected to. |
- *remote_addr_out = addr; |
- |
- return fd; |
-} |
- |
-} // namespace |
- |
-class PepperMessageFilter::LookupRequest { |
- public: |
- LookupRequest(PepperMessageFilter* pepper_message_filter, |
- net::HostResolver* resolver, |
- int routing_id, |
- int request_id, |
- const net::HostResolver::RequestInfo& request_info) |
- : ALLOW_THIS_IN_INITIALIZER_LIST( |
- net_callback_(this, &LookupRequest::OnLookupFinished)), |
- pepper_message_filter_(pepper_message_filter), |
- resolver_(resolver), |
- routing_id_(routing_id), |
- request_id_(request_id), |
- request_info_(request_info) { |
- } |
- |
- void Start() { |
- int result = resolver_.Resolve(request_info_, &addresses_, &net_callback_, |
- net::BoundNetLog()); |
- if (result != net::ERR_IO_PENDING) |
- OnLookupFinished(result); |
- } |
- |
- private: |
- void OnLookupFinished(int /*result*/) { |
- pepper_message_filter_->ConnectTcpLookupFinished( |
- routing_id_, request_id_, addresses_); |
- delete this; |
- } |
- |
- // HostResolver will call us using this callback when resolution is complete. |
- net::CompletionCallbackImpl<LookupRequest> net_callback_; |
- |
- PepperMessageFilter* pepper_message_filter_; |
- net::SingleRequestHostResolver resolver_; |
- |
- int routing_id_; |
- int request_id_; |
- net::HostResolver::RequestInfo request_info_; |
- |
- net::AddressList addresses_; |
- |
- DISALLOW_COPY_AND_ASSIGN(LookupRequest); |
-}; |
- |
-void PepperMessageFilter::OnConnectTcp(int routing_id, |
- int request_id, |
- const std::string& host, |
- uint16 port) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
- net::URLRequestContext* req_context = |
- request_context_->GetURLRequestContext(); |
- net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port)); |
- |
- // The lookup request will delete itself on completion. |
- LookupRequest* lookup_request = |
- new LookupRequest(this, req_context->host_resolver(), |
- routing_id, request_id, request_info); |
- lookup_request->Start(); |
-} |
- |
-void PepperMessageFilter::OnConnectTcpAddress(int routing_id, |
- int request_id, |
- const PP_Flash_NetAddress& addr) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
- // Validate the address and then continue (doing |connect()|) on a worker |
- // thread. |
- if (!ValidateNetAddress(addr) || |
- !base::WorkerPool::PostTask(FROM_HERE, |
- NewRunnableMethod( |
- this, |
- &PepperMessageFilter::ConnectTcpAddressOnWorkerThread, |
- routing_id, request_id, addr), |
- true)) { |
- SendConnectTcpACKError(routing_id, request_id); |
- } |
-} |
- |
-bool PepperMessageFilter::SendConnectTcpACKError(int routing_id, |
- int request_id) { |
- return Send( |
- new PepperMsg_ConnectTcpACK(routing_id, request_id, |
- IPC::InvalidPlatformFileForTransit(), |
- kInvalidNetAddress, kInvalidNetAddress)); |
-} |
- |
-void PepperMessageFilter::ConnectTcpLookupFinished( |
- int routing_id, |
- int request_id, |
- const net::AddressList& addresses) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
- |
- // If the lookup returned addresses, continue (doing |connect()|) on a worker |
- // thread. |
- if (!addresses.head() || |
- !base::WorkerPool::PostTask(FROM_HERE, |
- NewRunnableMethod( |
- this, |
- &PepperMessageFilter::ConnectTcpOnWorkerThread, |
- routing_id, request_id, addresses), |
- true)) { |
- SendConnectTcpACKError(routing_id, request_id); |
- } |
-} |
- |
-void PepperMessageFilter::ConnectTcpOnWorkerThread(int routing_id, |
- int request_id, |
- net::AddressList addresses) { |
- IPC::PlatformFileForTransit socket_for_transit = |
- IPC::InvalidPlatformFileForTransit(); |
- PP_Flash_NetAddress local_addr = kInvalidNetAddress; |
- PP_Flash_NetAddress remote_addr = kInvalidNetAddress; |
- |
- for (const struct addrinfo* ai = addresses.head(); ai; ai = ai->ai_next) { |
- PP_Flash_NetAddress addr = SockaddrToNetAddress(ai->ai_addr, |
- ai->ai_addrlen); |
- int fd = ConnectTcpSocket(addr, &local_addr, &remote_addr); |
- if (fd != -1) { |
- socket_for_transit = base::FileDescriptor(fd, true); |
- break; |
- } |
- } |
- |
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
- NewRunnableMethod( |
- this, &PepperMessageFilter::Send, |
- new PepperMsg_ConnectTcpACK( |
- routing_id, request_id, |
- socket_for_transit, local_addr, remote_addr))); |
-} |
- |
-// TODO(vluu): Eliminate duplication between this and |
-// |ConnectTcpOnWorkerThread()|. |
-void PepperMessageFilter::ConnectTcpAddressOnWorkerThread( |
- int routing_id, |
- int request_id, |
- PP_Flash_NetAddress addr) { |
- IPC::PlatformFileForTransit socket_for_transit = |
- IPC::InvalidPlatformFileForTransit(); |
- PP_Flash_NetAddress local_addr = kInvalidNetAddress; |
- PP_Flash_NetAddress remote_addr = kInvalidNetAddress; |
- |
- int fd = ConnectTcpSocket(addr, &local_addr, &remote_addr); |
- if (fd != -1) |
- socket_for_transit = base::FileDescriptor(fd, true); |
- |
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
- NewRunnableMethod( |
- this, &PepperMessageFilter::Send, |
- new PepperMsg_ConnectTcpACK( |
- routing_id, request_id, |
- socket_for_transit, local_addr, remote_addr))); |
-} |
- |
-#endif // ENABLE_FLAPPER_HACKS |