summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authorygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-31 08:55:28 +0000
committerygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-31 08:55:28 +0000
commit0addda9b12e46523d2f9967709d69dd1b5fb71e1 (patch)
treec533faf1fd41b8bbd343efe7a65634bfe181ecb4 /ppapi
parentae3e7bc278b7a13b9e5c36cdd5cda6a780f46096 (diff)
downloadchromium_src-0addda9b12e46523d2f9967709d69dd1b5fb71e1.zip
chromium_src-0addda9b12e46523d2f9967709d69dd1b5fb71e1.tar.gz
chromium_src-0addda9b12e46523d2f9967709d69dd1b5fb71e1.tar.bz2
AllowBroadcast() is exposed to NaCl.
BUG=136797 TEST=browser_tests:*.UDPSocketPrivate Review URL: https://chromiumcodereview.appspot.com/10735056 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@154407 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/api/private/ppb_udp_socket_private.idl33
-rw-r--r--ppapi/c/private/ppb_udp_socket_private.h65
-rw-r--r--ppapi/cpp/private/udp_socket_private.cc113
-rw-r--r--ppapi/cpp/private/udp_socket_private.h2
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_udp_socket_private_rpc_server.cc35
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc2
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.cc44
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.h1
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc21
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc17
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/ppb_udp_socket_private.srpc8
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h7
-rw-r--r--ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h6
-rw-r--r--ppapi/proxy/ppapi_messages.h8
-rw-r--r--ppapi/proxy/ppb_udp_socket_private_proxy.cc7
-rw-r--r--ppapi/shared_impl/private/udp_socket_private_impl.cc20
-rw-r--r--ppapi/shared_impl/private/udp_socket_private_impl.h3
-rw-r--r--ppapi/tests/test_udp_socket_private.cc177
-rw-r--r--ppapi/tests/test_udp_socket_private.h13
-rw-r--r--ppapi/thunk/interfaces_ppb_private.h2
-rw-r--r--ppapi/thunk/ppb_udp_socket_private_api.h2
-rw-r--r--ppapi/thunk/ppb_udp_socket_private_thunk.cc25
22 files changed, 533 insertions, 78 deletions
diff --git a/ppapi/api/private/ppb_udp_socket_private.idl b/ppapi/api/private/ppb_udp_socket_private.idl
index 083c33d..fc4fe1c 100644
--- a/ppapi/api/private/ppb_udp_socket_private.idl
+++ b/ppapi/api/private/ppb_udp_socket_private.idl
@@ -9,7 +9,24 @@
label Chrome {
M17 = 0.2,
- M19 = 0.3
+ M19 = 0.3,
+ M23 = 0.4
+};
+
+[assert_size(4)]
+enum PP_UDPSocketFeature_Private {
+ // Allow the socket to share the local address to which socket will
+ // be bound with other processes. Value's type should be
+ // PP_VARTYPE_BOOL.
+ PP_UDPSOCKETFEATURE_ADDRESS_REUSE = 0,
+
+ // Allow sending and receiving packets sent to and from broadcast
+ // addresses. Value's type should be PP_VARTYPE_BOOL.
+ PP_UDPSOCKETFEATURE_BROADCAST = 1,
+
+ // Special value for counting the number of available
+ // features. Should not be passed to SetSocketFeature().
+ PP_UDPSOCKETFEATURE_COUNT = 2
};
interface PPB_UDPSocket_Private {
@@ -23,6 +40,20 @@ interface PPB_UDPSocket_Private {
*/
PP_Bool IsUDPSocket([in] PP_Resource resource_id);
+ /**
+ * Sets a socket feature to |udp_socket|. Should be called before
+ * Bind(). Possible values for |name|, |value| and |value|'s type
+ * are described in PP_UDPSocketFeature_Private description. If no
+ * error occurs, returns PP_OK. Otherwise, returns
+ * PP_ERROR_BADRESOURCE (if bad |udp_socket| provided),
+ * PP_ERROR_BADARGUMENT (if bad name/value/value's type provided)
+ * or PP_ERROR_FAILED in the case of internal errors.
+ */
+ [version=0.4]
+ int32_t SetSocketFeature([in] PP_Resource udp_socket,
+ [in] PP_UDPSocketFeature_Private name,
+ [in] PP_Var value);
+
/* Creates a socket and binds to the address given by |addr|. */
int32_t Bind([in] PP_Resource udp_socket,
[in] PP_NetAddress_Private addr,
diff --git a/ppapi/c/private/ppb_udp_socket_private.h b/ppapi/c/private/ppb_udp_socket_private.h
index 047be46..27770b1 100644
--- a/ppapi/c/private/ppb_udp_socket_private.h
+++ b/ppapi/c/private/ppb_udp_socket_private.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From private/ppb_udp_socket_private.idl modified Wed Feb 8 18:02:19 2012. */
+/* From private/ppb_udp_socket_private.idl modified Thu Aug 23 12:32:12 2012. */
#ifndef PPAPI_C_PRIVATE_PPB_UDP_SOCKET_PRIVATE_H_
#define PPAPI_C_PRIVATE_PPB_UDP_SOCKET_PRIVATE_H_
@@ -14,11 +14,13 @@
#include "ppapi/c/pp_macros.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/pp_var.h"
#include "ppapi/c/private/ppb_net_address_private.h"
#define PPB_UDPSOCKET_PRIVATE_INTERFACE_0_2 "PPB_UDPSocket_Private;0.2"
#define PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3 "PPB_UDPSocket_Private;0.3"
-#define PPB_UDPSOCKET_PRIVATE_INTERFACE PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3
+#define PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4 "PPB_UDPSocket_Private;0.4"
+#define PPB_UDPSOCKET_PRIVATE_INTERFACE PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4
/**
* @file
@@ -27,10 +29,31 @@
/**
+ * @addtogroup Enums
+ * @{
+ */
+typedef enum {
+ /* Allow the socket to share the local address to which socket will
+ * be bound with other processes. Value's type should be
+ * PP_VARTYPE_BOOL. */
+ PP_UDPSOCKETFEATURE_ADDRESS_REUSE = 0,
+ /* Allow sending and receiving packets sent to and from broadcast
+ * addresses. Value's type should be PP_VARTYPE_BOOL. */
+ PP_UDPSOCKETFEATURE_BROADCAST = 1,
+ /* Special value for counting the number of available
+ * features. Should not be passed to SetSocketFeature(). */
+ PP_UDPSOCKETFEATURE_COUNT = 2
+} PP_UDPSocketFeature_Private;
+PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_UDPSocketFeature_Private, 4);
+/**
+ * @}
+ */
+
+/**
* @addtogroup Interfaces
* @{
*/
-struct PPB_UDPSocket_Private_0_3 {
+struct PPB_UDPSocket_Private_0_4 {
/**
* Creates a UDP socket resource.
*/
@@ -39,6 +62,18 @@ struct PPB_UDPSocket_Private_0_3 {
* Determines if a given resource is a UDP socket.
*/
PP_Bool (*IsUDPSocket)(PP_Resource resource_id);
+ /**
+ * Sets a socket feature to |udp_socket|. Should be called before
+ * Bind(). Possible values for |name|, |value| and |value|'s type
+ * are described in PP_UDPSocketFeature_Private description. If no
+ * error occurs, returns PP_OK. Otherwise, returns
+ * PP_ERROR_BADRESOURCE (if bad |udp_socket| provided),
+ * PP_ERROR_BADARGUMENT (if bad name/value/value's type provided)
+ * or PP_ERROR_FAILED in the case of internal errors.
+ */
+ int32_t (*SetSocketFeature)(PP_Resource udp_socket,
+ PP_UDPSocketFeature_Private name,
+ struct PP_Var value);
/* Creates a socket and binds to the address given by |addr|. */
int32_t (*Bind)(PP_Resource udp_socket,
const struct PP_NetAddress_Private* addr,
@@ -76,7 +111,7 @@ struct PPB_UDPSocket_Private_0_3 {
void (*Close)(PP_Resource udp_socket);
};
-typedef struct PPB_UDPSocket_Private_0_3 PPB_UDPSocket_Private;
+typedef struct PPB_UDPSocket_Private_0_4 PPB_UDPSocket_Private;
struct PPB_UDPSocket_Private_0_2 {
PP_Resource (*Create)(PP_Instance instance_id);
@@ -97,6 +132,28 @@ struct PPB_UDPSocket_Private_0_2 {
struct PP_CompletionCallback callback);
void (*Close)(PP_Resource udp_socket);
};
+
+struct PPB_UDPSocket_Private_0_3 {
+ PP_Resource (*Create)(PP_Instance instance_id);
+ PP_Bool (*IsUDPSocket)(PP_Resource resource_id);
+ int32_t (*Bind)(PP_Resource udp_socket,
+ const struct PP_NetAddress_Private* addr,
+ struct PP_CompletionCallback callback);
+ PP_Bool (*GetBoundAddress)(PP_Resource udp_socket,
+ struct PP_NetAddress_Private* addr);
+ int32_t (*RecvFrom)(PP_Resource udp_socket,
+ char* buffer,
+ int32_t num_bytes,
+ struct PP_CompletionCallback callback);
+ PP_Bool (*GetRecvFromAddress)(PP_Resource udp_socket,
+ struct PP_NetAddress_Private* addr);
+ int32_t (*SendTo)(PP_Resource udp_socket,
+ const char* buffer,
+ int32_t num_bytes,
+ const struct PP_NetAddress_Private* addr,
+ struct PP_CompletionCallback callback);
+ void (*Close)(PP_Resource udp_socket);
+};
/**
* @}
*/
diff --git a/ppapi/cpp/private/udp_socket_private.cc b/ppapi/cpp/private/udp_socket_private.cc
index 135e87e..c100924 100644
--- a/ppapi/cpp/private/udp_socket_private.cc
+++ b/ppapi/cpp/private/udp_socket_private.cc
@@ -10,11 +10,16 @@
#include "ppapi/cpp/instance_handle.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/module_impl.h"
+#include "ppapi/cpp/var.h"
namespace pp {
namespace {
+template <> const char* interface_name<PPB_UDPSocket_Private_0_4>() {
+ return PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4;
+}
+
template <> const char* interface_name<PPB_UDPSocket_Private_0_3>() {
return PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3;
}
@@ -22,67 +27,111 @@ template <> const char* interface_name<PPB_UDPSocket_Private_0_3>() {
} // namespace
UDPSocketPrivate::UDPSocketPrivate(const InstanceHandle& instance) {
- if (has_interface<PPB_UDPSocket_Private_0_3>()) {
+ if (has_interface<PPB_UDPSocket_Private_0_4>()) {
+ PassRefFromConstructor(get_interface<PPB_UDPSocket_Private_0_4>()->Create(
+ instance.pp_instance()));
+ } else if (has_interface<PPB_UDPSocket_Private_0_3>()) {
PassRefFromConstructor(get_interface<PPB_UDPSocket_Private_0_3>()->Create(
- instance.pp_instance()));
+ instance.pp_instance()));
}
}
// static
bool UDPSocketPrivate::IsAvailable() {
- return has_interface<PPB_UDPSocket_Private_0_3>();
+ return has_interface<PPB_UDPSocket_Private_0_4>() ||
+ has_interface<PPB_UDPSocket_Private_0_3>();
+}
+
+int32_t UDPSocketPrivate::SetSocketFeature(PP_UDPSocketFeature_Private name,
+ const Var& value) {
+ if (has_interface<PPB_UDPSocket_Private_0_4>()) {
+ return get_interface<PPB_UDPSocket_Private_0_4>()->SetSocketFeature(
+ pp_resource(), name, value.pp_var());
+ }
+ return PP_ERROR_NOINTERFACE;
}
int32_t UDPSocketPrivate::Bind(const PP_NetAddress_Private* addr,
const CompletionCallback& callback) {
- if (!has_interface<PPB_UDPSocket_Private_0_3>())
- return PP_ERROR_NOINTERFACE;
- return get_interface<PPB_UDPSocket_Private_0_3>()->Bind(
- pp_resource(), addr, callback.pp_completion_callback());
+ if (has_interface<PPB_UDPSocket_Private_0_4>()) {
+ return get_interface<PPB_UDPSocket_Private_0_4>()->Bind(
+ pp_resource(), addr, callback.pp_completion_callback());
+ }
+ if (has_interface<PPB_UDPSocket_Private_0_3>()) {
+ return get_interface<PPB_UDPSocket_Private_0_3>()->Bind(
+ pp_resource(), addr, callback.pp_completion_callback());
+ }
+ return callback.MayForce(PP_ERROR_NOINTERFACE);
}
bool UDPSocketPrivate::GetBoundAddress(PP_NetAddress_Private* addr) {
- if (!has_interface<PPB_UDPSocket_Private_0_3>())
- return false;
-
- PP_Bool result = get_interface<PPB_UDPSocket_Private_0_3>()->GetBoundAddress(
- pp_resource(), addr);
- return PP_ToBool(result);
+ if (has_interface<PPB_UDPSocket_Private_0_4>()) {
+ PP_Bool result =
+ get_interface<PPB_UDPSocket_Private_0_4>()->GetBoundAddress(
+ pp_resource(), addr);
+ return PP_ToBool(result);
+ }
+ if (has_interface<PPB_UDPSocket_Private_0_3>()) {
+ PP_Bool result =
+ get_interface<PPB_UDPSocket_Private_0_3>()->GetBoundAddress(
+ pp_resource(), addr);
+ return PP_ToBool(result);
+ }
+ return false;
}
int32_t UDPSocketPrivate::RecvFrom(char* buffer,
int32_t num_bytes,
const CompletionCallback& callback) {
- if (!has_interface<PPB_UDPSocket_Private_0_3>())
- return PP_ERROR_NOINTERFACE;
- return get_interface<PPB_UDPSocket_Private_0_3>()->RecvFrom(
- pp_resource(), buffer, num_bytes, callback.pp_completion_callback());
+ if (has_interface<PPB_UDPSocket_Private_0_4>()) {
+ return get_interface<PPB_UDPSocket_Private_0_4>()->RecvFrom(
+ pp_resource(), buffer, num_bytes, callback.pp_completion_callback());
+ }
+ if (has_interface<PPB_UDPSocket_Private_0_3>()) {
+ return get_interface<PPB_UDPSocket_Private_0_3>()->RecvFrom(
+ pp_resource(), buffer, num_bytes, callback.pp_completion_callback());
+ }
+ return callback.MayForce(PP_ERROR_NOINTERFACE);
}
bool UDPSocketPrivate::GetRecvFromAddress(PP_NetAddress_Private* addr) {
- if (!has_interface<PPB_UDPSocket_Private_0_3>())
- return false;
-
- PP_Bool result =
- get_interface<PPB_UDPSocket_Private_0_3>()->GetRecvFromAddress(
- pp_resource(), addr);
- return PP_ToBool(result);
+ if (has_interface<PPB_UDPSocket_Private_0_4>()) {
+ PP_Bool result =
+ get_interface<PPB_UDPSocket_Private_0_4>()->GetRecvFromAddress(
+ pp_resource(), addr);
+ return PP_ToBool(result);
+ }
+ if (has_interface<PPB_UDPSocket_Private_0_3>()) {
+ PP_Bool result =
+ get_interface<PPB_UDPSocket_Private_0_3>()->GetRecvFromAddress(
+ pp_resource(), addr);
+ return PP_ToBool(result);
+ }
+ return false;
}
int32_t UDPSocketPrivate::SendTo(const char* buffer,
int32_t num_bytes,
const PP_NetAddress_Private* addr,
const CompletionCallback& callback) {
- if (!has_interface<PPB_UDPSocket_Private_0_3>())
- return PP_ERROR_NOINTERFACE;
- return get_interface<PPB_UDPSocket_Private_0_3>()->SendTo(
- pp_resource(), buffer, num_bytes, addr,
- callback.pp_completion_callback());
+ if (has_interface<PPB_UDPSocket_Private_0_4>()) {
+ return get_interface<PPB_UDPSocket_Private_0_4>()->SendTo(
+ pp_resource(), buffer, num_bytes, addr,
+ callback.pp_completion_callback());
+ }
+ if (has_interface<PPB_UDPSocket_Private_0_3>()) {
+ return get_interface<PPB_UDPSocket_Private_0_3>()->SendTo(
+ pp_resource(), buffer, num_bytes, addr,
+ callback.pp_completion_callback());
+ }
+ return callback.MayForce(PP_ERROR_NOINTERFACE);
}
void UDPSocketPrivate::Close() {
- if (!has_interface<PPB_UDPSocket_Private_0_3>())
- return;
- return get_interface<PPB_UDPSocket_Private_0_3>()->Close(pp_resource());
+ if (has_interface<PPB_UDPSocket_Private_0_4>())
+ return get_interface<PPB_UDPSocket_Private_0_4>()->Close(pp_resource());
+ if (has_interface<PPB_UDPSocket_Private_0_3>())
+ return get_interface<PPB_UDPSocket_Private_0_3>()->Close(pp_resource());
}
+
} // namespace pp
diff --git a/ppapi/cpp/private/udp_socket_private.h b/ppapi/cpp/private/udp_socket_private.h
index 5179e72..34e06a9 100644
--- a/ppapi/cpp/private/udp_socket_private.h
+++ b/ppapi/cpp/private/udp_socket_private.h
@@ -13,6 +13,7 @@ namespace pp {
class CompletionCallback;
class InstanceHandle;
+class Var;
class UDPSocketPrivate : public Resource {
public:
@@ -21,6 +22,7 @@ class UDPSocketPrivate : public Resource {
// Returns true if the required interface is available.
static bool IsAvailable();
+ int32_t SetSocketFeature(PP_UDPSocketFeature_Private name, const Var& value);
int32_t Bind(const PP_NetAddress_Private* addr,
const CompletionCallback& callback);
bool GetBoundAddress(PP_NetAddress_Private* addr);
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_udp_socket_private_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_udp_socket_private_rpc_server.cc
index 11bd80c..2137e5d 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_udp_socket_private_rpc_server.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/browser_ppb_udp_socket_private_rpc_server.cc
@@ -10,6 +10,7 @@
#include "native_client/src/include/nacl_macros.h"
#include "native_client/src/shared/ppapi_proxy/browser_callback.h"
#include "native_client/src/shared/ppapi_proxy/browser_globals.h"
+#include "native_client/src/shared/ppapi_proxy/object_serialize.h"
#include "native_client/src/shared/ppapi_proxy/utility.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
@@ -18,6 +19,7 @@
using ppapi_proxy::DebugPrintf;
using ppapi_proxy::DeleteRemoteCallbackInfo;
+using ppapi_proxy::DeserializeTo;
using ppapi_proxy::MakeRemoteCompletionCallback;
using ppapi_proxy::PPBUDPSocketPrivateInterface;
@@ -54,6 +56,39 @@ void PpbUDPSocketPrivateRpcServer::PPB_UDPSocket_Private_IsUDPSocket(
"is_udp_socket=%d\n", *is_udp_socket);
}
+void PpbUDPSocketPrivateRpcServer::PPB_UDPSocket_Private_SetSocketFeature(
+ NaClSrpcRpc* rpc,
+ NaClSrpcClosure* done,
+ // inputs
+ PP_Resource udp_socket,
+ int32_t name,
+ nacl_abi_size_t value_bytes, char* value,
+ // output
+ int32_t* pp_error) {
+ NaClSrpcClosureRunner runner(done);
+ rpc->result = NACL_SRPC_RESULT_APP_ERROR;
+
+ if (name < 0 || name >= PP_UDPSOCKETFEATURE_COUNT) {
+ *pp_error = PP_ERROR_BADARGUMENT;
+ rpc->result = NACL_SRPC_RESULT_OK;
+ return;
+ }
+
+ PP_Var pp_value = PP_MakeUndefined();
+ if (!DeserializeTo(value, value_bytes, 1, &pp_value))
+ return;
+
+ *pp_error = PPBUDPSocketPrivateInterface()->SetSocketFeature(
+ udp_socket,
+ static_cast<PP_UDPSocketFeature_Private>(name),
+ pp_value);
+
+ DebugPrintf("PPB_UDPSocket_Private::SetSocketFeature: "
+ "pp_error=%"NACL_PRId32"\n", *pp_error);
+
+ rpc->result = NACL_SRPC_RESULT_OK;
+}
+
void PpbUDPSocketPrivateRpcServer::PPB_UDPSocket_Private_Bind(
NaClSrpcRpc* rpc,
NaClSrpcClosure* done,
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc
index aa0e8a1..cb2f837 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb.cc
@@ -132,6 +132,8 @@ InterfaceMapElement interface_map[] = {
PluginUDPSocketPrivate::GetInterface0_2(), true },
{ PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3,
PluginUDPSocketPrivate::GetInterface0_3(), true },
+ { PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4,
+ PluginUDPSocketPrivate::GetInterface0_4(), true },
{ PPB_URLLOADER_INTERFACE, PluginURLLoader::GetInterface(), true },
{ PPB_URLREQUESTINFO_INTERFACE, PluginURLRequestInfo::GetInterface(), true },
{ PPB_URLRESPONSEINFO_INTERFACE, PluginURLResponseInfo::GetInterface(),
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.cc b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.cc
index f38dcc0..49bde4c 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.cc
@@ -5,8 +5,11 @@
#include "native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.h"
#include <string.h>
+
#include "native_client/src/include/nacl_macros.h"
+#include "native_client/src/include/nacl_scoped_ptr.h"
#include "native_client/src/include/portability.h"
+#include "native_client/src/shared/ppapi_proxy/object_serialize.h"
#include "native_client/src/shared/ppapi_proxy/plugin_callback.h"
#include "native_client/src/shared/ppapi_proxy/plugin_globals.h"
#include "native_client/src/shared/ppapi_proxy/utility.h"
@@ -57,6 +60,32 @@ PP_Bool IsUDPSocket(PP_Resource resource_id) {
return PP_FALSE;
}
+int32_t SetSocketFeature(PP_Resource udp_socket,
+ PP_UDPSocketFeature_Private name,
+ struct PP_Var value) {
+ DebugPrintf("PPB_UDPSocket_Private::SetSocketFeature: ",
+ "udp_socket=%"NACL_PRId32"\n", udp_socket);
+
+ nacl_abi_size_t value_size;
+ nacl::scoped_array<char> value_bytes(Serialize(&value, 1, &value_size));
+
+ int32_t pp_error = PP_ERROR_FAILED;
+ NaClSrpcError srpc_result =
+ PpbUDPSocketPrivateRpcClient::PPB_UDPSocket_Private_SetSocketFeature(
+ GetMainSrpcChannel(),
+ udp_socket,
+ name,
+ value_size, value_bytes.get(),
+ &pp_error);
+
+ DebugPrintf("PPB_UDPSocket_Private::SetSocketFeature: %s\n",
+ NaClSrpcErrorString(srpc_result));
+
+ if (srpc_result != NACL_SRPC_RESULT_OK)
+ pp_error = PP_ERROR_FAILED;
+ return pp_error;
+}
+
int32_t Bind(PP_Resource udp_socket, const struct PP_NetAddress_Private* addr,
struct PP_CompletionCallback callback) {
DebugPrintf("PPB_UDPSocket_Private::Bind: "
@@ -248,4 +277,19 @@ const PPB_UDPSocket_Private_0_3* PluginUDPSocketPrivate::GetInterface0_3() {
return &udpsocket_private_interface;
}
+const PPB_UDPSocket_Private_0_4* PluginUDPSocketPrivate::GetInterface0_4() {
+ static const PPB_UDPSocket_Private_0_4 udpsocket_private_interface = {
+ Create,
+ IsUDPSocket,
+ SetSocketFeature,
+ Bind,
+ GetBoundAddress,
+ RecvFrom,
+ GetRecvFromAddress,
+ SendTo,
+ Close
+ };
+ return &udpsocket_private_interface;
+}
+
} // namespace ppapi_proxy
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.h b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.h
index 7e87382..4f9287e 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.h
+++ b/ppapi/native_client/src/shared/ppapi_proxy/plugin_ppb_udp_socket_private.h
@@ -15,6 +15,7 @@ class PluginUDPSocketPrivate {
public:
static const PPB_UDPSocket_Private_0_2* GetInterface0_2();
static const PPB_UDPSocket_Private_0_3* GetInterface0_3();
+ static const PPB_UDPSocket_Private_0_4* GetInterface0_4();
private:
NACL_DISALLOW_COPY_AND_ASSIGN(PluginUDPSocketPrivate);
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc
index 45f7933..ac50015 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_client.cc
@@ -2797,6 +2797,27 @@ NaClSrpcError PpbUDPSocketPrivateRpcClient::PPB_UDPSocket_Private_IsUDPSocket(
return retval;
}
+NaClSrpcError PpbUDPSocketPrivateRpcClient::PPB_UDPSocket_Private_SetSocketFeature(
+ NaClSrpcChannel* channel,
+ PP_Resource udp_socket,
+ int32_t name,
+ nacl_abi_size_t value_bytes, char* value,
+ int32_t* pp_error) {
+ VCHECK(ppapi_proxy::PPBCoreInterface()->IsMainThread(),
+ ("%s: PPAPI calls are not supported off the main thread\n",
+ __FUNCTION__));
+ NaClSrpcError retval;
+ retval = NaClSrpcInvokeBySignature(
+ channel,
+ "PPB_UDPSocket_Private_SetSocketFeature:iiC:i",
+ udp_socket,
+ name,
+ value_bytes, value,
+ pp_error
+ );
+ return retval;
+}
+
NaClSrpcError PpbUDPSocketPrivateRpcClient::PPB_UDPSocket_Private_Bind(
NaClSrpcChannel* channel,
PP_Resource udp_socket,
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc
index 10be251..da42e3d 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_rpc_server.cc
@@ -2234,6 +2234,22 @@ static void PPB_UDPSocket_Private_IsUDPSocketDispatcher(
);
}
+static void PPB_UDPSocket_Private_SetSocketFeatureDispatcher(
+ NaClSrpcRpc* rpc,
+ NaClSrpcArg** inputs,
+ NaClSrpcArg** outputs,
+ NaClSrpcClosure* done
+) {
+ PpbUDPSocketPrivateRpcServer::PPB_UDPSocket_Private_SetSocketFeature(
+ rpc,
+ done,
+ inputs[0]->u.ival,
+ inputs[1]->u.ival,
+ inputs[2]->u.count, inputs[2]->arrays.carr,
+ &(outputs[0]->u.ival)
+ );
+}
+
static void PPB_UDPSocket_Private_BindDispatcher(
NaClSrpcRpc* rpc,
NaClSrpcArg** inputs,
@@ -2985,6 +3001,7 @@ NaClSrpcHandlerDesc PpbRpcs::srpc_methods[] = {
{ "PPB_Testing_GetDocumentURL:i:CC", PPB_Testing_GetDocumentURLDispatcher },
{ "PPB_UDPSocket_Private_Create:i:i", PPB_UDPSocket_Private_CreateDispatcher },
{ "PPB_UDPSocket_Private_IsUDPSocket:i:i", PPB_UDPSocket_Private_IsUDPSocketDispatcher },
+ { "PPB_UDPSocket_Private_SetSocketFeature:iiC:i", PPB_UDPSocket_Private_SetSocketFeatureDispatcher },
{ "PPB_UDPSocket_Private_Bind:iCi:i", PPB_UDPSocket_Private_BindDispatcher },
{ "PPB_UDPSocket_Private_GetBoundAddress:i:Ci", PPB_UDPSocket_Private_GetBoundAddressDispatcher },
{ "PPB_UDPSocket_Private_RecvFrom:iii:Ci", PPB_UDPSocket_Private_RecvFromDispatcher },
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/ppb_udp_socket_private.srpc b/ppapi/native_client/src/shared/ppapi_proxy/ppb_udp_socket_private.srpc
index 3e5a27b..395012c7 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/ppb_udp_socket_private.srpc
+++ b/ppapi/native_client/src/shared/ppapi_proxy/ppb_udp_socket_private.srpc
@@ -20,6 +20,14 @@
'outputs': [['is_udp_socket_private', 'int32_t'], # PP_Bool
]
},
+ {'name': 'PPB_UDPSocket_Private_SetSocketFeature',
+ 'inputs': [['udp_socket', 'PP_Resource'], # PP_Resource
+ ['name', 'int32_t'], # PP_UDPSocketFeature_Private
+ ['value', 'char[]'], # PP_Var
+ ],
+ 'outputs': [['pp_error', 'int32_t'],
+ ]
+ },
{'name': 'PPB_UDPSocket_Private_Bind',
'inputs': [['udp_socket', 'PP_Resource'], # PP_Resource
['addr', 'char[]'], # PP_NetAddress_Private*
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h b/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h
index cf9c614..028ac86 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h
+++ b/ppapi/native_client/src/shared/ppapi_proxy/trusted/srpcgen/ppb_rpc.h
@@ -1137,6 +1137,13 @@ class PpbUDPSocketPrivateRpcServer {
NaClSrpcClosure* done,
PP_Resource resource_id,
int32_t* is_udp_socket_private);
+ static void PPB_UDPSocket_Private_SetSocketFeature(
+ NaClSrpcRpc* rpc,
+ NaClSrpcClosure* done,
+ PP_Resource udp_socket,
+ int32_t name,
+ nacl_abi_size_t value_bytes, char* value,
+ int32_t* pp_error);
static void PPB_UDPSocket_Private_Bind(
NaClSrpcRpc* rpc,
NaClSrpcClosure* done,
diff --git a/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h b/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h
index 54f5cb2..e4b6644 100644
--- a/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h
+++ b/ppapi/native_client/src/shared/ppapi_proxy/untrusted/srpcgen/ppb_rpc.h
@@ -992,6 +992,12 @@ class PpbUDPSocketPrivateRpcClient {
NaClSrpcChannel* channel,
PP_Resource resource_id,
int32_t* is_udp_socket_private);
+ static NaClSrpcError PPB_UDPSocket_Private_SetSocketFeature(
+ NaClSrpcChannel* channel,
+ PP_Resource udp_socket,
+ int32_t name,
+ nacl_abi_size_t value_bytes, char* value,
+ int32_t* pp_error);
static NaClSrpcError PPB_UDPSocket_Private_Bind(
NaClSrpcChannel* channel,
PP_Resource udp_socket,
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index b1f460b..070d3c3 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -35,6 +35,7 @@
#include "ppapi/c/private/ppb_host_resolver_private.h"
#include "ppapi/c/private/ppb_net_address_private.h"
#include "ppapi/c/private/ppb_tcp_socket_private.h"
+#include "ppapi/c/private/ppb_udp_socket_private.h"
#include "ppapi/c/private/ppp_flash_browser_operations.h"
#include "ppapi/proxy/ppapi_param_traits.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
@@ -63,8 +64,8 @@ IPC_ENUM_TRAITS(PP_FlashSetting)
IPC_ENUM_TRAITS(PP_InputEvent_MouseButton)
IPC_ENUM_TRAITS(PP_InputEvent_Type)
IPC_ENUM_TRAITS(PP_NetAddressFamily_Private)
-IPC_ENUM_TRAITS(PP_NetworkListType_Private)
IPC_ENUM_TRAITS(PP_NetworkListState_Private)
+IPC_ENUM_TRAITS(PP_NetworkListType_Private)
IPC_ENUM_TRAITS(PP_PrintOrientation_Dev)
IPC_ENUM_TRAITS(PP_PrintOutputFormat_Dev)
IPC_ENUM_TRAITS(PP_PrintScalingOption_Dev)
@@ -1449,6 +1450,11 @@ IPC_SYNC_MESSAGE_CONTROL2_1(PpapiHostMsg_PPBUDPSocket_Create,
int32 /* routing_id */,
uint32 /* plugin_dispatcher_id */,
uint32 /* socket_id */)
+IPC_MESSAGE_CONTROL4(PpapiHostMsg_PPBUDPSocket_SetBoolSocketFeature,
+ int32 /* routing_id */,
+ uint32 /* socket_id */,
+ int32_t /* name */,
+ bool /* value */)
IPC_MESSAGE_CONTROL3(PpapiHostMsg_PPBUDPSocket_Bind,
int32 /* routing_id */,
uint32 /* socket_id */,
diff --git a/ppapi/proxy/ppb_udp_socket_private_proxy.cc b/ppapi/proxy/ppb_udp_socket_private_proxy.cc
index 1e3a002..9b1184f 100644
--- a/ppapi/proxy/ppb_udp_socket_private_proxy.cc
+++ b/ppapi/proxy/ppb_udp_socket_private_proxy.cc
@@ -7,6 +7,7 @@
#include <map>
#include "base/logging.h"
+#include "ppapi/c/private/ppb_udp_socket_private.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/plugin_proxy_delegate.h"
@@ -29,6 +30,7 @@ class UDPSocket : public UDPSocketPrivateImpl {
UDPSocket(const HostResource& resource, uint32 socket_id);
virtual ~UDPSocket();
+ virtual void SendBoolSocketFeature(int32_t name, bool value) OVERRIDE;
virtual void SendBind(const PP_NetAddress_Private& addr) OVERRIDE;
virtual void SendRecvFrom(int32_t num_bytes) OVERRIDE;
virtual void SendSendTo(const std::string& data,
@@ -53,6 +55,11 @@ UDPSocket::~UDPSocket() {
Close();
}
+void UDPSocket::SendBoolSocketFeature(int32_t name, bool value) {
+ SendToBrowser(new PpapiHostMsg_PPBUDPSocket_SetBoolSocketFeature(
+ API_ID_PPB_UDPSOCKET_PRIVATE, socket_id_, name, value));
+}
+
void UDPSocket::SendBind(const PP_NetAddress_Private& addr) {
SendToBrowser(new PpapiHostMsg_PPBUDPSocket_Bind(
API_ID_PPB_UDPSOCKET_PRIVATE, socket_id_, addr));
diff --git a/ppapi/shared_impl/private/udp_socket_private_impl.cc b/ppapi/shared_impl/private/udp_socket_private_impl.cc
index 9b509e1..d3e94c1 100644
--- a/ppapi/shared_impl/private/udp_socket_private_impl.cc
+++ b/ppapi/shared_impl/private/udp_socket_private_impl.cc
@@ -12,6 +12,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop.h"
+#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
@@ -40,6 +41,25 @@ UDPSocketPrivateImpl::AsPPB_UDPSocket_Private_API() {
return this;
}
+int32_t UDPSocketPrivateImpl::SetSocketFeature(PP_UDPSocketFeature_Private name,
+ PP_Var value) {
+ if (bound_ || closed_)
+ return PP_ERROR_FAILED;
+
+ switch (name) {
+ case PP_UDPSOCKETFEATURE_ADDRESS_REUSE:
+ case PP_UDPSOCKETFEATURE_BROADCAST:
+ if (value.type != PP_VARTYPE_BOOL)
+ return PP_ERROR_BADARGUMENT;
+ SendBoolSocketFeature(static_cast<int32_t>(name),
+ PP_ToBool(value.value.as_bool));
+ break;
+ default:
+ return PP_ERROR_BADARGUMENT;
+ }
+ return PP_OK;
+}
+
int32_t UDPSocketPrivateImpl::Bind(const PP_NetAddress_Private* addr,
scoped_refptr<TrackedCallback> callback) {
if (!addr)
diff --git a/ppapi/shared_impl/private/udp_socket_private_impl.h b/ppapi/shared_impl/private/udp_socket_private_impl.h
index 36d51ca..e8e3cb2 100644
--- a/ppapi/shared_impl/private/udp_socket_private_impl.h
+++ b/ppapi/shared_impl/private/udp_socket_private_impl.h
@@ -40,6 +40,8 @@ class PPAPI_SHARED_EXPORT UDPSocketPrivateImpl
virtual PPB_UDPSocket_Private_API* AsPPB_UDPSocket_Private_API() OVERRIDE;
// PPB_UDPSocket_Private_API implementation.
+ virtual int32_t SetSocketFeature(PP_UDPSocketFeature_Private name,
+ PP_Var value) OVERRIDE;
virtual int32_t Bind(const PP_NetAddress_Private* addr,
scoped_refptr<TrackedCallback> callback) OVERRIDE;
virtual PP_Bool GetBoundAddress(PP_NetAddress_Private* addr) OVERRIDE;
@@ -63,6 +65,7 @@ class PPAPI_SHARED_EXPORT UDPSocketPrivateImpl
// Send functions that need to be implemented differently for
// the proxied and non-proxied derived classes.
+ virtual void SendBoolSocketFeature(int32_t name, bool value) = 0;
virtual void SendBind(const PP_NetAddress_Private& addr) = 0;
virtual void SendRecvFrom(int32_t num_bytes) = 0;
virtual void SendSendTo(const std::string& buffer,
diff --git a/ppapi/tests/test_udp_socket_private.cc b/ppapi/tests/test_udp_socket_private.cc
index 6251f76..4680ff2 100644
--- a/ppapi/tests/test_udp_socket_private.cc
+++ b/ppapi/tests/test_udp_socket_private.cc
@@ -3,10 +3,12 @@
// found in the LICENSE file.
#include <cstring>
+#include <vector>
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/private/net_address_private.h"
#include "ppapi/cpp/private/tcp_socket_private.h"
+#include "ppapi/cpp/var.h"
#include "ppapi/tests/test_udp_socket_private.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"
@@ -54,6 +56,8 @@ bool TestUDPSocketPrivate::Init() {
void TestUDPSocketPrivate::RunTests(const std::string& filter) {
RUN_TEST_FORCEASYNC_AND_NOT(Connect, filter);
RUN_TEST_FORCEASYNC_AND_NOT(ConnectFailure, filter);
+ RUN_TEST_FORCEASYNC_AND_NOT(Broadcast, filter);
+ RUN_TEST_FORCEASYNC_AND_NOT(SetSocketFeatureErrors, filter);
}
std::string TestUDPSocketPrivate::GetLocalAddress(
@@ -73,8 +77,36 @@ std::string TestUDPSocketPrivate::GetLocalAddress(
PASS();
}
+std::string TestUDPSocketPrivate::SetBroadcastOptions(
+ pp::UDPSocketPrivate* socket) {
+ int32_t rv = socket->SetSocketFeature(PP_UDPSOCKETFEATURE_ADDRESS_REUSE,
+ pp::Var(true));
+ if (rv != PP_OK)
+ return ReportError("PPB_UDPSocket_Private::SetSocketFeature", rv);
+
+ rv = socket->SetSocketFeature(PP_UDPSOCKETFEATURE_BROADCAST, pp::Var(true));
+ if (rv != PP_OK)
+ return ReportError("PPB_UDPSocket_Private::SetSocketFeature", rv);
+
+ PASS();
+}
+
std::string TestUDPSocketPrivate::BindUDPSocket(
pp::UDPSocketPrivate* socket,
+ PP_NetAddress_Private* address) {
+ TestCompletionCallback callback(instance_->pp_instance(), force_async_);
+ int32_t rv = socket->Bind(address, callback);
+ if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_UDPSocket_Private::Bind force_async", rv);
+ if (rv == PP_OK_COMPLETIONPENDING)
+ rv = callback.WaitForResult();
+ if (rv != PP_OK)
+ return ReportError("PPB_UDPSocket_Private::Bind", rv);
+ PASS();
+}
+
+std::string TestUDPSocketPrivate::LookupPortAndBindUDPSocket(
+ pp::UDPSocketPrivate* socket,
PP_NetAddress_Private *address) {
PP_NetAddress_Private base_address;
ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address));
@@ -83,13 +115,7 @@ std::string TestUDPSocketPrivate::BindUDPSocket(
for (uint16_t port = kPortScanFrom; port < kPortScanTo; ++port) {
if (!pp::NetAddressPrivate::ReplacePort(base_address, port, address))
return "PPB_NetAddress_Private::ReplacePort: Failed";
- TestCompletionCallback callback(instance_->pp_instance(), force_async_);
- int32_t rv = socket->Bind(address, callback);
- if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
- return ReportError("PPB_UDPSocket_Private::Bind force_async", rv);
- if (rv == PP_OK_COMPLETIONPENDING)
- rv = callback.WaitForResult();
- if (rv == PP_OK) {
+ if (BindUDPSocket(socket, address).empty()) {
is_free_port_found = true;
break;
}
@@ -117,53 +143,67 @@ std::string TestUDPSocketPrivate::BindUDPSocketFailure(
PASS();
}
+std::string TestUDPSocketPrivate::ReadSocket(pp::UDPSocketPrivate* socket,
+ PP_NetAddress_Private* address,
+ size_t size,
+ std::string* message) {
+ std::vector<char> buffer(size);
+ TestCompletionCallback callback(instance_->pp_instance(), force_async_);
+ int32_t rv = socket->RecvFrom(&buffer[0], size, callback);
+ if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_UDPSocket_Private::RecvFrom force_async", rv);
+ if (rv == PP_OK_COMPLETIONPENDING)
+ rv = callback.WaitForResult();
+ if (rv < 0 || size != static_cast<size_t>(rv))
+ return ReportError("PPB_UDPSocket_Private::RecvFrom", rv);
+ message->assign(buffer.begin(), buffer.end());
+ PASS();
+}
+
+std::string TestUDPSocketPrivate::PassMessage(pp::UDPSocketPrivate* target,
+ pp::UDPSocketPrivate* source,
+ PP_NetAddress_Private* address,
+ const std::string& message) {
+ TestCompletionCallback callback(instance_->pp_instance(), force_async_);
+ int32_t rv = source->SendTo(message.c_str(), message.size(), address,
+ callback);
+ if (force_async_ && rv != PP_OK_COMPLETIONPENDING)
+ return ReportError("PPB_UDPSocket_Private::SendTo force_async", rv);
+
+ std::string str;
+ ASSERT_SUBTEST_SUCCESS(ReadSocket(target, address, message.size(), &str));
+
+ if (rv == PP_OK_COMPLETIONPENDING)
+ rv = callback.WaitForResult();
+ if (rv < 0 || message.size() != static_cast<size_t>(rv))
+ return ReportError("PPB_UDPSocket_Private::SendTo", rv);
+
+ ASSERT_EQ(message, str);
+ PASS();
+}
+
std::string TestUDPSocketPrivate::TestConnect() {
pp::UDPSocketPrivate server_socket(instance_), client_socket(instance_);
PP_NetAddress_Private server_address, client_address;
- ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server_socket, &server_address));
- ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&client_socket, &client_address));
-
- static const char* const kMessage =
- "Simple message that will be sent via UDP";
- static const size_t kMessageBufferSize = 1024;
- char message_buffer[kMessageBufferSize];
-
- TestCompletionCallback write_callback(instance_->pp_instance(), force_async_);
- int32_t write_rv = client_socket.SendTo(kMessage, strlen(kMessage),
- &server_address,
- write_callback);
- if (force_async_ && write_rv != PP_OK_COMPLETIONPENDING)
- return ReportError("PPB_UDPSocket_Private::SendTo force_async", write_rv);
-
- TestCompletionCallback read_callback(instance_->pp_instance(), force_async_);
- int32_t read_rv = server_socket.RecvFrom(message_buffer, strlen(kMessage),
- read_callback);
- if (force_async_ && read_rv != PP_OK_COMPLETIONPENDING)
- return ReportError("PPB_UDPSocket_Private::RecvFrom force_async", read_rv);
-
- if (read_rv == PP_OK_COMPLETIONPENDING)
- read_rv = read_callback.WaitForResult();
- if (read_rv < 0 || strlen(kMessage) != static_cast<size_t>(read_rv))
- return ReportError("PPB_UDPSocket_Private::RecvFrom", read_rv);
-
- if (write_rv == PP_OK_COMPLETIONPENDING)
- write_rv = write_callback.WaitForResult();
- if (write_rv < 0 || strlen(kMessage) != static_cast<size_t>(write_rv))
- return ReportError("PPB_UDPSocket_Private::SendTo", write_rv);
-
+ ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&server_socket,
+ &server_address));
+ ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket,
+ &client_address));
+ const std::string message = "Simple message that will be sent via UDP";
+ ASSERT_SUBTEST_SUCCESS(PassMessage(&server_socket, &client_socket,
+ &server_address,
+ message));
PP_NetAddress_Private recv_from_address;
ASSERT_TRUE(server_socket.GetRecvFromAddress(&recv_from_address));
ASSERT_TRUE(pp::NetAddressPrivate::AreEqual(recv_from_address,
client_address));
- ASSERT_EQ(0, strncmp(kMessage, message_buffer, strlen(kMessage)));
server_socket.Close();
client_socket.Close();
if (server_socket.GetBoundAddress(&server_address))
return "PPB_UDPSocket_Private::GetBoundAddress: expected Failure";
-
PASS();
}
@@ -177,3 +217,60 @@ std::string TestUDPSocketPrivate::TestConnectFailure() {
PASS();
}
+
+std::string TestUDPSocketPrivate::TestBroadcast() {
+ const uint8_t broadcast_ip[4] = { 0xff, 0xff, 0xff, 0xff };
+
+ pp::UDPSocketPrivate server1(instance_), server2(instance_);
+
+ ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&server1));
+ ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&server2));
+ PP_NetAddress_Private server_address;
+ ASSERT_TRUE(pp::NetAddressPrivate::GetAnyAddress(false, &server_address));
+ ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server1, &server_address));
+ // Fill port field of |server_address|.
+ ASSERT_TRUE(server1.GetBoundAddress(&server_address));
+ ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server2, &server_address));
+
+ const uint16_t port = pp::NetAddressPrivate::GetPort(server_address);
+ PP_NetAddress_Private broadcast_address;
+ ASSERT_TRUE(pp::NetAddressPrivate::CreateFromIPv4Address(
+ broadcast_ip, port, &broadcast_address));
+
+ std::string message;
+ const std::string first_message = "first message";
+ const std::string second_message = "second_message";
+
+ ASSERT_SUBTEST_SUCCESS(PassMessage(&server1, &server2,
+ &broadcast_address,
+ first_message));
+ // |first_message| also arrived to |server2|.
+ ASSERT_SUBTEST_SUCCESS(ReadSocket(&server2, &broadcast_address,
+ first_message.size(), &message));
+ ASSERT_EQ(first_message, message);
+
+ ASSERT_SUBTEST_SUCCESS(PassMessage(&server2, &server1,
+ &broadcast_address,
+ second_message));
+ // |second_message| also arrived to |server1|.
+ ASSERT_SUBTEST_SUCCESS(ReadSocket(&server1, &broadcast_address,
+ second_message.size(), &message));
+ ASSERT_EQ(second_message, message);
+
+ server1.Close();
+ server2.Close();
+ PASS();
+}
+
+std::string TestUDPSocketPrivate::TestSetSocketFeatureErrors() {
+ pp::UDPSocketPrivate socket(instance_);
+ // Try to pass incorrect feature name.
+ int32_t rv = socket.SetSocketFeature(PP_UDPSOCKETFEATURE_COUNT,
+ pp::Var(true));
+ ASSERT_EQ(PP_ERROR_BADARGUMENT, rv);
+
+ // Try to pass incorrect feature value's type.
+ rv = socket.SetSocketFeature(PP_UDPSOCKETFEATURE_ADDRESS_REUSE, pp::Var(1));
+ ASSERT_EQ(PP_ERROR_BADARGUMENT, rv);
+ PASS();
+}
diff --git a/ppapi/tests/test_udp_socket_private.h b/ppapi/tests/test_udp_socket_private.h
index a164842..e4a23c9 100644
--- a/ppapi/tests/test_udp_socket_private.h
+++ b/ppapi/tests/test_udp_socket_private.h
@@ -21,13 +21,26 @@ class TestUDPSocketPrivate : public TestCase {
private:
std::string GetLocalAddress(PP_NetAddress_Private* address);
+ std::string SetBroadcastOptions(pp::UDPSocketPrivate* socket);
std::string BindUDPSocket(pp::UDPSocketPrivate* socket,
PP_NetAddress_Private *address);
+ std::string LookupPortAndBindUDPSocket(pp::UDPSocketPrivate* socket,
+ PP_NetAddress_Private* address);
std::string BindUDPSocketFailure(pp::UDPSocketPrivate* socket,
PP_NetAddress_Private *address);
+ std::string ReadSocket(pp::UDPSocketPrivate* socket,
+ PP_NetAddress_Private* address,
+ size_t size,
+ std::string* message);
+ std::string PassMessage(pp::UDPSocketPrivate* target,
+ pp::UDPSocketPrivate* source,
+ PP_NetAddress_Private* address,
+ const std::string& message);
std::string TestConnect();
std::string TestConnectFailure();
+ std::string TestBroadcast();
+ std::string TestSetSocketFeatureErrors();
std::string host_;
uint16_t port_;
diff --git a/ppapi/thunk/interfaces_ppb_private.h b/ppapi/thunk/interfaces_ppb_private.h
index 144d64c..a3c800d 100644
--- a/ppapi/thunk/interfaces_ppb_private.h
+++ b/ppapi/thunk/interfaces_ppb_private.h
@@ -58,6 +58,8 @@ PROXIED_IFACE(PPB_UDPSocket_Private, PPB_UDPSOCKET_PRIVATE_INTERFACE_0_2,
PPB_UDPSocket_Private_0_2)
PROXIED_IFACE(PPB_UDPSocket_Private, PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3,
PPB_UDPSocket_Private_0_3)
+PROXIED_IFACE(PPB_UDPSocket_Private, PPB_UDPSOCKET_PRIVATE_INTERFACE_0_4,
+ PPB_UDPSocket_Private_0_4)
PROXIED_IFACE(PPB_X509Certificate_Private,
PPB_X509CERTIFICATE_PRIVATE_INTERFACE_0_1,
PPB_X509Certificate_Private_0_1)
diff --git a/ppapi/thunk/ppb_udp_socket_private_api.h b/ppapi/thunk/ppb_udp_socket_private_api.h
index 0b2a3c6..9c403a0 100644
--- a/ppapi/thunk/ppb_udp_socket_private_api.h
+++ b/ppapi/thunk/ppb_udp_socket_private_api.h
@@ -19,6 +19,8 @@ class PPAPI_THUNK_EXPORT PPB_UDPSocket_Private_API {
public:
virtual ~PPB_UDPSocket_Private_API() {}
+ virtual int32_t SetSocketFeature(PP_UDPSocketFeature_Private name,
+ PP_Var value) = 0;
virtual int32_t Bind(const PP_NetAddress_Private* addr,
scoped_refptr<TrackedCallback> callback) = 0;
virtual PP_Bool GetBoundAddress(PP_NetAddress_Private* addr) = 0;
diff --git a/ppapi/thunk/ppb_udp_socket_private_thunk.cc b/ppapi/thunk/ppb_udp_socket_private_thunk.cc
index bfd6e1c..a493666 100644
--- a/ppapi/thunk/ppb_udp_socket_private_thunk.cc
+++ b/ppapi/thunk/ppb_udp_socket_private_thunk.cc
@@ -30,6 +30,15 @@ PP_Bool IsUDPSocket(PP_Resource resource) {
return PP_FromBool(enter.succeeded());
}
+int32_t SetSocketFeature(PP_Resource udp_socket,
+ PP_UDPSocketFeature_Private name,
+ PP_Var value) {
+ EnterUDP enter(udp_socket, true);
+ if (enter.failed())
+ return PP_ERROR_BADRESOURCE;
+ return enter.object()->SetSocketFeature(name, value);
+}
+
int32_t Bind(PP_Resource udp_socket,
const PP_NetAddress_Private *addr,
PP_CompletionCallback callback) {
@@ -109,6 +118,18 @@ const PPB_UDPSocket_Private_0_3 g_ppb_udp_socket_thunk_0_3 = {
&Close
};
+const PPB_UDPSocket_Private_0_4 g_ppb_udp_socket_thunk_0_4 = {
+ &Create,
+ &IsUDPSocket,
+ &SetSocketFeature,
+ &Bind,
+ &GetBoundAddress,
+ &RecvFrom,
+ &GetRecvFromAddress,
+ &SendTo,
+ &Close
+};
+
} // namespace
const PPB_UDPSocket_Private_0_2* GetPPB_UDPSocket_Private_0_2_Thunk() {
@@ -119,5 +140,9 @@ const PPB_UDPSocket_Private_0_3* GetPPB_UDPSocket_Private_0_3_Thunk() {
return &g_ppb_udp_socket_thunk_0_3;
}
+const PPB_UDPSocket_Private_0_4* GetPPB_UDPSocket_Private_0_4_Thunk() {
+ return &g_ppb_udp_socket_thunk_0_4;
+}
+
} // namespace thunk
} // namespace ppapi