| 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 dd915b85ea377e2c152c0a4329dd53c99e2f394f..8213bb4f8e9446c923a587e3767b4e18719a8617 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
|
| @@ -16,7 +16,8 @@
|
| #include "ipc/ipc_message_macros.h"
|
| #include "net/base/io_buffer.h"
|
| #include "net/base/net_errors.h"
|
| -#include "net/udp/udp_server_socket.h"
|
| +#include "net/base/rand_callback.h"
|
| +#include "net/udp/udp_socket.h"
|
| #include "ppapi/c/pp_errors.h"
|
| #include "ppapi/c/private/ppb_net_address_private.h"
|
| #include "ppapi/host/dispatch_host_message.h"
|
| @@ -44,8 +45,9 @@ PepperUDPSocketMessageFilter::PepperUDPSocketMessageFilter(
|
| BrowserPpapiHostImpl* host,
|
| PP_Instance instance,
|
| bool private_api)
|
| - : allow_address_reuse_(false),
|
| - allow_broadcast_(false),
|
| + : socket_options_(0),
|
| + rcvbuf_size_(0),
|
| + sndbuf_size_(0),
|
| closed_(false),
|
| remaining_recv_slots_(
|
| ppapi::proxy::UDPSocketResourceBase::kPluginReceiveBufferSlots),
|
| @@ -114,10 +116,11 @@ int32_t PepperUDPSocketMessageFilter::OnMsgSetOption(
|
| return PP_ERROR_FAILED;
|
|
|
| switch (name) {
|
| - case PP_UDPSOCKET_OPTION_ADDRESS_REUSE:
|
| - case PP_UDPSOCKET_OPTION_BROADCAST: {
|
| + case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: {
|
| if (socket_.get()) {
|
| - // They only take effect before the socket is bound.
|
| + // AllowReuseAddress is only effective before Bind().
|
| + // Note that this limitation originally comes from Windows, but
|
| + // PPAPI tries to provide platform independent APIs.
|
| return PP_ERROR_FAILED;
|
| }
|
|
|
| @@ -125,38 +128,67 @@ int32_t PepperUDPSocketMessageFilter::OnMsgSetOption(
|
| if (!value.GetBool(&boolean_value))
|
| return PP_ERROR_BADARGUMENT;
|
|
|
| - if (name == PP_UDPSOCKET_OPTION_ADDRESS_REUSE)
|
| - allow_address_reuse_ = boolean_value;
|
| - else
|
| - allow_broadcast_ = boolean_value;
|
| + if (boolean_value) {
|
| + socket_options_ |= SOCKET_OPTION_ADDRESS_REUSE;
|
| + } else {
|
| + socket_options_ &= ~SOCKET_OPTION_ADDRESS_REUSE;
|
| + }
|
| return PP_OK;
|
| }
|
| - case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE:
|
| - case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: {
|
| - if (!socket_.get()) {
|
| - // They only take effect after the socket is bound.
|
| - return PP_ERROR_FAILED;
|
| + case PP_UDPSOCKET_OPTION_BROADCAST: {
|
| + bool boolean_value = false;
|
| + if (!value.GetBool(&boolean_value))
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + // If the socket is already connected, proxy the value to TCPSocket.
|
| + if (socket_.get())
|
| + return NetErrorToPepperError(socket_->SetBroadcast(boolean_value));
|
| +
|
| + // UDPSocket instance is not yet created, so remember the value here.
|
| + if (boolean_value) {
|
| + socket_options_ |= SOCKET_OPTION_BROADCAST;
|
| + } else {
|
| + socket_options_ &= ~SOCKET_OPTION_BROADCAST;
|
| }
|
| + return PP_OK;
|
| + }
|
| + case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: {
|
| int32_t integer_value = 0;
|
| - if (!value.GetInt32(&integer_value) || integer_value <= 0)
|
| + if (!value.GetInt32(&integer_value) ||
|
| + integer_value <= 0 ||
|
| + integer_value >
|
| + ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize)
|
| return PP_ERROR_BADARGUMENT;
|
|
|
| - int net_result = net::ERR_UNEXPECTED;
|
| - if (name == PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE) {
|
| - if (integer_value >
|
| - ppapi::proxy::UDPSocketResourceBase::kMaxSendBufferSize) {
|
| - return PP_ERROR_BADARGUMENT;
|
| - }
|
| - net_result = socket_->SetSendBufferSize(integer_value);
|
| - } else {
|
| - if (integer_value >
|
| - ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize) {
|
| - return PP_ERROR_BADARGUMENT;
|
| - }
|
| - net_result = socket_->SetReceiveBufferSize(integer_value);
|
| + // If the socket is already connected, proxy the value to UDPSocket.
|
| + if (socket_.get()) {
|
| + return NetErrorToPepperError(
|
| + socket_->SetSendBufferSize(integer_value));
|
| }
|
| - // TODO(wtc): Add error mapping code.
|
| - return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED;
|
| +
|
| + // UDPSocket instance is not yet created, so remember the value here.
|
| + socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE;
|
| + sndbuf_size_ = integer_value;
|
| + return PP_OK;
|
| + }
|
| + case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: {
|
| + int32_t integer_value = 0;
|
| + if (!value.GetInt32(&integer_value) ||
|
| + integer_value <= 0 ||
|
| + integer_value >
|
| + ppapi::proxy::UDPSocketResourceBase::kMaxReceiveBufferSize)
|
| + return PP_ERROR_BADARGUMENT;
|
| +
|
| + // If the socket is already connected, proxy the value to UDPSocket.
|
| + if (socket_.get()) {
|
| + return NetErrorToPepperError(
|
| + socket_->SetReceiveBufferSize(integer_value));
|
| + }
|
| +
|
| + // UDPSocket instance is not yet created, so remember the value here.
|
| + socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE;
|
| + rcvbuf_size_ = integer_value;
|
| + return PP_OK;
|
| }
|
| default: {
|
| NOTREACHED();
|
| @@ -253,8 +285,9 @@ void PepperUDPSocketMessageFilter::DoBind(
|
| return;
|
| }
|
|
|
| - scoped_ptr<net::UDPServerSocket> socket(
|
| - new net::UDPServerSocket(NULL, net::NetLog::Source()));
|
| + scoped_ptr<net::UDPSocket> socket(new net::UDPSocket(
|
| + net::DatagramSocket::DEFAULT_BIND, net::RandIntCallback(),
|
| + NULL, net::NetLog::Source()));
|
|
|
| net::IPAddressNumber address;
|
| uint16 port;
|
| @@ -262,24 +295,59 @@ void PepperUDPSocketMessageFilter::DoBind(
|
| SendBindError(context, PP_ERROR_ADDRESS_INVALID);
|
| return;
|
| }
|
| + net::IPEndPoint end_point(address, port);
|
| + {
|
| + int net_result = socket->Open(end_point.GetFamily());
|
| + if (net_result != net::OK) {
|
| + SendBindError(context, NetErrorToPepperError(net_result));
|
| + return;
|
| + }
|
| + }
|
|
|
| - if (allow_address_reuse_)
|
| - socket->AllowAddressReuse();
|
| - if (allow_broadcast_)
|
| - socket->AllowBroadcast();
|
| + if (socket_options_ & SOCKET_OPTION_ADDRESS_REUSE) {
|
| + int net_result = socket->AllowAddressReuse();
|
| + if (net_result != net::OK) {
|
| + SendBindError(context, NetErrorToPepperError(net_result));
|
| + return;
|
| + }
|
| + }
|
| + if (socket_options_ & SOCKET_OPTION_BROADCAST) {
|
| + int net_result = socket->SetBroadcast(true);
|
| + if (net_result != net::OK) {
|
| + SendBindError(context, NetErrorToPepperError(net_result));
|
| + return;
|
| + }
|
| + }
|
| + if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) {
|
| + int net_result = socket->SetSendBufferSize(sndbuf_size_);
|
| + if (net_result != net::OK) {
|
| + SendBindError(context, NetErrorToPepperError(net_result));
|
| + return;
|
| + }
|
| + }
|
| + if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) {
|
| + int net_result = socket->SetReceiveBufferSize(rcvbuf_size_);
|
| + if (net_result != net::OK) {
|
| + SendBindError(context, NetErrorToPepperError(net_result));
|
| + return;
|
| + }
|
| + }
|
|
|
| - int32_t pp_result =
|
| - NetErrorToPepperError(socket->Listen(net::IPEndPoint(address, port)));
|
| - if (pp_result != PP_OK) {
|
| - SendBindError(context, pp_result);
|
| - return;
|
| + {
|
| + int net_result = socket->Bind(end_point);
|
| + if (net_result != net::OK) {
|
| + SendBindError(context, NetErrorToPepperError(net_result));
|
| + return;
|
| + }
|
| }
|
|
|
| net::IPEndPoint bound_address;
|
| - pp_result = NetErrorToPepperError(socket->GetLocalAddress(&bound_address));
|
| - if (pp_result != PP_OK) {
|
| - SendBindError(context, pp_result);
|
| - return;
|
| + {
|
| + int net_result = socket->GetLocalAddress(&bound_address);
|
| + if (net_result != net::OK) {
|
| + SendBindError(context, NetErrorToPepperError(net_result));
|
| + return;
|
| + }
|
| }
|
|
|
| PP_NetAddress_Private net_address = NetAddressPrivateImpl::kInvalidNetAddress;
|
| @@ -289,8 +357,6 @@ void PepperUDPSocketMessageFilter::DoBind(
|
| return;
|
| }
|
|
|
| - allow_address_reuse_ = false;
|
| - allow_broadcast_ = false;
|
| socket_.swap(socket);
|
| SendBindReply(context, PP_OK, net_address);
|
|
|
|
|