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

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: 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),
48 allow_broadcast_(false), 49 rcvbuf_size_(0),
50 sndbuf_size_(0),
49 closed_(false), 51 closed_(false),
50 remaining_recv_slots_( 52 remaining_recv_slots_(
51 ppapi::proxy::UDPSocketResourceBase::kPluginReceiveBufferSlots), 53 ppapi::proxy::UDPSocketResourceBase::kPluginReceiveBufferSlots),
52 external_plugin_(host->external_plugin()), 54 external_plugin_(host->external_plugin()),
53 private_api_(private_api), 55 private_api_(private_api),
54 render_process_id_(0), 56 render_process_id_(0),
55 render_frame_id_(0) { 57 render_frame_id_(0) {
56 ++g_num_instances; 58 ++g_num_instances;
57 DCHECK(host); 59 DCHECK(host);
58 60
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( 109 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption(
108 const ppapi::host::HostMessageContext* context, 110 const ppapi::host::HostMessageContext* context,
109 PP_UDPSocket_Option name, 111 PP_UDPSocket_Option name,
110 const ppapi::SocketOptionData& value) { 112 const ppapi::SocketOptionData& value) {
111 DCHECK_CURRENTLY_ON(BrowserThread::IO); 113 DCHECK_CURRENTLY_ON(BrowserThread::IO);
112 114
113 if (closed_) 115 if (closed_)
114 return PP_ERROR_FAILED; 116 return PP_ERROR_FAILED;
115 117
116 switch (name) { 118 switch (name) {
117 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: 119 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: {
118 case PP_UDPSOCKET_OPTION_BROADCAST: {
119 if (socket_.get()) { 120 if (socket_.get()) {
120 // They only take effect before the socket is bound. 121 // AllowReuseAddress is only effective before Bind().
122 // Note that this limitation originally comes from Windows, but
123 // PPAPI tries to provide platform independent APIs.
121 return PP_ERROR_FAILED; 124 return PP_ERROR_FAILED;
122 } 125 }
123 126
124 bool boolean_value = false; 127 bool boolean_value = false;
125 if (!value.GetBool(&boolean_value)) 128 if (!value.GetBool(&boolean_value))
126 return PP_ERROR_BADARGUMENT; 129 return PP_ERROR_BADARGUMENT;
127 130
128 if (name == PP_UDPSOCKET_OPTION_ADDRESS_REUSE) 131 if (boolean_value) {
129 allow_address_reuse_ = boolean_value; 132 socket_options_ |= SOCKET_OPTION_ADDRESS_REUSE;
130 else 133 } else {
131 allow_broadcast_ = boolean_value; 134 socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE;
135 }
132 return PP_OK; 136 return PP_OK;
133 } 137 }
134 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: 138 case PP_UDPSOCKET_OPTION_BROADCAST: {
135 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: { 139 bool boolean_value = false;
136 if (!socket_.get()) { 140 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; 141 return PP_ERROR_BADARGUMENT;
143 142
144 int net_result = net::ERR_UNEXPECTED; 143 // If the socket is already connected, proxy the value to TCPSocket.
145 if (name == PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE) { 144 if (socket_.get())
146 if (integer_value > 145 return NetErrorToPepperError(socket_->SetBroadcast(boolean_value));
147 ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize) { 146
148 return PP_ERROR_BADARGUMENT; 147 // UDPSocket instance is not yet created, so remember the value here.
149 } 148 if (boolean_value) {
150 net_result = socket_->SetSendBufferSize(integer_value); 149 socket_options_ |= SOCKET_OPTION_BROADCAST;
151 } else { 150 } else {
152 if (integer_value > 151 socket_options_ &= ~SOCKET_OPTION_BROADCAST;
153 ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize) {
154 return PP_ERROR_BADARGUMENT;
155 }
156 net_result = socket_->SetReceiveBufferSize(integer_value);
157 } 152 }
158 // TODO(wtc): Add error mapping code. 153 return PP_OK;
159 return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED; 154 }
155 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: {
156 int32_t integer_value = 0;
157 if (!value.GetInt32(&integer_value) ||
158 integer_value <= 0 ||
159 integer_value >
160 ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize)
161 return PP_ERROR_BADARGUMENT;
162
163 // If the socket is already connected, proxy the value to UDPSocket.
164 if (socket_.get()) {
165 return NetErrorToPepperError(
166 socket_->SetSendBufferSize(integer_value));
167 }
168
169 // UDPSocket instance is not yet created, so remember the value here.
170 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE;
171 sndbuf_size_ = integer_value;
172 return PP_OK;
173 }
174 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: {
175 int32_t integer_value = 0;
176 if (!value.GetInt32(&integer_value) ||
177 integer_value <= 0 ||
178 integer_value >
179 ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize)
180 return PP_ERROR_BADARGUMENT;
181
182 // If the socket is already connected, proxy the value to UDPSocket.
183 if (socket_.get()) {
184 return NetErrorToPepperError(
185 socket_->SetReceiveBufferSize(integer_value));
186 }
187
188 // UDPSocket instance is not yet created, so remember the value here.
189 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE;
190 rcvbuf_size_ = integer_value;
191 return PP_OK;
160 } 192 }
161 default: { 193 default: {
162 NOTREACHED(); 194 NOTREACHED();
163 return PP_ERROR_BADARGUMENT; 195 return PP_ERROR_BADARGUMENT;
164 } 196 }
165 } 197 }
166 } 198 }
167 199
168 int32_t PepperUDPSocketMessageFilter::OnMsgBind( 200 int32_t PepperUDPSocketMessageFilter::OnMsgBind(
169 const ppapi::host::HostMessageContext* context, 201 const ppapi::host::HostMessageContext* context,
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 void PepperUDPSocketMessageFilter::DoBind( 278 void PepperUDPSocketMessageFilter::DoBind(
247 const ppapi::host::ReplyMessageContext& context, 279 const ppapi::host::ReplyMessageContext& context,
248 const PP_NetAddress_Private& addr) { 280 const PP_NetAddress_Private& addr) {
249 DCHECK_CURRENTLY_ON(BrowserThread::IO); 281 DCHECK_CURRENTLY_ON(BrowserThread::IO);
250 282
251 if (closed_ || socket_.get()) { 283 if (closed_ || socket_.get()) {
252 SendBindError(context, PP_ERROR_FAILED); 284 SendBindError(context, PP_ERROR_FAILED);
253 return; 285 return;
254 } 286 }
255 287
256 scoped_ptr<net::UDPServerSocket> socket( 288 scoped_ptr<net::UDPSocket> socket(new net::UDPSocket(
257 new net::UDPServerSocket(NULL, net::NetLog::Source())); 289 net::DatagramSocket::DEFAULT_BIND, net::RandIntCallback(),
290 NULL, net::NetLog::Source()));
258 291
259 net::IPAddressNumber address; 292 net::IPAddressNumber address;
260 uint16 port; 293 uint16 port;
261 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) { 294 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &address, &port)) {
262 SendBindError(context, PP_ERROR_ADDRESS_INVALID); 295 SendBindError(context, PP_ERROR_ADDRESS_INVALID);
263 return; 296 return;
264 } 297 }
298 net::IPEndPoint end_point(address, port);
299 {
300 int net_result = socket->Open(end_point.GetFamily());
301 if (net_result != net::OK) {
302 SendBindError(context, NetErrorToPepperError(net_result));
303 return;
304 }
305 }
265 306
266 if (allow_address_reuse_) 307 if (socket_options_ & SOCKET_OPTION_ADDRESS_REUSE) {
267 socket->AllowAddressReuse(); 308 int net_result = socket->AllowAddressReuse();
268 if (allow_broadcast_) 309 if (net_result != net::OK) {
269 socket->AllowBroadcast(); 310 SendBindError(context, NetErrorToPepperError(net_result));
311 return;
312 }
313 }
314 if (socket_options_ & SOCKET_OPTION_BROADCAST) {
315 int net_result = socket->SetBroadcast(true);
316 if (net_result != net::OK) {
317 SendBindError(context, NetErrorToPepperError(net_result));
318 return;
319 }
320 }
321 if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) {
322 int net_result = socket->SetSendBufferSize(sndbuf_size_);
323 if (net_result != net::OK) {
324 SendBindError(context, NetErrorToPepperError(net_result));
325 return;
326 }
327 }
328 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) {
329 int net_result = socket->SetReceiveBufferSize(rcvbuf_size_);
330 if (net_result != net::OK) {
331 SendBindError(context, NetErrorToPepperError(net_result));
332 return;
333 }
334 }
270 335
271 int32_t pp_result = 336 {
272 NetErrorToPepperError(socket->Listen(net::IPEndPoint(address, port))); 337 int net_result = socket->Bind(end_point);
273 if (pp_result != PP_OK) { 338 if (net_result != net::OK) {
274 SendBindError(context, pp_result); 339 SendBindError(context, NetErrorToPepperError(net_result));
275 return; 340 return;
341 }
276 } 342 }
277 343
278 net::IPEndPoint bound_address; 344 net::IPEndPoint bound_address;
279 pp_result = NetErrorToPepperError(socket->GetLocalAddress(&bound_address)); 345 {
280 if (pp_result != PP_OK) { 346 int net_result = socket->GetLocalAddress(&bound_address);
281 SendBindError(context, pp_result); 347 if (net_result != net::OK) {
282 return; 348 SendBindError(context, NetErrorToPepperError(net_result));
349 return;
350 }
283 } 351 }
284 352
285 PP_NetAddress_Private net_address = NetAddressPrivateImpl::kInvalidNetAddress; 353 PP_NetAddress_Private net_address = NetAddressPrivateImpl::kInvalidNetAddress;
286 if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 354 if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
287 bound_address.address(), bound_address.port(), &net_address)) { 355 bound_address.address(), bound_address.port(), &net_address)) {
288 SendBindError(context, PP_ERROR_ADDRESS_INVALID); 356 SendBindError(context, PP_ERROR_ADDRESS_INVALID);
289 return; 357 return;
290 } 358 }
291 359
292 allow_address_reuse_ = false;
293 allow_broadcast_ = false;
294 socket_.swap(socket); 360 socket_.swap(socket);
295 SendBindReply(context, PP_OK, net_address); 361 SendBindReply(context, PP_OK, net_address);
296 362
297 DoRecvFrom(); 363 DoRecvFrom();
298 } 364 }
299 365
300 void PepperUDPSocketMessageFilter::DoRecvFrom() { 366 void PepperUDPSocketMessageFilter::DoRecvFrom() {
301 DCHECK_CURRENTLY_ON(BrowserThread::IO); 367 DCHECK_CURRENTLY_ON(BrowserThread::IO);
302 DCHECK(!closed_); 368 DCHECK(!closed_);
303 DCHECK(socket_.get()); 369 DCHECK(socket_.get());
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 NetAddressPrivateImpl::kInvalidNetAddress); 531 NetAddressPrivateImpl::kInvalidNetAddress);
466 } 532 }
467 533
468 void PepperUDPSocketMessageFilter::SendSendToError( 534 void PepperUDPSocketMessageFilter::SendSendToError(
469 const ppapi::host::ReplyMessageContext& context, 535 const ppapi::host::ReplyMessageContext& context,
470 int32_t result) { 536 int32_t result) {
471 SendSendToReply(context, result, 0); 537 SendSendToReply(context, result, 0);
472 } 538 }
473 539
474 } // namespace content 540 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h ('k') | ppapi/api/ppb_tcp_socket.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698