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

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: Added data size check. 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 NOTREACHED();
131 num_bytes = ppapi::proxy::UDPSocketPrivateResource::kMaxReadSize;
132 }
133 recvfrom_buffer_ = new net::IOBuffer(num_bytes);
134 int result = socket_->RecvFrom(
135 recvfrom_buffer_, num_bytes, &recvfrom_address_,
136 base::Bind(&PepperUDPSocketPrivateHost::OnRecvFromCompleted,
137 weak_factory_.GetWeakPtr()));
138 if (result != net::ERR_IO_PENDING)
139 OnRecvFromCompleted(result);
140 return PP_OK_COMPLETIONPENDING;
141 }
142
143 int32_t PepperUDPSocketPrivateHost::OnMsgSendTo(
144 const ppapi::host::HostMessageContext* context,
145 const std::string& data,
146 const PP_NetAddress_Private& addr) {
147 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
148 DCHECK(context);
149
150 if (data.empty() ||
151 data.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
152 return PP_ERROR_BADARGUMENT;
153 }
154 if (send_to_context_.get() || sendto_buffer_.get())
155 return PP_ERROR_INPROGRESS;
156 send_to_context_.reset(
157 new ppapi::host::ReplyMessageContext(context->MakeReplyMessageContext()));
158 int num_bytes = data.size();
159 if (num_bytes > ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize) {
160 NOTREACHED();
dmichael (off chromium) 2013/01/10 17:30:47 A comment that this was checked in the plugin side
ygorshenin1 2013/01/11 11:42:45 Done.
161 num_bytes = ppapi::proxy::UDPSocketPrivateResource::kMaxWriteSize;
162 }
163 sendto_buffer_ = new net::IOBufferWithSize(num_bytes);
164 memcpy(sendto_buffer_->data(), data.data(), num_bytes);
165 SocketPermissionRequest params =
166 pepper_socket_utils::CreateSocketPermissionRequest(
167 SocketPermissionRequest::UDP_SEND_TO, addr);
168 CheckSocketPermissionsAndReply(params,
169 base::Bind(
170 &PepperUDPSocketPrivateHost::DoSendTo,
171 weak_factory_.GetWeakPtr(),
172 addr));
173 return PP_OK_COMPLETIONPENDING;
174 }
175
176 int32_t PepperUDPSocketPrivateHost::OnMsgClose(
177 const ppapi::host::HostMessageContext* context) {
178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
179 Close();
180 return PP_OK;
181 }
182
183 void PepperUDPSocketPrivateHost::DoBind(const PP_NetAddress_Private& addr,
184 bool allowed) {
185 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
186 DCHECK(!closed());
187
188 if (!allowed) {
189 SendBindError();
190 return;
191 }
192
193 socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source()));
194
195 net::IPAddressNumber address;
196 int port;
197 if (!socket_.get() ||
198 !NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
199 SendBindError();
200 return;
201 }
202
203 if (allow_address_reuse_)
204 socket_->AllowAddressReuse();
205 if (allow_broadcast_)
206 socket_->AllowBroadcast();
207
208 int result = socket_->Listen(net::IPEndPoint(address, port));
209
210 if (result == net::OK &&
211 socket_->GetLocalAddress(&bound_address_) != net::OK) {
212 SendBindError();
213 return;
214 }
215
216 OnBindCompleted(result);
217 }
218
219 void PepperUDPSocketPrivateHost::DoSendTo(const PP_NetAddress_Private& addr,
220 bool allowed) {
221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
222 DCHECK(socket_.get());
223 DCHECK(sendto_buffer_.get());
224 DCHECK(!closed());
225
226 if (!allowed) {
227 SendSendToError();
228 return;
229 }
230
231 net::IPAddressNumber address;
232 int port;
233 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
234 SendSendToError();
235 return;
236 }
237
238 int result = socket_->SendTo(
239 sendto_buffer_, sendto_buffer_->size(), net::IPEndPoint(address, port),
240 base::Bind(&PepperUDPSocketPrivateHost::OnSendToCompleted,
241 weak_factory_.GetWeakPtr()));
242
243 if (result != net::ERR_IO_PENDING)
244 OnSendToCompleted(result);
245 }
246
247 void PepperUDPSocketPrivateHost::Close() {
248 if (socket_.get() && !closed_)
249 socket_->Close();
250 closed_ = true;
251 }
252
253 void PepperUDPSocketPrivateHost::OnBindCompleted(int result) {
254 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress;
255 if (result < 0 ||
256 !NetAddressPrivateImpl::IPEndPointToNetAddress(bound_address_.address(),
257 bound_address_.port(),
258 &addr)) {
259 SendBindError();
260 } else {
261 SendBindReply(true, addr);
262 }
263 }
264
265 void PepperUDPSocketPrivateHost::OnRecvFromCompleted(int result) {
266 DCHECK(recvfrom_buffer_.get());
267
268 // Convert IPEndPoint we get back from RecvFrom to a PP_NetAddress_Private,
269 // to send back.
270 PP_NetAddress_Private addr = NetAddressPrivateImpl::kInvalidNetAddress;
271 if (result < 0 ||
272 !NetAddressPrivateImpl::IPEndPointToNetAddress(
273 recvfrom_address_.address(),
274 recvfrom_address_.port(),
275 &addr)) {
276 SendRecvFromError();
277 } else {
278 SendRecvFromReply(true,
279 std::string(recvfrom_buffer_->data(), result),
280 addr);
281 }
282
283 recvfrom_buffer_ = NULL;
284 }
285
286 void PepperUDPSocketPrivateHost::OnSendToCompleted(int result) {
287 DCHECK(sendto_buffer_.get());
288 if (result < 0)
289 SendSendToError();
290 else
291 SendSendToReply(true, result);
292 sendto_buffer_ = NULL;
293 }
294
295 void PepperUDPSocketPrivateHost::SendBindReply(
296 bool succeeded,
297 const PP_NetAddress_Private& addr) {
298 DCHECK(bind_context_.get());
299
300 scoped_ptr<ppapi::host::ReplyMessageContext> context(bind_context_.release());
301 host()->SendReply(*context,
302 PpapiPluginMsg_UDPSocketPrivate_BindReply(succeeded, addr));
303 }
304
305 void PepperUDPSocketPrivateHost::SendRecvFromReply(
306 bool succeeded,
307 const std::string& data,
308 const PP_NetAddress_Private& addr) {
309 DCHECK(recv_from_context_.get());
310
311 scoped_ptr<ppapi::host::ReplyMessageContext> context(
312 recv_from_context_.release());
313 host()->SendReply(*context,
314 PpapiPluginMsg_UDPSocketPrivate_RecvFromReply(succeeded,
315 data,
316 addr));
317 }
318
319 void PepperUDPSocketPrivateHost::SendSendToReply(bool succeeded,
320 int32_t bytes_written) {
321 DCHECK(send_to_context_.get());
322
323 scoped_ptr<ppapi::host::ReplyMessageContext> context(
324 send_to_context_.release());
325 host()->SendReply(*context,
326 PpapiPluginMsg_UDPSocketPrivate_SendToReply(succeeded,
327 bytes_written));
328 }
329
330 void PepperUDPSocketPrivateHost::CheckSocketPermissionsAndReply(
331 const SocketPermissionRequest& params,
332 const RequestCallback& callback) {
333 host_->PostOnUIThreadWithRenderViewHostAndReply(
334 FROM_HERE,
335 pp_instance(),
336 base::Bind(&pepper_socket_utils::CanUseSocketAPIs,
337 host_->plugin_process_type(), params),
338 callback);
339 }
340
341 void PepperUDPSocketPrivateHost::SendBindError() {
342 SendBindReply(false, NetAddressPrivateImpl::kInvalidNetAddress);
343 }
344
345 void PepperUDPSocketPrivateHost::SendRecvFromError() {
346 SendRecvFromReply(false, "", NetAddressPrivateImpl::kInvalidNetAddress);
347 }
348
349 void PepperUDPSocketPrivateHost::SendSendToError() {
350 SendSendToReply(false, 0);
351 }
352
353 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698