| 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 8213bb4f8e9446c923a587e3767b4e18719a8617..5b06e5fb2d5b2944945d17eeaf4aff6e7cf0e511 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
|
| @@ -29,9 +29,13 @@
|
| #include "ppapi/proxy/udp_socket_resource_base.h"
|
| #include "ppapi/shared_impl/private/net_address_private_impl.h"
|
| #include "ppapi/shared_impl/socket_option_data.h"
|
| +#include "ppapi/thunk/enter.h"
|
| +#include "ppapi/thunk/ppb_net_address_api.h"
|
|
|
| using ppapi::NetAddressPrivateImpl;
|
| using ppapi::host::NetErrorToPepperError;
|
| +using ppapi::thunk::EnterResource;
|
| +using ppapi::thunk::PPB_NetAddress_API;
|
|
|
| namespace {
|
|
|
| @@ -48,6 +52,8 @@ PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter(
|
| : socket_options_(0),
|
| rcvbuf_size_(0),
|
| sndbuf_size_(0),
|
| + multicast_if_(0),
|
| + multicast_ttl_(0),
|
| closed_(false),
|
| remaining_recv_slots_(
|
| ppapi::proxy::UDPSocketResourceBase::kPluginReceiveBufferSlots),
|
| @@ -140,7 +146,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 connected, proxy the value to UDPSocket.
|
| if (socket_.get())
|
| return NetErrorToPepperError(socket_->SetBroadcast(boolean_value));
|
|
|
| @@ -190,6 +196,96 @@ int32_t PepperUDPSocketMessageFilter::OnMsgSetOption(
|
| rcvbuf_size_ = integer_value;
|
| return PP_OK;
|
| }
|
| + case PP_UDPSOCKET_OPTION_MULTICAST_LOOP: {
|
| + bool boolean_value = false;
|
| + if (!value.GetBool(&boolean_value))
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + // If the socket is already connected, proxy the value to UDPSocket.
|
| + if (socket_.get())
|
| + 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: {
|
| + 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 connected, proxy the value to UDPSocket.
|
| + if (socket_.get())
|
| + 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;
|
| + }
|
| + case PP_UDPSOCKET_OPTION_MULTICAST_IF: {
|
| + int32_t integer_value = 0;
|
| + if (!value.GetInt32(&integer_value) || integer_value < 0)
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + // If the socket is already connected, proxy the value to UDPSocket.
|
| + if (socket_.get())
|
| + return NetErrorToPepperError(
|
| + socket_->SetMulticastInterface(static_cast<uint32>(integer_value)));
|
| +
|
| + // UDPSocket instance is not yet created, so remember the value here.
|
| + socket_options_ |= SOCKET_OPTION_MULTICAST_IF;
|
| + multicast_if_ = integer_value;
|
| + return PP_OK;
|
| + }
|
| + case PP_UDPSOCKET_OPTION_MULTICAST_JOIN:
|
| + case PP_UDPSOCKET_OPTION_MULTICAST_LEAVE: {
|
| + PP_Resource resource = 0;
|
| + if (!value.GetInt32(&resource))
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + EnterResource<PPB_NetAddress_API> net_address_api(resource, true);
|
| + if (net_address_api.failed())
|
| + return PP_ERROR_BADRESOURCE;
|
| +
|
| + PP_NetAddress_Private addr;
|
| + PP_NetAddress_Family family = net_address_api.object()->GetFamily();
|
| + if (family == PP_NETADDRESS_FAMILY_IPV4) {
|
| + PP_NetAddress_IPv4 v4;
|
| + if (!net_address_api.object()->DescribeAsIPv4Address(&v4))
|
| + return PP_ERROR_ADDRESS_INVALID;
|
| + NetAddressPrivateImpl::CreateNetAddressPrivateFromIPv4Address(
|
| + v4, &addr);
|
| + } else if (family == PP_NETADDRESS_FAMILY_IPV6) {
|
| + PP_NetAddress_IPv6 v6;
|
| + if (!net_address_api.object()->DescribeAsIPv6Address(&v6))
|
| + return PP_ERROR_ADDRESS_INVALID;
|
| + NetAddressPrivateImpl::CreateNetAddressPrivateFromIPv6Address(
|
| + v6, &addr);
|
| + } else {
|
| + return PP_ERROR_BADARGUMENT;
|
| + }
|
| +
|
| + net::IPAddressNumber group;
|
| + uint16 port;
|
| + if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(addr, &group, &port))
|
| + return PP_ERROR_ADDRESS_INVALID;
|
| +
|
| + int net_result = net::ERR_UNEXPECTED;
|
| + if (name == PP_UDPSOCKET_OPTION_MULTICAST_JOIN)
|
| + net_result = socket_->JoinGroup(group);
|
| + else if (name == PP_UDPSOCKET_OPTION_MULTICAST_LEAVE)
|
| + net_result = socket_->LeaveGroup(group);
|
| +
|
| + return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED;
|
| + }
|
| default: {
|
| NOTREACHED();
|
| return PP_ERROR_BADARGUMENT;
|
| @@ -332,6 +428,27 @@ 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;
|
| + }
|
| + }
|
| + if (socket_options_ & SOCKET_OPTION_MULTICAST_IF) {
|
| + int net_result = socket->SetMulticastInterface(multicast_if_);
|
| + if (net_result != net::OK) {
|
| + SendBindError(context, NetErrorToPepperError(net_result));
|
| + return;
|
| + }
|
| + }
|
|
|
| {
|
| int net_result = socket->Bind(end_point);
|
|
|