OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |