Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ppapi/proxy/ppb_tcp_socket_private_proxy.h"
      6 
      7 #include <map>
      8 
      9 #include "base/logging.h"
     10 #include "ppapi/proxy/plugin_dispatcher.h"
     11 #include "ppapi/proxy/plugin_globals.h"
     12 #include "ppapi/proxy/plugin_resource_tracker.h"
     13 #include "ppapi/proxy/ppapi_messages.h"
     14 #include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
     15 #include "ppapi/shared_impl/private/tcp_socket_private_impl.h"
     16 #include "ppapi/shared_impl/resource.h"
     17 #include "ppapi/shared_impl/socket_option_data.h"
     18 #include "ppapi/thunk/thunk.h"
     19 
     20 namespace ppapi {
     21 namespace proxy {
     22 
     23 namespace {
     24 
     25 typedef std::map<uint32, TCPSocketPrivateImpl*> IDToSocketMap;
     26 IDToSocketMap* g_id_to_socket = NULL;
     27 
     28 class TCPSocket : public TCPSocketPrivateImpl {
     29  public:
     30   // C-tor for new sockets.
     31   TCPSocket(const HostResource& resource, uint32 socket_id);
     32   // C-tor for already connected sockets.
     33   TCPSocket(const HostResource& resource,
     34             uint32 socket_id,
     35             const PP_NetAddress_Private& local_addr,
     36             const PP_NetAddress_Private& remote_addr);
     37   virtual ~TCPSocket();
     38 
     39   virtual void SendConnect(const std::string& host, uint16_t port) OVERRIDE;
     40   virtual void SendConnectWithNetAddress(
     41       const PP_NetAddress_Private& addr) OVERRIDE;
     42   virtual void SendSSLHandshake(
     43       const std::string& server_name,
     44       uint16_t server_port,
     45       const std::vector<std::vector<char> >& trusted_certs,
     46       const std::vector<std::vector<char> >& untrusted_certs) OVERRIDE;
     47   virtual void SendRead(int32_t bytes_to_read) OVERRIDE;
     48   virtual void SendWrite(const std::string& buffer) OVERRIDE;
     49   virtual void SendDisconnect() OVERRIDE;
     50   virtual void SendSetOption(PP_TCPSocket_Option name,
     51                              const SocketOptionData& value) OVERRIDE;
     52 
     53  private:
     54   void SendToBrowser(IPC::Message* msg);
     55 
     56   DISALLOW_COPY_AND_ASSIGN(TCPSocket);
     57 };
     58 
     59 TCPSocket::TCPSocket(const HostResource& resource, uint32 socket_id)
     60     : TCPSocketPrivateImpl(resource, socket_id) {
     61   if (!g_id_to_socket)
     62     g_id_to_socket = new IDToSocketMap();
     63   DCHECK(g_id_to_socket->find(socket_id) == g_id_to_socket->end());
     64   (*g_id_to_socket)[socket_id] = this;
     65 }
     66 
     67 TCPSocket::TCPSocket(const HostResource& resource,
     68                      uint32 socket_id,
     69                      const PP_NetAddress_Private& local_addr,
     70                      const PP_NetAddress_Private& remote_addr)
     71     : TCPSocketPrivateImpl(resource, socket_id) {
     72   if (!g_id_to_socket)
     73     g_id_to_socket = new IDToSocketMap();
     74   DCHECK(g_id_to_socket->find(socket_id) == g_id_to_socket->end());
     75 
     76   connection_state_ = CONNECTED;
     77   local_addr_ = local_addr;
     78   remote_addr_ = remote_addr;
     79 
     80   (*g_id_to_socket)[socket_id] = this;
     81 }
     82 
     83 TCPSocket::~TCPSocket() {
     84   Disconnect();
     85 }
     86 
     87 void TCPSocket::SendConnect(const std::string& host, uint16_t port) {
     88   SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Connect(
     89       API_ID_PPB_TCPSOCKET_PRIVATE, socket_id_, host, port));
     90 }
     91 
     92 void TCPSocket::SendConnectWithNetAddress(const PP_NetAddress_Private& addr) {
     93   SendToBrowser(new PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress(
     94       API_ID_PPB_TCPSOCKET_PRIVATE, socket_id_, addr));
     95 }
     96 
     97 void TCPSocket::SendSSLHandshake(
     98     const std::string& server_name,
     99     uint16_t server_port,
    100     const std::vector<std::vector<char> >& trusted_certs,
    101     const std::vector<std::vector<char> >& untrusted_certs) {
    102   SendToBrowser(new PpapiHostMsg_PPBTCPSocket_SSLHandshake(
    103       socket_id_, server_name, server_port, trusted_certs, untrusted_certs));
    104 }
    105 
    106 void TCPSocket::SendRead(int32_t bytes_to_read) {
    107   SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Read(socket_id_, bytes_to_read));
    108 }
    109 
    110 void TCPSocket::SendWrite(const std::string& buffer) {
    111   SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Write(socket_id_, buffer));
    112 }
    113 
    114 void TCPSocket::SendDisconnect() {
    115   // After removed from the mapping, this object won't receive any notifications
    116   // from the proxy.
    117   DCHECK(g_id_to_socket->find(socket_id_) != g_id_to_socket->end());
    118   g_id_to_socket->erase(socket_id_);
    119   SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Disconnect(socket_id_));
    120 }
    121 
    122 void TCPSocket::SendSetOption(PP_TCPSocket_Option name,
    123                               const SocketOptionData& value) {
    124   SendToBrowser(
    125       new PpapiHostMsg_PPBTCPSocket_SetOption(socket_id_, name, value));
    126 }
    127 
    128 void TCPSocket::SendToBrowser(IPC::Message* msg) {
    129   PluginGlobals::Get()->GetBrowserSender()->Send(msg);
    130 }
    131 
    132 }  // namespace
    133 
    134 //------------------------------------------------------------------------------
    135 
    136 PPB_TCPSocket_Private_Proxy::PPB_TCPSocket_Private_Proxy(Dispatcher* dispatcher)
    137     : InterfaceProxy(dispatcher) {
    138 }
    139 
    140 PPB_TCPSocket_Private_Proxy::~PPB_TCPSocket_Private_Proxy() {
    141 }
    142 
    143 // static
    144 PP_Resource PPB_TCPSocket_Private_Proxy::CreateProxyResource(
    145     PP_Instance instance) {
    146   PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
    147   if (!dispatcher)
    148     return 0;
    149 
    150   uint32 socket_id = 0;
    151   PluginGlobals::Get()->GetBrowserSender()->Send(
    152       new PpapiHostMsg_PPBTCPSocket_CreatePrivate(
    153           API_ID_PPB_TCPSOCKET_PRIVATE, dispatcher->plugin_dispatcher_id(),
    154           &socket_id));
    155   if (socket_id == 0)
    156     return 0;
    157   return (new TCPSocket(HostResource::MakeInstanceOnly(instance),
    158                         socket_id))->GetReference();
    159 }
    160 
    161 // static
    162 PP_Resource PPB_TCPSocket_Private_Proxy::CreateProxyResourceForConnectedSocket(
    163     PP_Instance instance,
    164     uint32 socket_id,
    165     const PP_NetAddress_Private& local_addr,
    166     const PP_NetAddress_Private& remote_addr) {
    167   return (new TCPSocket(HostResource::MakeInstanceOnly(instance),
    168                         socket_id,
    169                         local_addr,
    170                         remote_addr))->GetReference();
    171 }
    172 
    173 bool PPB_TCPSocket_Private_Proxy::OnMessageReceived(const IPC::Message& msg) {
    174   bool handled = true;
    175   IPC_BEGIN_MESSAGE_MAP(PPB_TCPSocket_Private_Proxy, msg)
    176     IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ConnectACK,
    177                         OnMsgConnectACK)
    178     IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SSLHandshakeACK,
    179                         OnMsgSSLHandshakeACK)
    180     IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ReadACK, OnMsgReadACK)
    181     IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_WriteACK, OnMsgWriteACK)
    182     IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetOptionACK, OnMsgSetOptionACK)
    183     IPC_MESSAGE_UNHANDLED(handled = false)
    184   IPC_END_MESSAGE_MAP()
    185   return handled;
    186 }
    187 
    188 void PPB_TCPSocket_Private_Proxy::OnMsgConnectACK(
    189     uint32 /* plugin_dispatcher_id */,
    190     uint32 socket_id,
    191     int32_t result,
    192     const PP_NetAddress_Private& local_addr,
    193     const PP_NetAddress_Private& remote_addr) {
    194   if (!g_id_to_socket) {
    195     NOTREACHED();
    196     return;
    197   }
    198   IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
    199   if (iter == g_id_to_socket->end())
    200     return;
    201   iter->second->OnConnectCompleted(result, local_addr, remote_addr);
    202 }
    203 
    204 void PPB_TCPSocket_Private_Proxy::OnMsgSSLHandshakeACK(
    205     uint32 /* plugin_dispatcher_id */,
    206     uint32 socket_id,
    207     bool succeeded,
    208     const PPB_X509Certificate_Fields& certificate_fields) {
    209   if (!g_id_to_socket) {
    210     NOTREACHED();
    211     return;
    212   }
    213   IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
    214   if (iter == g_id_to_socket->end())
    215     return;
    216   iter->second->OnSSLHandshakeCompleted(succeeded, certificate_fields);
    217 }
    218 
    219 void PPB_TCPSocket_Private_Proxy::OnMsgReadACK(
    220     uint32 /* plugin_dispatcher_id */,
    221     uint32 socket_id,
    222     int32_t result,
    223     const std::string& data) {
    224   if (!g_id_to_socket) {
    225     NOTREACHED();
    226     return;
    227   }
    228   IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
    229   if (iter == g_id_to_socket->end())
    230     return;
    231   iter->second->OnReadCompleted(result, data);
    232 }
    233 
    234 void PPB_TCPSocket_Private_Proxy::OnMsgWriteACK(
    235     uint32 /* plugin_dispatcher_id */,
    236     uint32 socket_id,
    237     int32_t result) {
    238   if (!g_id_to_socket) {
    239     NOTREACHED();
    240     return;
    241   }
    242   IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
    243   if (iter == g_id_to_socket->end())
    244     return;
    245   iter->second->OnWriteCompleted(result);
    246 }
    247 
    248 void PPB_TCPSocket_Private_Proxy::OnMsgSetOptionACK(
    249     uint32 /* plugin_dispatcher_id */,
    250     uint32 socket_id,
    251     int32_t result) {
    252   if (!g_id_to_socket) {
    253     NOTREACHED();
    254     return;
    255   }
    256   IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
    257   if (iter == g_id_to_socket->end())
    258     return;
    259   iter->second->OnSetOptionCompleted(result);
    260 }
    261 
    262 }  // namespace proxy
    263 }  // namespace ppapi
    264