Chromium Code Reviews| Index: content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc |
| diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc |
| index 50221d9222c4f7dfe3e7f2c87e3218020c864d48..9661e875d114920fe9f528a5a7d9d974eafba960 100644 |
| --- a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc |
| +++ b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc |
| @@ -11,6 +11,7 @@ |
| #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" |
| #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" |
| #include "content/public/browser/browser_thread.h" |
| +#include "content/public/browser/content_browser_client.h" |
| #include "content/public/common/process_type.h" |
| #include "content/public/common/socket_permission_request.h" |
| #include "ipc/ipc_message_macros.h" |
| @@ -60,6 +61,7 @@ PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter( |
| : socket_options_(0), |
| rcvbuf_size_(0), |
| sndbuf_size_(0), |
| + multicast_ttl_(0), |
| closed_(false), |
| remaining_recv_slots_(UDPSocketResourceBase::kPluginReceiveBufferSlots), |
| external_plugin_(host->external_plugin()), |
| @@ -95,6 +97,8 @@ PepperUDPSocketMessageFilter::OverrideTaskRunnerForMessage( |
| return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); |
| case PpapiHostMsg_UDPSocket_Bind::ID: |
| case PpapiHostMsg_UDPSocket_SendTo::ID: |
| + case PpapiHostMsg_UDPSocket_JoinGroup::ID: |
| + case PpapiHostMsg_UDPSocket_LeaveGroup::ID: |
| return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); |
| } |
| return NULL; |
| @@ -113,6 +117,10 @@ int32_t PepperUDPSocketMessageFilter::OnResourceMessageReceived( |
| OnMsgClose) |
| PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( |
| PpapiHostMsg_UDPSocket_RecvSlotAvailable, OnMsgRecvSlotAvailable) |
| + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_JoinGroup, |
| + OnMsgJoinGroup) |
| + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_UDPSocket_LeaveGroup, |
| + OnMsgLeaveGroup) |
| PPAPI_END_MESSAGE_MAP() |
| return PP_ERROR_FAILED; |
| } |
| @@ -151,7 +159,7 @@ int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( |
| if (!value.GetBool(&boolean_value)) |
| return PP_ERROR_BADARGUMENT; |
| - // If the socket is already connected, proxy the value to TCPSocket. |
| + // If the socket is already bound, proxy the value to UDPSocket. |
| if (socket_.get()) |
| return NetErrorToPepperError(socket_->SetBroadcast(boolean_value)); |
| @@ -171,7 +179,7 @@ int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( |
| ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize) |
| return PP_ERROR_BADARGUMENT; |
| - // If the socket is already connected, proxy the value to UDPSocket. |
| + // If the socket is already bound, proxy the value to UDPSocket. |
| if (socket_.get()) { |
| return NetErrorToPepperError( |
| socket_->SetSendBufferSize(integer_value)); |
| @@ -190,7 +198,7 @@ int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( |
| ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize) |
| return PP_ERROR_BADARGUMENT; |
| - // If the socket is already connected, proxy the value to UDPSocket. |
| + // If the socket is already bound, proxy the value to UDPSocket. |
| if (socket_.get()) { |
| return NetErrorToPepperError( |
| socket_->SetReceiveBufferSize(integer_value)); |
| @@ -201,6 +209,52 @@ int32_t PepperUDPSocketMessageFilter::OnMsgSetOption( |
| rcvbuf_size_ = integer_value; |
| return PP_OK; |
| } |
| + case PP_UDPSOCKET_OPTION_MULTICAST_LOOP: { |
| + PP_NetAddress_Private any_addr; |
| + NetAddressPrivateImpl::CreateNetAddressPrivateFromAnyAddress( |
| + PP_FromBool(false), &any_addr); |
|
bbudge
2015/03/07 00:52:21
s/PP_FromBool(false)/PP_FALSE
etrunko
2015/03/09 17:24:30
Done.
|
| + if (!CanUseUDPMulticastAPI(any_addr)) |
| + return PP_ERROR_NOACCESS; |
| + |
| + bool boolean_value = false; |
| + if (!value.GetBool(&boolean_value)) |
| + return PP_ERROR_BADARGUMENT; |
| + |
| + // If the socket is already bound, proxy the value to UDPSocket. |
| + if (socket_) |
| + return NetErrorToPepperError( |
| + socket_->SetMulticastLoopbackMode(boolean_value)); |
| + |
| + // UDPSocket instance is not yet created, so remember the value here. |
| + if (boolean_value) { |
| + socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP; |
| + } else { |
| + socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP; |
| + } |
| + return PP_OK; |
| + } |
| + case PP_UDPSOCKET_OPTION_MULTICAST_TTL: { |
| + PP_NetAddress_Private any_addr; |
| + NetAddressPrivateImpl::CreateNetAddressPrivateFromAnyAddress( |
| + PP_FromBool(false), &any_addr); |
|
bbudge
2015/03/07 00:52:21
PP_FALSE
etrunko
2015/03/09 17:24:30
Done.
|
| + if (!CanUseUDPMulticastAPI(any_addr)) |
| + return PP_ERROR_NOACCESS; |
| + |
| + int32_t integer_value = 0; |
| + if (!value.GetInt32(&integer_value) || |
| + integer_value < 0 || integer_value > 255) |
| + return PP_ERROR_BADARGUMENT; |
| + |
| + // If the socket is already bound, proxy the value to UDPSocket. |
| + if (socket_) |
| + return NetErrorToPepperError( |
| + socket_->SetMulticastTimeToLive(integer_value)); |
| + |
| + // UDPSocket instance is not yet created, so remember the value here. |
| + socket_options_ |= SOCKET_OPTION_MULTICAST_TTL; |
| + multicast_ttl_ = integer_value; |
| + return PP_OK; |
| + } |
| default: { |
| NOTREACHED(); |
| return PP_ERROR_BADARGUMENT; |
| @@ -286,6 +340,46 @@ int32_t PepperUDPSocketMessageFilter::OnMsgRecvSlotAvailable( |
| return PP_OK; |
| } |
| +int32_t PepperUDPSocketMessageFilter::OnMsgJoinGroup( |
| + const ppapi::host::HostMessageContext* context, |
| + const PP_NetAddress_Private& addr) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + |
| + if (!CanUseUDPMulticastAPI(addr)) |
| + return PP_ERROR_NOACCESS; |
| + |
| + if (!socket_) |
| + return PP_ERROR_FAILED; |
| + |
| + net::IPAddressNumber group; |
| + uint16 port; |
| + |
| + if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port)) |
| + return PP_ERROR_ADDRESS_INVALID; |
| + |
| + return NetErrorToPepperError(socket_->JoinGroup(group)); |
| +} |
| + |
| +int32_t PepperUDPSocketMessageFilter::OnMsgLeaveGroup( |
| + const ppapi::host::HostMessageContext* context, |
| + const PP_NetAddress_Private& addr) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + |
| + if (!CanUseUDPMulticastAPI(addr)) |
| + return PP_ERROR_NOACCESS; |
| + |
| + if (!socket_) |
| + return PP_ERROR_FAILED; |
| + |
| + net::IPAddressNumber group; |
| + uint16 port; |
| + |
| + if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port)) |
| + return PP_ERROR_ADDRESS_INVALID; |
| + |
| + return NetErrorToPepperError(socket_->LeaveGroup(group)); |
| +} |
| + |
| void PepperUDPSocketMessageFilter::DoBind( |
| const ppapi::host::ReplyMessageContext& context, |
| const PP_NetAddress_Private& addr) { |
| @@ -343,6 +437,20 @@ void PepperUDPSocketMessageFilter::DoBind( |
| return; |
| } |
| } |
| + if (socket_options_ & SOCKET_OPTION_MULTICAST_LOOP) { |
| + int net_result = socket->SetMulticastLoopbackMode(true); |
| + if (net_result != net::OK) { |
| + SendBindError(context, NetErrorToPepperError(net_result)); |
| + return; |
| + } |
| + } |
| + if (socket_options_ & SOCKET_OPTION_MULTICAST_TTL) { |
| + int net_result = socket->SetMulticastInterface(multicast_ttl_); |
| + if (net_result != net::OK) { |
| + SendBindError(context, NetErrorToPepperError(net_result)); |
| + return; |
| + } |
| + } |
| { |
| int net_result = socket->Bind(end_point); |
| @@ -570,4 +678,30 @@ void PepperUDPSocketMessageFilter::SendSendToError( |
| SendSendToReply(context, result, 0); |
| } |
| +bool PepperUDPSocketMessageFilter::CanUseUDPMulticastAPI( |
| + const PP_NetAddress_Private& addr) { |
| + // Check for Dev API. |
| + // TODO(etrunko): remove check when Multicast API reaches beta/stable. |
| + // https://crbug.com/464452 |
| + ContentBrowserClient* content_renderer_client = GetContentClient()->browser(); |
|
bbudge
2015/03/07 00:52:21
nit: content_browser_client or content_client.
etrunko
2015/03/09 17:24:30
Done.
|
| + if (!content_renderer_client->IsPluginAllowedToUseDevChannelAPIs(NULL, |
| + GURL())) { |
| + return false; |
|
bbudge
2015/03/07 00:52:21
It would be better if we could return PP_ERROR_FAI
etrunko
2015/03/09 17:24:30
Done.
|
| + } |
| + |
| + // Check for plugin permissions. |
| + SocketPermissionRequest request = |
| + pepper_socket_utils::CreateSocketPermissionRequest( |
| + SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, addr); |
| + if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, |
| + private_api_, |
| + &request, |
| + render_process_id_, |
| + render_frame_id_)) { |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| } // namespace content |