12385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
22385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// Use of this source code is governed by a BSD-style license that can be
32385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// found in the LICENSE file.
42385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
52385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h"
62385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
72385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/bind.h"
82385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/bind_helpers.h"
92385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "base/logging.h"
102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h"
122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/public/browser/browser_thread.h"
142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "content/public/common/socket_permission_request.h"
152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "net/base/ip_endpoint.h"
162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "net/base/net_errors.h"
172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "net/base/net_util.h"
182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "ppapi/c/pp_errors.h"
192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "ppapi/c/private/ppb_net_address_private.h"
202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "ppapi/host/dispatch_host_message.h"
212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "ppapi/host/error_conversion.h"
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/host/ppapi_host.h"
23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/host/resource_host.h"
242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "ppapi/proxy/ppapi_messages.h"
252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "ppapi/shared_impl/api_id.h"
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ppapi/shared_impl/ppb_tcp_socket_shared.h"
272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch#include "ppapi/shared_impl/private/net_address_private_impl.h"
282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochusing ppapi::NetAddressPrivateImpl;
302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochusing ppapi::host::NetErrorToPepperError;
312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochnamespace {
332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochsize_t g_num_instances = 0;
352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}  // namespace
372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochnamespace content {
392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochPepperTCPServerSocketMessageFilter::PepperTCPServerSocketMessageFilter(
41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    ContentBrowserPepperHostFactory* factory,
422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    BrowserPpapiHostImpl* host,
432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    PP_Instance instance,
44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    bool private_api)
45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    : ppapi_host_(host->GetPpapiHost()),
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      factory_(factory),
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      instance_(instance),
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      state_(STATE_BEFORE_LISTENING),
492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      external_plugin_(host->external_plugin()),
502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      private_api_(private_api),
512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      render_process_id_(0),
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      render_frame_id_(0) {
532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ++g_num_instances;
54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(factory_);
55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(ppapi_host_);
56a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!host->GetRenderFrameIDsForInstance(
57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          instance, &render_process_id_, &render_frame_id_)) {
582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    NOTREACHED();
592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochPepperTCPServerSocketMessageFilter::~PepperTCPServerSocketMessageFilter() {
632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  --g_num_instances;
642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch// static
672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochsize_t PepperTCPServerSocketMessageFilter::GetNumInstances() {
682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return g_num_instances;
692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochscoped_refptr<base::TaskRunner>
722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochPepperTCPServerSocketMessageFilter::OverrideTaskRunnerForMessage(
732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const IPC::Message& message) {
742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  switch (message.type()) {
752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    case PpapiHostMsg_TCPServerSocket_Listen::ID:
762385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
772385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    case PpapiHostMsg_TCPServerSocket_Accept::ID:
782385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    case PpapiHostMsg_TCPServerSocket_StopListening::ID:
792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
812385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return NULL;
822385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
832385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
842385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochint32_t PepperTCPServerSocketMessageFilter::OnResourceMessageReceived(
852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const IPC::Message& msg,
862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    ppapi::host::HostMessageContext* context) {
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PPAPI_BEGIN_MESSAGE_MAP(PepperTCPServerSocketMessageFilter, msg)
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPServerSocket_Listen,
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                      OnMsgListen)
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TCPServerSocket_Accept,
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                        OnMsgAccept)
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        PpapiHostMsg_TCPServerSocket_StopListening, OnMsgStopListening)
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  PPAPI_END_MESSAGE_MAP()
952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return PP_ERROR_FAILED;
962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochint32_t PepperTCPServerSocketMessageFilter::OnMsgListen(
992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ppapi::host::HostMessageContext* context,
1002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const PP_NetAddress_Private& addr,
1012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int32_t backlog) {
102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::UI);
1032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(context);
1042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  SocketPermissionRequest request =
1062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      pepper_socket_utils::CreateSocketPermissionRequest(
1072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          content::SocketPermissionRequest::TCP_LISTEN, addr);
1082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_,
1092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                             private_api_,
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                             &request,
1112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                                             render_process_id_,
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             render_frame_id_)) {
1132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return PP_ERROR_NOACCESS;
1142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
1152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  BrowserThread::PostTask(
117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      BrowserThread::IO,
118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      FROM_HERE,
119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      base::Bind(&PepperTCPServerSocketMessageFilter::DoListen,
120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 this,
121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 context->MakeReplyMessageContext(),
122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 addr,
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 backlog));
1242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return PP_OK_COMPLETIONPENDING;
1252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochint32_t PepperTCPServerSocketMessageFilter::OnMsgAccept(
128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    const ppapi::host::HostMessageContext* context) {
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
1302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(context);
1312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (state_ != STATE_LISTENING)
1332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return PP_ERROR_FAILED;
1342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  state_ = STATE_ACCEPT_IN_PROGRESS;
1362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ppapi::host::ReplyMessageContext reply_context(
1372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      context->MakeReplyMessageContext());
1382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  int net_result = socket_->Accept(
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      &accepted_socket_,
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      &accepted_address_,
1412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      base::Bind(&PepperTCPServerSocketMessageFilter::OnAcceptCompleted,
142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 base::Unretained(this),
143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                 reply_context));
1442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (net_result != net::ERR_IO_PENDING)
145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    OnAcceptCompleted(reply_context, net_result);
1462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return PP_OK_COMPLETIONPENDING;
1472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1492385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochint32_t PepperTCPServerSocketMessageFilter::OnMsgStopListening(
1502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ppapi::host::HostMessageContext* context) {
151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
1522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(context);
1532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  state_ = STATE_CLOSED;
1552385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  socket_.reset();
1562385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  return PP_OK;
1572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid PepperTCPServerSocketMessageFilter::DoListen(
1602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ppapi::host::ReplyMessageContext& context,
1612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const PP_NetAddress_Private& addr,
1622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int32_t backlog) {
163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  DCHECK_CURRENTLY_ON(BrowserThread::IO);
1642385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1652385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  net::IPAddressNumber address;
1662385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  int port;
1672385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (state_ != STATE_BEFORE_LISTENING ||
1682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
1692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SendListenError(context, PP_ERROR_FAILED);
1702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    state_ = STATE_CLOSED;
1712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
1722385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
1732385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1742385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  state_ = STATE_LISTEN_IN_PROGRESS;
1752385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  socket_.reset(new net::TCPSocket(NULL, net::NetLog::Source()));
17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int net_result = net::OK;
17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  do {
17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    net::IPEndPoint ip_end_point(address, port);
18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    net_result = socket_->Open(ip_end_point.GetFamily());
18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (net_result != net::OK)
18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      break;
18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    net_result = socket_->SetDefaultOptionsForServer();
18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (net_result != net::OK)
18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      break;
18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    net_result = socket_->Bind(ip_end_point);
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (net_result != net::OK)
18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      break;
18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    net_result = socket_->Listen(backlog);
19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } while (false);
19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (net_result != net::ERR_IO_PENDING)
1932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    OnListenCompleted(context, net_result);
1942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
1952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
1962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid PepperTCPServerSocketMessageFilter::OnListenCompleted(
1972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ppapi::host::ReplyMessageContext& context,
1982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int net_result) {
1992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (state_ != STATE_LISTEN_IN_PROGRESS) {
2002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SendListenError(context, PP_ERROR_FAILED);
2012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    state_ = STATE_CLOSED;
2022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
2032385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
2042385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (net_result != net::OK) {
2052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SendListenError(context, NetErrorToPepperError(net_result));
2062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    state_ = STATE_BEFORE_LISTENING;
2072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
2082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
2092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2102385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  DCHECK(socket_.get());
2112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  net::IPEndPoint end_point;
2132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  PP_NetAddress_Private addr;
2142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2152385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  int32_t pp_result =
2162385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch      NetErrorToPepperError(socket_->GetLocalAddress(&end_point));
2172385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (pp_result != PP_OK) {
2182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SendListenError(context, pp_result);
2192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    state_ = STATE_BEFORE_LISTENING;
2202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
2212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
222a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
223a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          end_point.address(), end_point.port(), &addr)) {
2242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SendListenError(context, PP_ERROR_FAILED);
2252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    state_ = STATE_BEFORE_LISTENING;
2262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
2272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
2282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  SendListenReply(context, PP_OK, addr);
2302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  state_ = STATE_LISTENING;
2312385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
2322385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2332385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid PepperTCPServerSocketMessageFilter::OnAcceptCompleted(
2342385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ppapi::host::ReplyMessageContext& context,
2352385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int net_result) {
2362385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (state_ != STATE_ACCEPT_IN_PROGRESS) {
2372385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SendAcceptError(context, PP_ERROR_FAILED);
2382385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    state_ = STATE_CLOSED;
2392385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
2402385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
2412385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2422385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  state_ = STATE_LISTENING;
2432385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2442385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (net_result != net::OK) {
2452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SendAcceptError(context, NetErrorToPepperError(net_result));
2462385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
2472385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
2482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(accepted_socket_.get());
2502385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2512385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  net::IPEndPoint ip_end_point_local;
2522385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  PP_NetAddress_Private local_addr = NetAddressPrivateImpl::kInvalidNetAddress;
2532385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  PP_NetAddress_Private remote_addr = NetAddressPrivateImpl::kInvalidNetAddress;
2542385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int32_t pp_result = NetErrorToPepperError(
256a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      accepted_socket_->GetLocalAddress(&ip_end_point_local));
2572385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (pp_result != PP_OK) {
2582385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SendAcceptError(context, pp_result);
2592385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
2602385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
2612385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
2622385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          ip_end_point_local.address(),
2632385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          ip_end_point_local.port(),
26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          &local_addr) ||
26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      !NetAddressPrivateImpl::IPEndPointToNetAddress(
26668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          accepted_address_.address(),
26768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          accepted_address_.port(),
2682385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch          &remote_addr)) {
2692385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SendAcceptError(context, PP_ERROR_FAILED);
2702385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
2712385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  scoped_ptr<ppapi::host::ResourceHost> host =
274a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      factory_->CreateAcceptedTCPSocket(instance_,
275a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                        ppapi::TCP_SOCKET_VERSION_PRIVATE,
276a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                        accepted_socket_.Pass());
277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!host) {
278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    SendAcceptError(context, PP_ERROR_NOSPACE);
2792385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    return;
2802385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int pending_resource_id = ppapi_host_->AddPendingResourceHost(host.Pass());
282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (pending_resource_id) {
283a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    SendAcceptReply(
284a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        context, PP_OK, pending_resource_id, local_addr, remote_addr);
2852385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  } else {
2862385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    SendAcceptError(context, PP_ERROR_NOSPACE);
2872385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  }
2882385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
2892385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
2902385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid PepperTCPServerSocketMessageFilter::SendListenReply(
2912385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ppapi::host::ReplyMessageContext& context,
2922385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int32_t pp_result,
2932385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const PP_NetAddress_Private& local_addr) {
2942385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ppapi::host::ReplyMessageContext reply_context(context);
2952385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  reply_context.params.set_result(pp_result);
2962385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  SendReply(reply_context,
2972385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch            PpapiPluginMsg_TCPServerSocket_ListenReply(local_addr));
2982385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
2992385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3002385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid PepperTCPServerSocketMessageFilter::SendListenError(
3012385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ppapi::host::ReplyMessageContext& context,
3022385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int32_t pp_result) {
303a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SendListenReply(
304a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      context, pp_result, NetAddressPrivateImpl::kInvalidNetAddress);
3052385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3062385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3072385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid PepperTCPServerSocketMessageFilter::SendAcceptReply(
3082385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ppapi::host::ReplyMessageContext& context,
3092385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int32_t pp_result,
310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    int pending_resource_id,
3112385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const PP_NetAddress_Private& local_addr,
3122385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const PP_NetAddress_Private& remote_addr) {
3132385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  ppapi::host::ReplyMessageContext reply_context(context);
3142385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  reply_context.params.set_result(pp_result);
315a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SendReply(reply_context,
316a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            PpapiPluginMsg_TCPServerSocket_AcceptReply(
317a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                pending_resource_id, local_addr, remote_addr));
3182385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3192385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3202385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdochvoid PepperTCPServerSocketMessageFilter::SendAcceptError(
3212385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    const ppapi::host::ReplyMessageContext& context,
3222385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch    int32_t pp_result) {
3232385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  SendAcceptReply(context,
3242385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                  pp_result,
3252385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                  0,
3262385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                  NetAddressPrivateImpl::kInvalidNetAddress,
3272385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch                  NetAddressPrivateImpl::kInvalidNetAddress);
3282385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}
3292385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch
3302385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch}  // namespace content
331