OLD | NEW |
| (Empty) |
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 | |
OLD | NEW |