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

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

Issue 690903002: Remove timing limitation of SetOption invocation for PPAPI sockets. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase and fixed implementation. Created 6 years 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter. h" 5 #include "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter. h"
6 6
7 #include <cstring> 7 #include <cstring>
8 8
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" 11 #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
12 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" 12 #include "content/browser/renderer_host/pepper/pepper_socket_utils.h"
13 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
14 #include "content/public/common/process_type.h" 14 #include "content/public/common/process_type.h"
15 #include "content/public/common/socket_permission_request.h" 15 #include "content/public/common/socket_permission_request.h"
16 #include "ipc/ipc_message_macros.h" 16 #include "ipc/ipc_message_macros.h"
17 #include "net/base/io_buffer.h" 17 #include "net/base/io_buffer.h"
18 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 #include "net/udp/udp_server_socket.h" 19 #include "net/base/rand_callback.h"
20 #include "net/udp/udp_socket.h"
20 #include "ppapi/c/pp_errors.h" 21 #include "ppapi/c/pp_errors.h"
21 #include "ppapi/c/private/ppb_net_address_private.h" 22 #include "ppapi/c/private/ppb_net_address_private.h"
22 #include "ppapi/host/dispatch_host_message.h" 23 #include "ppapi/host/dispatch_host_message.h"
23 #include "ppapi/host/error_conversion.h" 24 #include "ppapi/host/error_conversion.h"
24 #include "ppapi/host/host_message_context.h" 25 #include "ppapi/host/host_message_context.h"
25 #include "ppapi/host/ppapi_host.h" 26 #include "ppapi/host/ppapi_host.h"
26 #include "ppapi/host/resource_host.h" 27 #include "ppapi/host/resource_host.h"
27 #include "ppapi/proxy/ppapi_messages.h" 28 #include "ppapi/proxy/ppapi_messages.h"
28 #include "ppapi/proxy/udp_socket_resource_base.h" 29 #include "ppapi/proxy/udp_socket_resource_base.h"
29 #include "ppapi/shared_impl/private/net_address_private_impl.h" 30 #include "ppapi/shared_impl/private/net_address_private_impl.h"
30 #include "ppapi/shared_impl/socket_option_data.h" 31 #include "ppapi/shared_impl/socket_option_data.h"
31 32
32 using ppapi::NetAddressPrivateImpl; 33 using ppapi::NetAddressPrivateImpl;
33 using ppapi::host::NetErrorToPepperError; 34 using ppapi::host::NetErrorToPepperError;
34 35
35 namespace { 36 namespace {
36 37
37 size_t g_num_instances = 0; 38 size_t g_num_instances = 0;
38 39
39 } // namespace 40 } // namespace
40 41
41 namespace content { 42 namespace content {
42 43
43 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter( 44 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter(
44 BrowserPpapiHostImpl* host, 45 BrowserPpapiHostImpl* host,
45 PP_Instance instance, 46 PP_Instance instance,
46 bool private_api) 47 bool private_api)
47 : allow_address_reuse_(false), 48 : socket_options_(0),
bbudge 2014/12/09 18:37:37 Even though not strictly necessary in this case, w
hidehiko 2014/12/09 19:51:42 Done.
48 allow_broadcast_(false),
49 closed_(false), 49 closed_(false),
50 remaining_recv_slots_( 50 remaining_recv_slots_(
51 ppapi::proxy::UDPSocketResourceBase::kPluginReceiveBufferSlots), 51 ppapi::proxy::UDPSocketResourceBase::kPluginReceiveBufferSlots),
52 external_plugin_(host->external_plugin()), 52 external_plugin_(host->external_plugin()),
53 private_api_(private_api), 53 private_api_(private_api),
54 render_process_id_(0), 54 render_process_id_(0),
55 render_frame_id_(0) { 55 render_frame_id_(0) {
56 ++g_num_instances; 56 ++g_num_instances;
57 DCHECK(host); 57 DCHECK(host);
58 58
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( 107 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption(
108 const ppapi::host::HostMessageContext* context, 108 const ppapi::host::HostMessageContext* context,
109 PP_UDPSocket_Option name, 109 PP_UDPSocket_Option name,
110 const ppapi::SocketOptionData& value) { 110 const ppapi::SocketOptionData& value) {
111 DCHECK_CURRENTLY_ON(BrowserThread::IO); 111 DCHECK_CURRENTLY_ON(BrowserThread::IO);
112 112
113 if (closed_) 113 if (closed_)
114 return PP_ERROR_FAILED; 114 return PP_ERROR_FAILED;
115 115
116 switch (name) { 116 switch (name) {
117 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: 117 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: {
118 case PP_UDPSOCKET_OPTION_BROADCAST: {
119 if (socket_.get()) { 118 if (socket_.get()) {
120 // They only take effect before the socket is bound. 119 // AllowReuseAddress is only effective before Bind().
120 // Note that this limitation originally comes from the Windows, but
121 // PPAPI tries to provide a platform independent APIs.
bbudge 2014/12/09 18:37:37 s/the Windows/Windows s/a platform/platform
hidehiko 2014/12/09 19:51:42 Done.
121 return PP_ERROR_FAILED; 122 return PP_ERROR_FAILED;
122 } 123 }
123 124
124 bool boolean_value = false; 125 bool boolean_value = false;
125 if (!value.GetBool(&boolean_value)) 126 if (!value.GetBool(&boolean_value))
126 return PP_ERROR_BADARGUMENT; 127 return PP_ERROR_BADARGUMENT;
127 128
128 if (name == PP_UDPSOCKET_OPTION_ADDRESS_REUSE) 129 if (boolean_value) {
129 allow_address_reuse_ = boolean_value; 130 socket_options_ |= SOCKET_OPTION_ADDRESS_REUSE;
130 else 131 } else {
131 allow_broadcast_ = boolean_value; 132 socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE;
133 }
132 return PP_OK; 134 return PP_OK;
133 } 135 }
134 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: 136 case PP_UDPSOCKET_OPTION_BROADCAST: {
135 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: { 137 bool boolean_value = false;
136 if (!socket_.get()) { 138 if (!value.GetBool(&boolean_value))
137 // They only take effect after the socket is bound.
138 return PP_ERROR_FAILED;
139 }
140 int32_t integer_value = 0;
141 if (!value.GetInt32(&integer_value) || integer_value <= 0)
142 return PP_ERROR_BADARGUMENT; 139 return PP_ERROR_BADARGUMENT;
143 140
144 int net_result = net::ERR_UNEXPECTED; 141 // If the socket is already connected, proxy the value to TCPSocket.
145 if (name == PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE) { 142 if (socket_.get())
146 if (integer_value > 143 return NetErrorToPepperError(socket_->SetBroadcast(boolean_value));
147 ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize) { 144
148 return PP_ERROR_BADARGUMENT; 145 // UDPSocket instance is not yet created. So remember the value here.
bbudge 2014/12/09 18:37:37 nit: s/. So/, so
hidehiko 2014/12/09 19:51:42 Done.
149 } 146 if (boolean_value) {
150 net_result = socket_->SetSendBufferSize(integer_value); 147 socket_options_ |= SOCKET_OPTION_BROADCAST;
151 } else { 148 } else {
152 if (integer_value > 149 socket_options_ &= ~SOCKET_OPTION_BROADCAST;
153 ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize) {
154 return PP_ERROR_BADARGUMENT;
155 }
156 net_result = socket_->SetReceiveBufferSize(integer_value);
157 } 150 }
158 // TODO(wtc): Add error mapping code. 151 return PP_OK;
159 return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED; 152 }
153 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: {
154 int32_t integer_value = 0;
155 if (!value.GetInt32(&integer_value) ||
156 integer_value <= 0 ||
157 integer_value >
158 ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize)
159 return PP_ERROR_BADARGUMENT;
160
161 // If the socket is already connected, proxy the value to UDPSocket.
162 if (socket_.get()) {
163 return NetErrorToPepperError(
164 socket_->SetSendBufferSize(integer_value));
165 }
166
167 // UDPSocket instance is not yet created. So remember the value here.
bbudge 2014/12/09 18:37:37 nit: s/. So/, so
hidehiko 2014/12/09 19:51:42 Done.
168 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE;
169 sndbuf_size_ = integer_value;
170 return PP_OK;
171 }
172 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: {
173 int32_t integer_value = 0;
174 if (!value.GetInt32(&integer_value) ||
175 integer_value <= 0 ||
176 integer_value >
177 ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize)
178 return PP_ERROR_BADARGUMENT;
179
180 // If the socket is already connected, proxy the value to UDPSocket.
181 if (socket_.get()) {
182 return NetErrorToPepperError(
183 socket_->SetReceiveBufferSize(integer_value));
184 }
185
186 // UDPSocket instance is not yet created. So remember the value here.
bbudge 2014/12/09 18:37:37 nit: s/. So/, so
hidehiko 2014/12/09 19:51:42 Done.
187 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE;
188 rcvbuf_size_ = integer_value;
189 return PP_OK;
160 } 190 }
161 default: { 191 default: {
162 NOTREACHED(); 192 NOTREACHED();
163 return PP_ERROR_BADARGUMENT; 193 return PP_ERROR_BADARGUMENT;
164 } 194 }
165 } 195 }
166 } 196 }
167 197
168 int32_t PepperUDPSocketMessageFilter::OnMsgBind( 198 int32_t PepperUDPSocketMessageFilter::OnMsgBind(
169 const ppapi::host::HostMessageContext* context, 199 const ppapi::host::HostMessageContext* context,
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 void PepperUDPSocketMessageFilter::DoBind( 276 void PepperUDPSocketMessageFilter::DoBind(
247 const ppapi::host::ReplyMessageContext& context, 277 const ppapi::host::ReplyMessageContext& context,
248 const PP_NetAddress_Private& addr) { 278 const PP_NetAddress_Private& addr) {
249 DCHECK_CURRENTLY_ON(BrowserThread::IO); 279 DCHECK_CURRENTLY_ON(BrowserThread::IO);
250 280
251 if (closed_ || socket_.get()) { 281 if (closed_ || socket_.get()) {
252 SendBindError(context, PP_ERROR_FAILED); 282 SendBindError(context, PP_ERROR_FAILED);
253 return; 283 return;
254 } 284 }
255 285
256 scoped_ptr<net::UDPServerSocket> socket( 286 scoped_ptr<net::UDPSocket> socket(new net::UDPSocket(
257 new net::UDPServerSocket(NULL, net::NetLog::Source())); 287 net::DatagramSocket::DEFAULT_BIND, net::RandIntCallback(),
288 NULL, net::NetLog::Source()));
258 289
259 net::IPAddressNumber address; 290 net::IPAddressNumber address;
260 uint16 port; 291 uint16 port;
261 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) { 292 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
262 SendBindError(context, PP_ERROR_ADDRESS_INVALID); 293 SendBindError(context, PP_ERROR_ADDRESS_INVALID);
263 return; 294 return;
264 } 295 }
296 net::IPEndPoint end_point(address, port);
297 {
298 int net_result = socket->Open(end_point.GetFamily());
299 if (net_result != net::OK) {
300 SendBindError(context, NetErrorToPepperError(net_result));
301 return;
302 }
303 }
265 304
266 if (allow_address_reuse_) 305 if (socket_options_ & SOCKET_OPTION_ADDRESS_REUSE) {
267 socket->AllowAddressReuse(); 306 int net_result = socket->AllowAddressReuse();
268 if (allow_broadcast_) 307 if (net_result != net::OK) {
269 socket->AllowBroadcast(); 308 SendBindError(context, NetErrorToPepperError(net_result));
309 return;
310 }
311 }
312 if (socket_options_ & SOCKET_OPTION_BROADCAST) {
313 int net_result = socket->SetBroadcast(true);
314 if (net_result != net::OK) {
315 SendBindError(context, NetErrorToPepperError(net_result));
316 return;
317 }
318 }
319 if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) {
320 int net_result = socket->SetSendBufferSize(sndbuf_size_);
321 if (net_result != net::OK) {
322 SendBindError(context, NetErrorToPepperError(net_result));
323 return;
324 }
325 }
326 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) {
327 int net_result = socket->SetReceiveBufferSize(rcvbuf_size_);
328 if (net_result != net::OK) {
329 SendBindError(context, NetErrorToPepperError(net_result));
330 return;
331 }
332 }
270 333
271 int32_t pp_result = 334 {
272 NetErrorToPepperError(socket->Listen(net::IPEndPoint(address, port))); 335 int net_result = socket->Bind(end_point);
273 if (pp_result != PP_OK) { 336 if (net_result != net::OK) {
274 SendBindError(context, pp_result); 337 SendBindError(context, NetErrorToPepperError(net_result));
275 return; 338 return;
339 }
276 } 340 }
277 341
278 net::IPEndPoint bound_address; 342 net::IPEndPoint bound_address;
279 pp_result = NetErrorToPepperError(socket->GetLocalAddress(&bound_address)); 343 {
280 if (pp_result != PP_OK) { 344 int net_result = socket->GetLocalAddress(&bound_address);
281 SendBindError(context, pp_result); 345 if (net_result != net::OK) {
282 return; 346 SendBindError(context, NetErrorToPepperError(net_result));
347 return;
348 }
283 } 349 }
284 350
285 PP_NetAddress_Private net_address = NetAddressPrivateImpl::kInvalidNetAddress; 351 PP_NetAddress_Private net_address = NetAddressPrivateImpl::kInvalidNetAddress;
286 if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 352 if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
287 bound_address.address(), bound_address.port(), &net_address)) { 353 bound_address.address(), bound_address.port(), &net_address)) {
288 SendBindError(context, PP_ERROR_ADDRESS_INVALID); 354 SendBindError(context, PP_ERROR_ADDRESS_INVALID);
289 return; 355 return;
290 } 356 }
291 357
292 allow_address_reuse_ = false;
293 allow_broadcast_ = false;
294 socket_.swap(socket); 358 socket_.swap(socket);
295 SendBindReply(context, PP_OK, net_address); 359 SendBindReply(context, PP_OK, net_address);
296 360
297 DoRecvFrom(); 361 DoRecvFrom();
298 } 362 }
299 363
300 void PepperUDPSocketMessageFilter::DoRecvFrom() { 364 void PepperUDPSocketMessageFilter::DoRecvFrom() {
301 DCHECK_CURRENTLY_ON(BrowserThread::IO); 365 DCHECK_CURRENTLY_ON(BrowserThread::IO);
302 DCHECK(!closed_); 366 DCHECK(!closed_);
303 DCHECK(socket_.get()); 367 DCHECK(socket_.get());
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 NetAddressPrivateImpl::kInvalidNetAddress); 529 NetAddressPrivateImpl::kInvalidNetAddress);
466 } 530 }
467 531
468 void PepperUDPSocketMessageFilter::SendSendToError( 532 void PepperUDPSocketMessageFilter::SendSendToError(
469 const ppapi::host::ReplyMessageContext& context, 533 const ppapi::host::ReplyMessageContext& context,
470 int32_t result) { 534 int32_t result) {
471 SendSendToReply(context, result, 0); 535 SendSendToReply(context, result, 0);
472 } 536 }
473 537
474 } // namespace content 538 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698