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

Side by Side Diff: content/browser/renderer_host/pepper/pepper_udp_socket_private_host.cc

Issue 11441012: PPB_UDPSocket_Private is switched to the new Pepper proxy. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync. Created 7 years, 11 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 "content/browser/renderer_host/pepper/pepper_udp_socket_private_host.h"
6
7 #include <cstring>
8 #include <limits>
9
10 #include "base/compiler_specific.h"
11 #include "base/logging.h"
12 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
13 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/common/process_type.h"
16 #include "content/public/common/socket_permission_request.h"
17 #include "ipc/ipc_message_macros.h"
18 #include "net/base/io_buffer.h"
19 #include "net/base/net_errors.h"
20 #include "net/udp/udp_server_socket.h"
21 #include "ppapi/c/pp_errors.h"
22 #include "ppapi/c/private/ppb_net_address_private.h"
23 #include "ppapi/c/private/ppb_udp_socket_private.h"
24 #include "ppapi/host/dispatch_host_message.h"
25 #include "ppapi/host/host_message_context.h"
26 #include "ppapi/host/ppapi_host.h"
27 #include "ppapi/proxy/ppapi_messages.h"
28 #include "ppapi/proxy/udp_socket_private_resource.h"
29 #include "ppapi/shared_impl/private/net_address_private_impl.h"
30
31 using ppapi::NetAddressPrivateImpl;
32
33 namespace content {
34
35 PepperUDPSocketPrivateHost::PepperUDPSocketPrivateHost(
36 BrowserPpapiHostImpl* host,
37 PP_Instance instance,
38 PP_Resource resource)
39 : ResourceHost(host->GetPpapiHost(), instance, resource),
40 allow_address_reuse_(false),
41 allow_broadcast_(false),
42 closed_(false),
43 host_(host),
44 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
45 DCHECK(host_);
46 }
47
48 PepperUDPSocketPrivateHost::~PepperUDPSocketPrivateHost() {
49 Close();
50 }
51
52 int32_t PepperUDPSocketPrivateHost::OnResourceMessageReceived(
53 const IPC::Message& msg,
54 ppapi::host::HostMessageContext* context) {
55 IPC_BEGIN_MESSAGE_MAP(PepperUDPSocketPrivateHost, msg)
56 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
57 PpapiHostMsg_UDPSocketPrivate_SetBoolSocketFeature,
58 OnMsgSetBoolSocketFeature)
59 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
60 PpapiHostMsg_UDPSocketPrivate_Bind,
61 OnMsgBind)
62 PPAPI_DISPATCH_HOST_RESOURCE_CALL(
63 PpapiHostMsg_UDPSocketPrivate_RecvFrom,
64 OnMsgRecvFrom)
65 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocketPrivate_SendTo,
66 OnMsgSendTo)
67 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(
68 PpapiHostMsg_UDPSocketPrivate_Close,
69 OnMsgClose)
70 IPC_END_MESSAGE_MAP()
71 return PP_ERROR_FAILED;
72 }
73
74 int32_t PepperUDPSocketPrivateHost::OnMsgSetBoolSocketFeature(
75 const ppapi::host::HostMessageContext* context,
76 int32_t name,
77 bool value) {
78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
79 DCHECK(!socket_.get());
80 DCHECK(!closed());
81
82 switch(static_cast<PP_UDPSocketFeature_Private>(name)) {
83 case PP_UDPSOCKETFEATURE_ADDRESS_REUSE:
84 allow_address_reuse_ = value;
85 break;
86 case PP_UDPSOCKETFEATURE_BROADCAST:
87 allow_broadcast_ = value;
88 break;
89 default:
90 NOTREACHED();
91 break;
92 }
93 return PP_OK;
94 }
95
96 int32_t PepperUDPSocketPrivateHost::OnMsgBind(
97 const ppapi::host::HostMessageContext* context,
98 const PP_NetAddress_Private& addr) {
99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
100 DCHECK(context);
101
102 if (bind_context_.get())
103 return PP_ERROR_INPROGRESS;
104 bind_context_.reset(
105 new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
106
107 SocketPermissionRequest params =
108 pepper_socket_utils::CreateSocketPermissionRequest(
109 SocketPermissionRequest::UDP_BIND, addr);
110 CheckSocketPermissionsAndReply(params,
111 base::Bind(&PepperUDPSocketPrivateHost::DoBind,
112 weak_factory_.GetWeakPtr(),
113 addr));
114 return PP_OK_COMPLETIONPENDING;
115 }
116
117 int32_t PepperUDPSocketPrivateHost::OnMsgRecvFrom(
118 const ppapi::host::HostMessageContext* context,
119 int32_t num_bytes) {
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
121 DCHECK(context);
122 DCHECK(socket_.get());
123 DCHECK(!closed());
124
125 if (recv_from_context_.get() || recvfrom_buffer_.get())
126 return PP_ERROR_INPROGRESS;
127 recv_from_context_.reset(
128 new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
129 if (num_bytes > ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize) {
130 // |num_bytes| value is checked on the plugin side.
131 NOTREACHED();
132 num_bytes = ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize;
133 }
134 recvfrom_buffer_ = new net::IOBuffer(num_bytes);
135 int result = socket_->RecvFrom(
136 recvfrom_buffer_, num_bytes, &recvfrom_address_,
137 base::Bind(&PepperUDPSocketPrivateHost::OnRecvFromCompleted,
138 weak_factory_.GetWeakPtr()));
139 if (result != net::ERR_IO_PENDING)
140 OnRecvFromCompleted(result);
141 return PP_OK_COMPLETIONPENDING;
142 }
143
144 int32_t PepperUDPSocketPrivateHost::OnMsgSendTo(
145 const ppapi::host::HostMessageContext* context,
146 const std::string& data,
147 const PP_NetAddress_Private& addr) {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
149 DCHECK(context);
150
151 if (data.empty() ||
152 data.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
153 return PP_ERROR_BADARGUMENT;
154 }
155 if (send_to_context_.get() || sendto_buffer_.get())
156 return PP_ERROR_INPROGRESS;
157 send_to_context_.reset(
158 new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
159 int num_bytes = data.size();
160 if (num_bytes > ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize) {
161 // Size of |data| is checked on the plugin side.
162 NOTREACHED();
163 num_bytes = ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize;
164 }
165 sendto_buffer_ = new net::IOBufferWithSize(num_bytes);
166 memcpy(sendto_buffer_->data(), data.data(), num_bytes);
167 SocketPermissionRequest params =
168 pepper_socket_utils::CreateSocketPermissionRequest(
169 SocketPermissionRequest::UDP_SEND_TO, addr);
170 CheckSocketPermissionsAndReply(params,
171 base::Bind(
172 &PepperUDPSocketPrivateHost::DoSendTo,
173 weak_factory_.GetWeakPtr(),
174 addr));
175 return PP_OK_COMPLETIONPENDING;
176 }
177
178 int32_t PepperUDPSocketPrivateHost::OnMsgClose(
179 const ppapi::host::HostMessageContext* context) {
180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
181 Close();
182 return PP_OK;
183 }
184
185 void PepperUDPSocketPrivateHost::DoBind(const PP_NetAddress_Private& addr,
186 bool allowed) {
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
188 DCHECK(!closed());
189
190 if (!allowed) {
191 SendBindError();
192 return;
193 }
194
195 socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source()));
196
197 net::IPAddressNumber address;
198 int port;
199 if (!socket_.get() ||
200 !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
201 SendBindError();
202 return;
203 }
204
205 if (allow_address_reuse_)
206 socket_->AllowAddressReuse();
207 if (allow_broadcast_)
208 socket_->AllowBroadcast();
209
210 int result = socket_->Listen(net::IPEndPoint(address, port));
211
212 if (result == net::OK &&
213 socket_->GetLocalAddress(&bound_address_) != net::OK) {
214 SendBindError();
215 return;
216 }
217
218 OnBindCompleted(result);
219 }
220
221 void PepperUDPSocketPrivateHost::DoSendTo(const PP_NetAddress_Private& addr,
222 bool allowed) {
223 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
224 DCHECK(socket_.get());
225 DCHECK(sendto_buffer_.get());
226 DCHECK(!closed());
227
228 if (!allowed) {
229 SendSendToError();
230 return;
231 }
232
233 net::IPAddressNumber address;
234 int port;
235 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
236 SendSendToError();
237 return;
238 }
239
240 int result = socket_->SendTo(
241 sendto_buffer_, sendto_buffer_->size(), net::IPEndPoint(address, port),
242 base::Bind(&PepperUDPSocketPrivateHost::OnSendToCompleted,
243 weak_factory_.GetWeakPtr()));
244
245 if (result != net::ERR_IO_PENDING)
246 OnSendToCompleted(result);
247 }
248
249 void PepperUDPSocketPrivateHost::Close() {
250 if (socket_.get() && !closed_)
251 socket_->Close();
252 closed_ = true;
253 }
254
255 void PepperUDPSocketPrivateHost::OnBindCompleted(int result) {
256 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress;
257 if (result < 0 ||
258 !NetAddressPrivateImpl::IPEndPointToNetAddress(bound_address_.address(),
259 bound_address_.port(),
260 &addr)) {
261 SendBindError();
262 } else {
263 SendBindReply(true, addr);
264 }
265 }
266
267 void PepperUDPSocketPrivateHost::OnRecvFromCompleted(int result) {
268 DCHECK(recvfrom_buffer_.get());
269
270 // Convert IPEndPoint we get back from RecvFrom to a PP_NetAddress_Private,
271 // to send back.
272 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress;
273 if (result < 0 ||
274 !NetAddressPrivateImpl::IPEndPointToNetAddress(
275 recvfrom_address_.address(),
276 recvfrom_address_.port(),
277 &addr)) {
278 SendRecvFromError();
279 } else {
280 SendRecvFromReply(true,
281 std::string(recvfrom_buffer_->data(), result),
282 addr);
283 }
284
285 recvfrom_buffer_ = NULL;
286 }
287
288 void PepperUDPSocketPrivateHost::OnSendToCompleted(int result) {
289 DCHECK(sendto_buffer_.get());
290 if (result < 0)
291 SendSendToError();
292 else
293 SendSendToReply(true, result);
294 sendto_buffer_ = NULL;
295 }
296
297 void PepperUDPSocketPrivateHost::SendBindReply(
298 bool succeeded,
299 const PP_NetAddress_Private& addr) {
300 DCHECK(bind_context_.get());
301
302 scoped_ptr<ppapi::host::ReplyMessageContext> context(bind_context_.release());
303 host()->SendReply(*context,
304 PpapiPluginMsg_UDPSocketPrivate_BindReply(succeeded, addr));
305 }
306
307 void PepperUDPSocketPrivateHost::SendRecvFromReply(
308 bool succeeded,
309 const std::string& data,
310 const PP_NetAddress_Private& addr) {
311 DCHECK(recv_from_context_.get());
312
313 scoped_ptr<ppapi::host::ReplyMessageContext> context(
314 recv_from_context_.release());
315 host()->SendReply(*context,
316 PpapiPluginMsg_UDPSocketPrivate_RecvFromReply(succeeded,
317 data,
318 addr));
319 }
320
321 void PepperUDPSocketPrivateHost::SendSendToReply(bool succeeded,
322 int32_t bytes_written) {
323 DCHECK(send_to_context_.get());
324
325 scoped_ptr<ppapi::host::ReplyMessageContext> context(
326 send_to_context_.release());
327 host()->SendReply(*context,
328 PpapiPluginMsg_UDPSocketPrivate_SendToReply(succeeded,
329 bytes_written));
330 }
331
332 void PepperUDPSocketPrivateHost::CheckSocketPermissionsAndReply(
333 const SocketPermissionRequest& params,
334 const RequestCallback& callback) {
335 pepper_socket_utils::PostOnUIThreadWithRenderViewHostAndReply(
336 host_, FROM_HERE, pp_instance(),
337 base::Bind(&pepper_socket_utils::CanUseSocketAPIs,
338 host_->plugin_process_type(), params),
339 callback);
340 }
341
342 void PepperUDPSocketPrivateHost::SendBindError() {
343 SendBindReply(false, NetAddressPrivateImpl::kInvalidNetAddress);
344 }
345
346 void PepperUDPSocketPrivateHost::SendRecvFromError() {
347 SendRecvFromReply(false, "", NetAddressPrivateImpl::kInvalidNetAddress);
348 }
349
350 void PepperUDPSocketPrivateHost::SendSendToError() {
351 SendSendToReply(false, 0);
352 }
353
354 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698