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" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 #include "ppapi/c/private/ppb_net_address_private.h" | 22 #include "ppapi/c/private/ppb_net_address_private.h" |
| 23 #include "ppapi/host/dispatch_host_message.h" | 23 #include "ppapi/host/dispatch_host_message.h" |
| 24 #include "ppapi/host/error_conversion.h" | 24 #include "ppapi/host/error_conversion.h" |
| 25 #include "ppapi/host/host_message_context.h" | 25 #include "ppapi/host/host_message_context.h" |
| 26 #include "ppapi/host/ppapi_host.h" | 26 #include "ppapi/host/ppapi_host.h" |
| 27 #include "ppapi/host/resource_host.h" | 27 #include "ppapi/host/resource_host.h" |
| 28 #include "ppapi/proxy/ppapi_messages.h" | 28 #include "ppapi/proxy/ppapi_messages.h" |
| 29 #include "ppapi/proxy/udp_socket_resource_base.h" | 29 #include "ppapi/proxy/udp_socket_resource_base.h" |
| 30 #include "ppapi/shared_impl/private/net_address_private_impl.h" | 30 #include "ppapi/shared_impl/private/net_address_private_impl.h" |
| 31 #include "ppapi/shared_impl/socket_option_data.h" | 31 #include "ppapi/shared_impl/socket_option_data.h" |
| 32 #include "ppapi/thunk/enter.h" | |
| 33 #include "ppapi/thunk/ppb_net_address_api.h" | |
| 32 | 34 |
| 33 using ppapi::NetAddressPrivateImpl; | 35 using ppapi::NetAddressPrivateImpl; |
| 34 using ppapi::host::NetErrorToPepperError; | 36 using ppapi::host::NetErrorToPepperError; |
| 35 using ppapi::proxy::UDPSocketResourceBase; | 37 using ppapi::proxy::UDPSocketResourceBase; |
| 38 using ppapi::thunk::EnterResource; | |
| 39 using ppapi::thunk::PPB_NetAddress_API; | |
| 36 | 40 |
| 37 namespace { | 41 namespace { |
| 38 | 42 |
| 39 size_t g_num_instances = 0; | 43 size_t g_num_instances = 0; |
| 40 | 44 |
| 41 } // namespace | 45 } // namespace |
| 42 | 46 |
| 43 namespace content { | 47 namespace content { |
| 44 | 48 |
| 45 PepperUDPSocketMessageFilter::PendingSend::PendingSend( | 49 PepperUDPSocketMessageFilter::PendingSend::PendingSend( |
| 46 const net::IPAddressNumber& address, | 50 const net::IPAddressNumber& address, |
| 47 int port, | 51 int port, |
| 48 const scoped_refptr<net::IOBufferWithSize>& buffer, | 52 const scoped_refptr<net::IOBufferWithSize>& buffer, |
| 49 const ppapi::host::ReplyMessageContext& context) | 53 const ppapi::host::ReplyMessageContext& context) |
| 50 : address(address), port(port), buffer(buffer), context(context) { | 54 : address(address), port(port), buffer(buffer), context(context) { |
| 51 } | 55 } |
| 52 | 56 |
| 53 PepperUDPSocketMessageFilter::PendingSend::~PendingSend() { | 57 PepperUDPSocketMessageFilter::PendingSend::~PendingSend() { |
| 54 } | 58 } |
| 55 | 59 |
| 56 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter( | 60 PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter( |
| 57 BrowserPpapiHostImpl* host, | 61 BrowserPpapiHostImpl* host, |
| 58 PP_Instance instance, | 62 PP_Instance instance, |
| 59 bool private_api) | 63 bool private_api) |
| 60 : socket_options_(0), | 64 : socket_options_(0), |
| 61 rcvbuf_size_(0), | 65 rcvbuf_size_(0), |
| 62 sndbuf_size_(0), | 66 sndbuf_size_(0), |
| 67 multicast_ttl_(0), | |
| 63 closed_(false), | 68 closed_(false), |
| 64 remaining_recv_slots_(UDPSocketResourceBase::kPluginReceiveBufferSlots), | 69 remaining_recv_slots_(UDPSocketResourceBase::kPluginReceiveBufferSlots), |
| 65 external_plugin_(host->external_plugin()), | 70 external_plugin_(host->external_plugin()), |
| 66 private_api_(private_api), | 71 private_api_(private_api), |
| 67 render_process_id_(0), | 72 render_process_id_(0), |
| 68 render_frame_id_(0) { | 73 render_frame_id_(0) { |
| 69 ++g_num_instances; | 74 ++g_num_instances; |
| 70 DCHECK(host); | 75 DCHECK(host); |
| 71 | 76 |
| 72 if (!host->GetRenderFrameIDsForInstance( | 77 if (!host->GetRenderFrameIDsForInstance( |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 88 scoped_refptr<base::TaskRunner> | 93 scoped_refptr<base::TaskRunner> |
| 89 PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage( | 94 PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage( |
| 90 const IPC::Message& message) { | 95 const IPC::Message& message) { |
| 91 switch (message.type()) { | 96 switch (message.type()) { |
| 92 case PpapiHostMsg_UDPSocket_SetOption::ID: | 97 case PpapiHostMsg_UDPSocket_SetOption::ID: |
| 93 case PpapiHostMsg_UDPSocket_Close::ID: | 98 case PpapiHostMsg_UDPSocket_Close::ID: |
| 94 case PpapiHostMsg_UDPSocket_RecvSlotAvailable::ID: | 99 case PpapiHostMsg_UDPSocket_RecvSlotAvailable::ID: |
| 95 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); | 100 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); |
| 96 case PpapiHostMsg_UDPSocket_Bind::ID: | 101 case PpapiHostMsg_UDPSocket_Bind::ID: |
| 97 case PpapiHostMsg_UDPSocket_SendTo::ID: | 102 case PpapiHostMsg_UDPSocket_SendTo::ID: |
| 103 case PpapiHostMsg_UDPSocket_JoinGroup::ID: | |
| 104 case PpapiHostMsg_UDPSocket_LeaveGroup::ID: | |
| 98 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); | 105 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); |
| 99 } | 106 } |
| 100 return NULL; | 107 return NULL; |
| 101 } | 108 } |
| 102 | 109 |
| 103 int32_t PepperUDPSocketMessageFilter::OnResourceMessageReceived( | 110 int32_t PepperUDPSocketMessageFilter::OnResourceMessageReceived( |
| 104 const IPC::Message& msg, | 111 const IPC::Message& msg, |
| 105 ppapi::host::HostMessageContext* context) { | 112 ppapi::host::HostMessageContext* context) { |
| 106 PPAPI_BEGIN_MESSAGE_MAP(PepperUDPSocketMessageFilter, msg) | 113 PPAPI_BEGIN_MESSAGE_MAP(PepperUDPSocketMessageFilter, msg) |
| 107 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SetOption, | 114 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SetOption, |
| 108 OnMsgSetOption) | 115 OnMsgSetOption) |
| 109 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_Bind, OnMsgBind) | 116 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_Bind, OnMsgBind) |
| 110 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SendTo, | 117 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_SendTo, |
| 111 OnMsgSendTo) | 118 OnMsgSendTo) |
| 112 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_UDPSocket_Close, | 119 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_UDPSocket_Close, |
| 113 OnMsgClose) | 120 OnMsgClose) |
| 114 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( | 121 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( |
| 115 PpapiHostMsg_UDPSocket_RecvSlotAvailable, OnMsgRecvSlotAvailable) | 122 PpapiHostMsg_UDPSocket_RecvSlotAvailable, OnMsgRecvSlotAvailable) |
| 123 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_JoinGroup, | |
| 124 OnMsgJoinGroup) | |
| 125 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_LeaveGroup, | |
| 126 OnMsgLeaveGroup) | |
| 116 PPAPI_END_MESSAGE_MAP() | 127 PPAPI_END_MESSAGE_MAP() |
| 117 return PP_ERROR_FAILED; | 128 return PP_ERROR_FAILED; |
| 118 } | 129 } |
| 119 | 130 |
| 120 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( | 131 int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( |
| 121 const ppapi::host::HostMessageContext* context, | 132 const ppapi::host::HostMessageContext* context, |
| 122 PP_UDPSocket_Option name, | 133 PP_UDPSocket_Option name, |
| 123 const ppapi::SocketOptionData& value) { | 134 const ppapi::SocketOptionData& value) { |
| 124 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 135 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 125 | 136 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 144 } else { | 155 } else { |
| 145 socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE; | 156 socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE; |
| 146 } | 157 } |
| 147 return PP_OK; | 158 return PP_OK; |
| 148 } | 159 } |
| 149 case PP_UDPSOCKET_OPTION_BROADCAST: { | 160 case PP_UDPSOCKET_OPTION_BROADCAST: { |
| 150 bool boolean_value = false; | 161 bool boolean_value = false; |
| 151 if (!value.GetBool(&boolean_value)) | 162 if (!value.GetBool(&boolean_value)) |
| 152 return PP_ERROR_BADARGUMENT; | 163 return PP_ERROR_BADARGUMENT; |
| 153 | 164 |
| 154 // If the socket is already connected, proxy the value to TCPSocket. | 165 // If the socket is already connected, proxy the value to UDPSocket. |
| 155 if (socket_.get()) | 166 if (socket_.get()) |
| 156 return NetErrorToPepperError(socket_->SetBroadcast(boolean_value)); | 167 return NetErrorToPepperError(socket_->SetBroadcast(boolean_value)); |
| 157 | 168 |
| 158 // UDPSocket instance is not yet created, so remember the value here. | 169 // UDPSocket instance is not yet created, so remember the value here. |
| 159 if (boolean_value) { | 170 if (boolean_value) { |
| 160 socket_options_ |= SOCKET_OPTION_BROADCAST; | 171 socket_options_ |= SOCKET_OPTION_BROADCAST; |
| 161 } else { | 172 } else { |
| 162 socket_options_ &= ~SOCKET_OPTION_BROADCAST; | 173 socket_options_ &= ~SOCKET_OPTION_BROADCAST; |
| 163 } | 174 } |
| 164 return PP_OK; | 175 return PP_OK; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 194 if (socket_.get()) { | 205 if (socket_.get()) { |
| 195 return NetErrorToPepperError( | 206 return NetErrorToPepperError( |
| 196 socket_->SetReceiveBufferSize(integer_value)); | 207 socket_->SetReceiveBufferSize(integer_value)); |
| 197 } | 208 } |
| 198 | 209 |
| 199 // UDPSocket instance is not yet created, so remember the value here. | 210 // UDPSocket instance is not yet created, so remember the value here. |
| 200 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE; | 211 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE; |
| 201 rcvbuf_size_ = integer_value; | 212 rcvbuf_size_ = integer_value; |
| 202 return PP_OK; | 213 return PP_OK; |
| 203 } | 214 } |
| 215 case PP_UDPSOCKET_OPTION_MULTICAST_LOOP: { | |
| 216 bool boolean_value = false; | |
| 217 if (!value.GetBool(&boolean_value)) | |
| 218 return PP_ERROR_BADARGUMENT; | |
| 219 | |
| 220 // If the socket is already connected, proxy the value to UDPSocket. | |
| 221 if (socket_.get()) | |
| 222 return NetErrorToPepperError( | |
| 223 socket_->SetMulticastLoopbackMode(boolean_value)); | |
| 224 | |
| 225 // UDPSocket instance is not yet created, so remember the value here. | |
| 226 if (boolean_value) { | |
| 227 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP; | |
| 228 } else { | |
| 229 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP; | |
| 230 } | |
| 231 return PP_OK; | |
| 232 } | |
| 233 case PP_UDPSOCKET_OPTION_MULTICAST_TTL: { | |
| 234 int32_t integer_value = 0; | |
| 235 if (!value.GetInt32(&integer_value) || | |
| 236 integer_value < 0 || integer_value > 255) | |
| 237 return PP_ERROR_BADARGUMENT; | |
| 238 | |
| 239 // If the socket is already connected, proxy the value to UDPSocket. | |
| 240 if (socket_.get()) | |
| 241 return NetErrorToPepperError( | |
| 242 socket_->SetMulticastTimeToLive(integer_value)); | |
| 243 | |
| 244 // UDPSocket instance is not yet created, so remember the value here. | |
| 245 socket_options_ |= SOCKET_OPTION_MULTICAST_TTL; | |
| 246 multicast_ttl_ = integer_value; | |
| 247 return PP_OK; | |
| 248 } | |
| 204 default: { | 249 default: { |
| 205 NOTREACHED(); | 250 NOTREACHED(); |
| 206 return PP_ERROR_BADARGUMENT; | 251 return PP_ERROR_BADARGUMENT; |
| 207 } | 252 } |
| 208 } | 253 } |
| 209 } | 254 } |
| 210 | 255 |
| 211 int32_t PepperUDPSocketMessageFilter::OnMsgBind( | 256 int32_t PepperUDPSocketMessageFilter::OnMsgBind( |
| 212 const ppapi::host::HostMessageContext* context, | 257 const ppapi::host::HostMessageContext* context, |
| 213 const PP_NetAddress_Private& addr) { | 258 const PP_NetAddress_Private& addr) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 } | 324 } |
| 280 | 325 |
| 281 if (!recvfrom_buffer_.get() && !closed_ && socket_.get()) { | 326 if (!recvfrom_buffer_.get() && !closed_ && socket_.get()) { |
| 282 DCHECK_EQ(1u, remaining_recv_slots_); | 327 DCHECK_EQ(1u, remaining_recv_slots_); |
| 283 DoRecvFrom(); | 328 DoRecvFrom(); |
| 284 } | 329 } |
| 285 | 330 |
| 286 return PP_OK; | 331 return PP_OK; |
| 287 } | 332 } |
| 288 | 333 |
| 334 int32_t PepperUDPSocketMessageFilter::OnMsgJoinGroup( | |
| 335 const ppapi::host::HostMessageContext* context, | |
| 336 const PP_NetAddress_Private& addr) { | |
| 337 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 338 DCHECK(context); | |
| 339 | |
| 340 if (!socket_.get()) | |
| 341 return PP_ERROR_FAILED; | |
| 342 | |
| 343 net::IPAddressNumber group; | |
| 344 uint16 port; | |
| 345 | |
| 346 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port)) | |
| 347 return PP_ERROR_ADDRESS_INVALID; | |
| 348 | |
| 349 // TODO(etrunko) Check that app has multicast permission. | |
|
etrunko
2015/02/23 22:22:15
Although I added the comment as requested, I am no
bbudge
2015/03/02 16:03:08
We can work that out in a follow on patch.
| |
| 350 return NetErrorToPepperError(socket_->JoinGroup(group)); | |
| 351 } | |
| 352 | |
| 353 int32_t PepperUDPSocketMessageFilter::OnMsgLeaveGroup( | |
| 354 const ppapi::host::HostMessageContext* context, | |
| 355 const PP_NetAddress_Private& addr) { | |
| 356 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
| 357 DCHECK(context); | |
| 358 | |
| 359 if (!socket_.get()) | |
| 360 return PP_ERROR_FAILED; | |
| 361 | |
| 362 net::IPAddressNumber group; | |
| 363 uint16 port; | |
| 364 | |
| 365 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port)) | |
| 366 return PP_ERROR_ADDRESS_INVALID; | |
| 367 | |
| 368 return NetErrorToPepperError(socket_->LeaveGroup(group)); | |
| 369 } | |
| 370 | |
| 289 void PepperUDPSocketMessageFilter::DoBind( | 371 void PepperUDPSocketMessageFilter::DoBind( |
| 290 const ppapi::host::ReplyMessageContext& context, | 372 const ppapi::host::ReplyMessageContext& context, |
| 291 const PP_NetAddress_Private& addr) { | 373 const PP_NetAddress_Private& addr) { |
| 292 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 374 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 293 | 375 |
| 294 if (closed_ || socket_.get()) { | 376 if (closed_ || socket_.get()) { |
| 295 SendBindError(context, PP_ERROR_FAILED); | 377 SendBindError(context, PP_ERROR_FAILED); |
| 296 return; | 378 return; |
| 297 } | 379 } |
| 298 | 380 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 336 return; | 418 return; |
| 337 } | 419 } |
| 338 } | 420 } |
| 339 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) { | 421 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) { |
| 340 int net_result = socket->SetReceiveBufferSize(rcvbuf_size_); | 422 int net_result = socket->SetReceiveBufferSize(rcvbuf_size_); |
| 341 if (net_result != net::OK) { | 423 if (net_result != net::OK) { |
| 342 SendBindError(context, NetErrorToPepperError(net_result)); | 424 SendBindError(context, NetErrorToPepperError(net_result)); |
| 343 return; | 425 return; |
| 344 } | 426 } |
| 345 } | 427 } |
| 428 if (socket_options_ & SOCKET_OPTION_MULTICAST_LOOP) { | |
| 429 int net_result = socket->SetMulticastLoopbackMode(true); | |
| 430 if (net_result != net::OK) { | |
| 431 SendBindError(context, NetErrorToPepperError(net_result)); | |
| 432 return; | |
| 433 } | |
| 434 } | |
| 435 if (socket_options_ & SOCKET_OPTION_MULTICAST_TTL) { | |
| 436 int net_result = socket->SetMulticastInterface(multicast_ttl_); | |
| 437 if (net_result != net::OK) { | |
| 438 SendBindError(context, NetErrorToPepperError(net_result)); | |
| 439 return; | |
| 440 } | |
| 441 } | |
| 346 | 442 |
| 347 { | 443 { |
| 348 int net_result = socket->Bind(end_point); | 444 int net_result = socket->Bind(end_point); |
| 349 if (net_result != net::OK) { | 445 if (net_result != net::OK) { |
| 350 SendBindError(context, NetErrorToPepperError(net_result)); | 446 SendBindError(context, NetErrorToPepperError(net_result)); |
| 351 return; | 447 return; |
| 352 } | 448 } |
| 353 } | 449 } |
| 354 | 450 |
| 355 net::IPEndPoint bound_address; | 451 net::IPEndPoint bound_address; |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 564 NetAddressPrivateImpl::kInvalidNetAddress); | 660 NetAddressPrivateImpl::kInvalidNetAddress); |
| 565 } | 661 } |
| 566 | 662 |
| 567 void PepperUDPSocketMessageFilter::SendSendToError( | 663 void PepperUDPSocketMessageFilter::SendSendToError( |
| 568 const ppapi::host::ReplyMessageContext& context, | 664 const ppapi::host::ReplyMessageContext& context, |
| 569 int32_t result) { | 665 int32_t result) { |
| 570 SendSendToReply(context, result, 0); | 666 SendSendToReply(context, result, 0); |
| 571 } | 667 } |
| 572 | 668 |
| 573 } // namespace content | 669 } // namespace content |
| OLD | NEW |