Chromium Code Reviews| 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 |