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); |