summaryrefslogtreecommitdiffstats
path: root/ppapi
diff options
context:
space:
mode:
authoreduardo.lima <eduardo.lima@intel.com>2015-03-13 08:40:21 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-13 15:41:01 +0000
commit8171d46410b1ea937b0ae59577b9b36ed151149a (patch)
tree24bb98ab89f255ac337f9d584de264f931570bf3 /ppapi
parentfe37dca5b311cf194493669f26ddee27d60cc667 (diff)
downloadchromium_src-8171d46410b1ea937b0ae59577b9b36ed151149a.zip
chromium_src-8171d46410b1ea937b0ae59577b9b36ed151149a.tar.gz
chromium_src-8171d46410b1ea937b0ae59577b9b36ed151149a.tar.bz2
Add support for multicast in PPB_UDPSocket API
This change introduces two new values to be used with SetOption(), to set up the behavior of the multicast packets: - PP_UDPSOCKET_OPTION_MULTICAST_LOOP (Boolean) Whether packets sent from the host to the multicast group will be looped back to the host or not. - PP_UDPSOCKET_OPTION_MULTICAST_TTL (Integer) Sets time-to-live of multicast packets sent to the multicast group. It also introduces two new functions JoinGroup() and LeaveGroup(), both of them expecting the address of the multicast group as specified by the PPB_NetAddress API. These two functions should only be called after the socket is bound. This CL adds specific test cases to browser_tests in order to exercise the different versions of the SetOption function. For this reason, the PPAPI UDPSocket tests were split into multiple tests, instead of a single one that enclosed all of them. This way we get clearer information about the results of each test. BUG=430939 TEST=browser_tests NOPRESUBMIT=true Signed-off-by: Eduardo Lima (Etrunko) <eduardo.lima@intel.com> Review URL: https://codereview.chromium.org/704133005 Cr-Commit-Position: refs/heads/master@{#320504}
Diffstat (limited to 'ppapi')
-rw-r--r--ppapi/api/ppb_udp_socket.idl84
-rw-r--r--ppapi/c/ppb_udp_socket.h86
-rw-r--r--ppapi/cpp/udp_socket.cc55
-rw-r--r--ppapi/cpp/udp_socket.h24
-rw-r--r--ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c75
-rw-r--r--ppapi/proxy/ppapi_messages.h8
-rw-r--r--ppapi/proxy/udp_socket_resource.cc37
-rw-r--r--ppapi/proxy/udp_socket_resource.h8
-rw-r--r--ppapi/proxy/udp_socket_resource_base.cc64
-rw-r--r--ppapi/proxy/udp_socket_resource_base.h8
-rw-r--r--ppapi/shared_impl/private/net_address_private_impl.cc6
-rw-r--r--ppapi/shared_impl/private/net_address_private_impl.h2
-rw-r--r--ppapi/tests/test_udp_socket.cc136
-rw-r--r--ppapi/tests/test_udp_socket.h19
-rw-r--r--ppapi/thunk/interfaces_ppb_public_dev_channel.h1
-rw-r--r--ppapi/thunk/ppb_udp_socket_api.h7
-rw-r--r--ppapi/thunk/ppb_udp_socket_thunk.cc97
17 files changed, 668 insertions, 49 deletions
diff --git a/ppapi/api/ppb_udp_socket.idl b/ppapi/api/ppb_udp_socket.idl
index 9f186f5..d4ceb11 100644
--- a/ppapi/api/ppb_udp_socket.idl
+++ b/ppapi/api/ppb_udp_socket.idl
@@ -7,9 +7,12 @@
* This file defines the <code>PPB_UDPSocket</code> interface.
*/
+[generate_thunk]
+
label Chrome {
M29 = 1.0,
- M41 = 1.1
+ M41 = 1.1,
+ [channel=dev] M43 = 1.2
};
/**
@@ -56,7 +59,28 @@ enum PP_UDPSocket_Option {
* size. Even if <code>SetOption()</code> succeeds, the browser doesn't
* guarantee it will conform to the size.
*/
- PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE = 3
+ PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE = 3,
+
+ /**
+ * Specifies whether the packets sent from the host to the multicast group
+ * should be looped back to the host or not. Value's type should be
+ * <code>PP_VARTYPE_BOOL</code>.
+ * This option can only be set before calling <code>Bind()</code>.
+ *
+ * This is only supported in version 1.2 of the API (Chrome 43) and later.
+ */
+ PP_UDPSOCKET_OPTION_MULTICAST_LOOP = 4,
+
+ /**
+ * Specifies the time-to-live for packets sent to the multicast group. The
+ * value should be within 0 to 255 range. The default value is 1 and means
+ * that packets will not be routed beyond the local network. Value's type
+ * should be <code>PP_VARTYPE_INT32</code>.
+ * This option can only be set before calling <code>Bind()</code>.
+ *
+ * This is only supported in version 1.2 of the API (Chrome 43) and later.
+ */
+ PP_UDPSOCKET_OPTION_MULTICAST_TTL = 5
};
/**
@@ -220,4 +244,60 @@ interface PPB_UDPSocket {
[in] PP_UDPSocket_Option name,
[in] PP_Var value,
[in] PP_CompletionCallback callback);
+
+ /**
+ * Sets a socket option on the UDP socket.
+ * Please see the <code>PP_UDPSocket_Option</code> description for option
+ * names, value types and allowed values.
+ *
+ * @param[in] udp_socket A <code>PP_Resource</code> corresponding to a UDP
+ * socket.
+ * @param[in] name The option to set.
+ * @param[in] value The option value to set.
+ * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
+ * completion.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ */
+ [version=1.2]
+ int32_t SetOption([in] PP_Resource udp_socket,
+ [in] PP_UDPSocket_Option name,
+ [in] PP_Var value,
+ [in] PP_CompletionCallback callback);
+
+ /**
+ * Joins the multicast group with address specified by <code>group</code>
+ * parameter, which is expected to be a <code>PPB_NetAddress</code> object.
+ *
+ * @param[in] udp_socket A <code>PP_Resource</code> corresponding to a UDP
+ * socket.
+ * @param[in] group A <code>PP_Resource</code> corresponding to the network
+ * address of the multicast group.
+ * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
+ * completion.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ */
+ [version=1.2]
+ int32_t JoinGroup([in] PP_Resource udp_socket,
+ [in] PP_Resource group,
+ [in] PP_CompletionCallback callback);
+
+ /**
+ * Leaves the multicast group with address specified by <code>group</code>
+ * parameter, which is expected to be a <code>PPB_NetAddress</code> object.
+ *
+ * @param[in] udp_socket A <code>PP_Resource</code> corresponding to a UDP
+ * socket.
+ * @param[in] group A <code>PP_Resource</code> corresponding to the network
+ * address of the multicast group.
+ * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
+ * completion.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ */
+ [version=1.2]
+ int32_t LeaveGroup([in] PP_Resource udp_socket,
+ [in] PP_Resource group,
+ [in] PP_CompletionCallback callback);
};
diff --git a/ppapi/c/ppb_udp_socket.h b/ppapi/c/ppb_udp_socket.h
index 17f349a..d25de17 100644
--- a/ppapi/c/ppb_udp_socket.h
+++ b/ppapi/c/ppb_udp_socket.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From ppb_udp_socket.idl modified Wed Jan 14 13:13:19 2015. */
+/* From ppb_udp_socket.idl modified Mon Mar 2 16:50:15 2015. */
#ifndef PPAPI_C_PPB_UDP_SOCKET_H_
#define PPAPI_C_PPB_UDP_SOCKET_H_
@@ -18,6 +18,7 @@
#define PPB_UDPSOCKET_INTERFACE_1_0 "PPB_UDPSocket;1.0"
#define PPB_UDPSOCKET_INTERFACE_1_1 "PPB_UDPSocket;1.1"
+#define PPB_UDPSOCKET_INTERFACE_1_2 "PPB_UDPSocket;1.2" /* dev */
#define PPB_UDPSOCKET_INTERFACE PPB_UDPSOCKET_INTERFACE_1_1
/**
@@ -70,7 +71,26 @@ typedef enum {
* size. Even if <code>SetOption()</code> succeeds, the browser doesn't
* guarantee it will conform to the size.
*/
- PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE = 3
+ PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE = 3,
+ /**
+ * Specifies whether the packets sent from the host to the multicast group
+ * should be looped back to the host or not. Value's type should be
+ * <code>PP_VARTYPE_BOOL</code>.
+ * This option can only be set before calling <code>Bind()</code>.
+ *
+ * This is only supported in version 1.2 of the API (Chrome 43) and later.
+ */
+ PP_UDPSOCKET_OPTION_MULTICAST_LOOP = 4,
+ /**
+ * Specifies the time-to-live for packets sent to the multicast group. The
+ * value should be within 0 to 255 range. The default value is 1 and means
+ * that packets will not be routed beyond the local network. Value's type
+ * should be <code>PP_VARTYPE_INT32</code>.
+ * This option can only be set before calling <code>Bind()</code>.
+ *
+ * This is only supported in version 1.2 of the API (Chrome 43) and later.
+ */
+ PP_UDPSOCKET_OPTION_MULTICAST_TTL = 5
} PP_UDPSocket_Option;
PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_UDPSocket_Option, 4);
/**
@@ -90,7 +110,7 @@ PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_UDPSocket_Option, 4);
* For more details about network communication permissions, please see:
* http://developer.chrome.com/apps/app_network.html
*/
-struct PPB_UDPSocket_1_1 {
+struct PPB_UDPSocket_1_2 { /* dev */
/**
* Creates a UDP socket resource.
*
@@ -215,10 +235,40 @@ struct PPB_UDPSocket_1_1 {
PP_UDPSocket_Option name,
struct PP_Var value,
struct PP_CompletionCallback callback);
+ /**
+ * Joins the multicast group with address specified by <code>group</code>
+ * parameter, which is expected to be a <code>PPB_NetAddress</code> object.
+ *
+ * @param[in] udp_socket A <code>PP_Resource</code> corresponding to a UDP
+ * socket.
+ * @param[in] group A <code>PP_Resource</code> corresponding to the network
+ * address of the multicast group.
+ * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
+ * completion.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ */
+ int32_t (*JoinGroup)(PP_Resource udp_socket,
+ PP_Resource group,
+ struct PP_CompletionCallback callback);
+ /**
+ * Leaves the multicast group with address specified by <code>group</code>
+ * parameter, which is expected to be a <code>PPB_NetAddress</code> object.
+ *
+ * @param[in] udp_socket A <code>PP_Resource</code> corresponding to a UDP
+ * socket.
+ * @param[in] group A <code>PP_Resource</code> corresponding to the network
+ * address of the multicast group.
+ * @param[in] callback A <code>PP_CompletionCallback</code> to be called upon
+ * completion.
+ *
+ * @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ */
+ int32_t (*LeaveGroup)(PP_Resource udp_socket,
+ PP_Resource group,
+ struct PP_CompletionCallback callback);
};
-typedef struct PPB_UDPSocket_1_1 PPB_UDPSocket;
-
struct PPB_UDPSocket_1_0 {
PP_Resource (*Create)(PP_Instance instance);
PP_Bool (*IsUDPSocket)(PP_Resource resource);
@@ -242,6 +292,32 @@ struct PPB_UDPSocket_1_0 {
struct PP_Var value,
struct PP_CompletionCallback callback);
};
+
+struct PPB_UDPSocket_1_1 {
+ PP_Resource (*Create)(PP_Instance instance);
+ PP_Bool (*IsUDPSocket)(PP_Resource resource);
+ int32_t (*Bind)(PP_Resource udp_socket,
+ PP_Resource addr,
+ struct PP_CompletionCallback callback);
+ PP_Resource (*GetBoundAddress)(PP_Resource udp_socket);
+ int32_t (*RecvFrom)(PP_Resource udp_socket,
+ char* buffer,
+ int32_t num_bytes,
+ PP_Resource* addr,
+ struct PP_CompletionCallback callback);
+ int32_t (*SendTo)(PP_Resource udp_socket,
+ const char* buffer,
+ int32_t num_bytes,
+ PP_Resource addr,
+ struct PP_CompletionCallback callback);
+ void (*Close)(PP_Resource udp_socket);
+ int32_t (*SetOption)(PP_Resource udp_socket,
+ PP_UDPSocket_Option name,
+ struct PP_Var value,
+ struct PP_CompletionCallback callback);
+};
+
+typedef struct PPB_UDPSocket_1_1 PPB_UDPSocket;
/**
* @}
*/
diff --git a/ppapi/cpp/udp_socket.cc b/ppapi/cpp/udp_socket.cc
index 2f8c505..19d2894 100644
--- a/ppapi/cpp/udp_socket.cc
+++ b/ppapi/cpp/udp_socket.cc
@@ -22,13 +22,20 @@ template <> const char* interface_name<PPB_UDPSocket_1_1>() {
return PPB_UDPSOCKET_INTERFACE_1_1;
}
+template <> const char* interface_name<PPB_UDPSocket_1_2>() {
+ return PPB_UDPSOCKET_INTERFACE_1_2;
+}
+
} // namespace
UDPSocket::UDPSocket() {
}
UDPSocket::UDPSocket(const InstanceHandle& instance) {
- if (has_interface<PPB_UDPSocket_1_1>()) {
+ if (has_interface<PPB_UDPSocket_1_2>()) {
+ PassRefFromConstructor(get_interface<PPB_UDPSocket_1_2>()->Create(
+ instance.pp_instance()));
+ } else if (has_interface<PPB_UDPSocket_1_1>()) {
PassRefFromConstructor(get_interface<PPB_UDPSocket_1_1>()->Create(
instance.pp_instance()));
} else if (has_interface<PPB_UDPSocket_1_0>()) {
@@ -54,12 +61,17 @@ UDPSocket& UDPSocket::operator=(const UDPSocket& other) {
// static
bool UDPSocket::IsAvailable() {
- return has_interface<PPB_UDPSocket_1_1>() ||
+ return has_interface<PPB_UDPSocket_1_2>() ||
+ has_interface<PPB_UDPSocket_1_1>() ||
has_interface<PPB_UDPSocket_1_0>();
}
int32_t UDPSocket::Bind(const NetAddress& addr,
const CompletionCallback& callback) {
+ if (has_interface<PPB_UDPSocket_1_2>()) {
+ return get_interface<PPB_UDPSocket_1_2>()->Bind(
+ pp_resource(), addr.pp_resource(), callback.pp_completion_callback());
+ }
if (has_interface<PPB_UDPSocket_1_1>()) {
return get_interface<PPB_UDPSocket_1_1>()->Bind(
pp_resource(), addr.pp_resource(), callback.pp_completion_callback());
@@ -72,6 +84,11 @@ int32_t UDPSocket::Bind(const NetAddress& addr,
}
NetAddress UDPSocket::GetBoundAddress() {
+ if (has_interface<PPB_UDPSocket_1_2>()) {
+ return NetAddress(
+ PASS_REF,
+ get_interface<PPB_UDPSocket_1_2>()->GetBoundAddress(pp_resource()));
+ }
if (has_interface<PPB_UDPSocket_1_1>()) {
return NetAddress(
PASS_REF,
@@ -89,6 +106,11 @@ int32_t UDPSocket::RecvFrom(
char* buffer,
int32_t num_bytes,
const CompletionCallbackWithOutput<NetAddress>& callback) {
+ if (has_interface<PPB_UDPSocket_1_2>()) {
+ return get_interface<PPB_UDPSocket_1_2>()->RecvFrom(
+ pp_resource(), buffer, num_bytes, callback.output(),
+ callback.pp_completion_callback());
+ }
if (has_interface<PPB_UDPSocket_1_1>()) {
return get_interface<PPB_UDPSocket_1_1>()->RecvFrom(
pp_resource(), buffer, num_bytes, callback.output(),
@@ -106,6 +128,11 @@ int32_t UDPSocket::SendTo(const char* buffer,
int32_t num_bytes,
const NetAddress& addr,
const CompletionCallback& callback) {
+ if (has_interface<PPB_UDPSocket_1_2>()) {
+ return get_interface<PPB_UDPSocket_1_2>()->SendTo(
+ pp_resource(), buffer, num_bytes, addr.pp_resource(),
+ callback.pp_completion_callback());
+ }
if (has_interface<PPB_UDPSocket_1_1>()) {
return get_interface<PPB_UDPSocket_1_1>()->SendTo(
pp_resource(), buffer, num_bytes, addr.pp_resource(),
@@ -120,6 +147,8 @@ int32_t UDPSocket::SendTo(const char* buffer,
}
void UDPSocket::Close() {
+ if (has_interface<PPB_UDPSocket_1_2>())
+ return get_interface<PPB_UDPSocket_1_2>()->Close(pp_resource());
if (has_interface<PPB_UDPSocket_1_1>())
return get_interface<PPB_UDPSocket_1_1>()->Close(pp_resource());
if (has_interface<PPB_UDPSocket_1_0>())
@@ -129,6 +158,10 @@ void UDPSocket::Close() {
int32_t UDPSocket::SetOption(PP_UDPSocket_Option name,
const Var& value,
const CompletionCallback& callback) {
+ if (has_interface<PPB_UDPSocket_1_2>()) {
+ return get_interface<PPB_UDPSocket_1_2>()->SetOption(
+ pp_resource(), name, value.pp_var(), callback.pp_completion_callback());
+ }
if (has_interface<PPB_UDPSocket_1_1>()) {
return get_interface<PPB_UDPSocket_1_1>()->SetOption(
pp_resource(), name, value.pp_var(), callback.pp_completion_callback());
@@ -140,4 +173,22 @@ int32_t UDPSocket::SetOption(PP_UDPSocket_Option name,
return callback.MayForce(PP_ERROR_NOINTERFACE);
}
+int32_t UDPSocket::JoinGroup(const NetAddress& group,
+ const CompletionCallback callback) {
+ if (has_interface<PPB_UDPSocket_1_2>()) {
+ return get_interface<PPB_UDPSocket_1_2>()->JoinGroup(
+ pp_resource(), group.pp_resource(), callback.pp_completion_callback());
+ }
+ return callback.MayForce(PP_ERROR_NOINTERFACE);
+}
+
+int32_t UDPSocket::LeaveGroup(const NetAddress& group,
+ const CompletionCallback callback) {
+ if (has_interface<PPB_UDPSocket_1_2>()) {
+ return get_interface<PPB_UDPSocket_1_2>()->LeaveGroup(
+ pp_resource(), group.pp_resource(), callback.pp_completion_callback());
+ }
+ return callback.MayForce(PP_ERROR_NOINTERFACE);
+}
+
} // namespace pp
diff --git a/ppapi/cpp/udp_socket.h b/ppapi/cpp/udp_socket.h
index 707c621..69e906f 100644
--- a/ppapi/cpp/udp_socket.h
+++ b/ppapi/cpp/udp_socket.h
@@ -156,6 +156,30 @@ class UDPSocket : public Resource {
int32_t SetOption(PP_UDPSocket_Option name,
const Var& value,
const CompletionCallback& callback);
+
+ /// Joins the multicast group with address specified by <code>group</code>
+ /// parameter, which is expected to be a <code>NetAddress</code> object.
+ ///
+ /// @param[in] group A <code>NetAddress</code> corresponding to the network
+ /// address of the multicast group.
+ /// @param[in] callback A <code>CompletionCallback</code> to be called upon
+ /// completion.
+ ///
+ /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ int32_t JoinGroup(const NetAddress& group,
+ const CompletionCallback callback);
+
+ /// Leaves the multicast group with address specified by <code>group</code>
+ /// parameter, which is expected to be a <code>NetAddress</code> object.
+ ///
+ /// @param[in] group A <code>NetAddress</code> corresponding to the network
+ /// address of the multicast group.
+ /// @param[in] callback A <code>CompletionCallback</code> to be called upon
+ /// completion.
+ ///
+ /// @return An int32_t containing an error code from <code>pp_errors.h</code>.
+ int32_t LeaveGroup(const NetAddress& group,
+ const CompletionCallback callback);
};
} // namespace pp
diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
index b4271a4..c3a578f 100644
--- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
+++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
@@ -134,6 +134,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TCPSocket_1_2;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TextInputController_1_0;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_1_0;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_1_1;
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_1_2;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_URLLoader_1_0;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_URLRequestInfo_1_0;
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_URLResponseInfo_1_0;
@@ -1762,6 +1763,60 @@ static int32_t Pnacl_M41_PPB_UDPSocket_SetOption(PP_Resource udp_socket, PP_UDPS
/* End wrapper methods for PPB_UDPSocket_1_1 */
+/* Begin wrapper methods for PPB_UDPSocket_1_2 */
+
+static PP_Resource Pnacl_M43_PPB_UDPSocket_Create(PP_Instance instance) {
+ const struct PPB_UDPSocket_1_2 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_1_2.real_iface;
+ return iface->Create(instance);
+}
+
+static PP_Bool Pnacl_M43_PPB_UDPSocket_IsUDPSocket(PP_Resource resource) {
+ const struct PPB_UDPSocket_1_2 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_1_2.real_iface;
+ return iface->IsUDPSocket(resource);
+}
+
+static int32_t Pnacl_M43_PPB_UDPSocket_Bind(PP_Resource udp_socket, PP_Resource addr, struct PP_CompletionCallback* callback) {
+ const struct PPB_UDPSocket_1_2 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_1_2.real_iface;
+ return iface->Bind(udp_socket, addr, *callback);
+}
+
+static PP_Resource Pnacl_M43_PPB_UDPSocket_GetBoundAddress(PP_Resource udp_socket) {
+ const struct PPB_UDPSocket_1_2 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_1_2.real_iface;
+ return iface->GetBoundAddress(udp_socket);
+}
+
+static int32_t Pnacl_M43_PPB_UDPSocket_RecvFrom(PP_Resource udp_socket, char* buffer, int32_t num_bytes, PP_Resource* addr, struct PP_CompletionCallback* callback) {
+ const struct PPB_UDPSocket_1_2 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_1_2.real_iface;
+ return iface->RecvFrom(udp_socket, buffer, num_bytes, addr, *callback);
+}
+
+static int32_t Pnacl_M43_PPB_UDPSocket_SendTo(PP_Resource udp_socket, const char* buffer, int32_t num_bytes, PP_Resource addr, struct PP_CompletionCallback* callback) {
+ const struct PPB_UDPSocket_1_2 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_1_2.real_iface;
+ return iface->SendTo(udp_socket, buffer, num_bytes, addr, *callback);
+}
+
+static void Pnacl_M43_PPB_UDPSocket_Close(PP_Resource udp_socket) {
+ const struct PPB_UDPSocket_1_2 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_1_2.real_iface;
+ iface->Close(udp_socket);
+}
+
+static int32_t Pnacl_M43_PPB_UDPSocket_SetOption(PP_Resource udp_socket, PP_UDPSocket_Option name, struct PP_Var* value, struct PP_CompletionCallback* callback) {
+ const struct PPB_UDPSocket_1_2 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_1_2.real_iface;
+ return iface->SetOption(udp_socket, name, *value, *callback);
+}
+
+static int32_t Pnacl_M43_PPB_UDPSocket_JoinGroup(PP_Resource udp_socket, PP_Resource group, struct PP_CompletionCallback* callback) {
+ const struct PPB_UDPSocket_1_2 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_1_2.real_iface;
+ return iface->JoinGroup(udp_socket, group, *callback);
+}
+
+static int32_t Pnacl_M43_PPB_UDPSocket_LeaveGroup(PP_Resource udp_socket, PP_Resource group, struct PP_CompletionCallback* callback) {
+ const struct PPB_UDPSocket_1_2 *iface = Pnacl_WrapperInfo_PPB_UDPSocket_1_2.real_iface;
+ return iface->LeaveGroup(udp_socket, group, *callback);
+}
+
+/* End wrapper methods for PPB_UDPSocket_1_2 */
+
/* Begin wrapper methods for PPB_URLLoader_1_0 */
static PP_Resource Pnacl_M14_PPB_URLLoader_Create(PP_Instance instance) {
@@ -4929,6 +4984,19 @@ static const struct PPB_UDPSocket_1_1 Pnacl_Wrappers_PPB_UDPSocket_1_1 = {
.SetOption = (int32_t (*)(PP_Resource udp_socket, PP_UDPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback))&Pnacl_M41_PPB_UDPSocket_SetOption
};
+static const struct PPB_UDPSocket_1_2 Pnacl_Wrappers_PPB_UDPSocket_1_2 = {
+ .Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M43_PPB_UDPSocket_Create,
+ .IsUDPSocket = (PP_Bool (*)(PP_Resource resource))&Pnacl_M43_PPB_UDPSocket_IsUDPSocket,
+ .Bind = (int32_t (*)(PP_Resource udp_socket, PP_Resource addr, struct PP_CompletionCallback callback))&Pnacl_M43_PPB_UDPSocket_Bind,
+ .GetBoundAddress = (PP_Resource (*)(PP_Resource udp_socket))&Pnacl_M43_PPB_UDPSocket_GetBoundAddress,
+ .RecvFrom = (int32_t (*)(PP_Resource udp_socket, char* buffer, int32_t num_bytes, PP_Resource* addr, struct PP_CompletionCallback callback))&Pnacl_M43_PPB_UDPSocket_RecvFrom,
+ .SendTo = (int32_t (*)(PP_Resource udp_socket, const char* buffer, int32_t num_bytes, PP_Resource addr, struct PP_CompletionCallback callback))&Pnacl_M43_PPB_UDPSocket_SendTo,
+ .Close = (void (*)(PP_Resource udp_socket))&Pnacl_M43_PPB_UDPSocket_Close,
+ .SetOption = (int32_t (*)(PP_Resource udp_socket, PP_UDPSocket_Option name, struct PP_Var value, struct PP_CompletionCallback callback))&Pnacl_M43_PPB_UDPSocket_SetOption,
+ .JoinGroup = (int32_t (*)(PP_Resource udp_socket, PP_Resource group, struct PP_CompletionCallback callback))&Pnacl_M43_PPB_UDPSocket_JoinGroup,
+ .LeaveGroup = (int32_t (*)(PP_Resource udp_socket, PP_Resource group, struct PP_CompletionCallback callback))&Pnacl_M43_PPB_UDPSocket_LeaveGroup
+};
+
static const struct PPB_URLLoader_1_0 Pnacl_Wrappers_PPB_URLLoader_1_0 = {
.Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M14_PPB_URLLoader_Create,
.IsURLLoader = (PP_Bool (*)(PP_Resource resource))&Pnacl_M14_PPB_URLLoader_IsURLLoader,
@@ -5947,6 +6015,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_1_1 = {
.real_iface = NULL
};
+static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_1_2 = {
+ .iface_macro = PPB_UDPSOCKET_INTERFACE_1_2,
+ .wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_UDPSocket_1_2,
+ .real_iface = NULL
+};
+
static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_URLLoader_1_0 = {
.iface_macro = PPB_URLLOADER_INTERFACE_1_0,
.wrapped_iface = (const void *) &Pnacl_Wrappers_PPB_URLLoader_1_0,
@@ -6419,6 +6493,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = {
&Pnacl_WrapperInfo_PPB_TextInputController_1_0,
&Pnacl_WrapperInfo_PPB_UDPSocket_1_0,
&Pnacl_WrapperInfo_PPB_UDPSocket_1_1,
+ &Pnacl_WrapperInfo_PPB_UDPSocket_1_2,
&Pnacl_WrapperInfo_PPB_URLLoader_1_0,
&Pnacl_WrapperInfo_PPB_URLRequestInfo_1_0,
&Pnacl_WrapperInfo_PPB_URLResponseInfo_1_0,
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index 4347649..0f1f393 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -130,7 +130,7 @@ IPC_ENUM_TRAITS(PP_TrueTypeFontWeight_Dev)
IPC_ENUM_TRAITS(PP_TrueTypeFontWidth_Dev)
IPC_ENUM_TRAITS(PP_TrueTypeFontCharset_Dev)
IPC_ENUM_TRAITS_MAX_VALUE(PP_UDPSocket_Option,
- PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE)
+ PP_UDPSOCKET_OPTION_MULTICAST_TTL)
IPC_ENUM_TRAITS(PP_VideoDecodeError_Dev)
IPC_ENUM_TRAITS(PP_VideoDecoder_Profile)
IPC_ENUM_TRAITS_MAX_VALUE(PP_VideoFrame_Format, PP_VIDEOFRAME_FORMAT_LAST)
@@ -1781,6 +1781,12 @@ IPC_MESSAGE_CONTROL2(PpapiHostMsg_UDPSocket_SendTo,
IPC_MESSAGE_CONTROL1(PpapiPluginMsg_UDPSocket_SendToReply,
int32_t /* bytes_written */)
IPC_MESSAGE_CONTROL0(PpapiHostMsg_UDPSocket_Close)
+IPC_MESSAGE_CONTROL1(PpapiHostMsg_UDPSocket_JoinGroup,
+ PP_NetAddress_Private /* net_addr */)
+IPC_MESSAGE_CONTROL0(PpapiPluginMsg_UDPSocket_JoinGroupReply)
+IPC_MESSAGE_CONTROL1(PpapiHostMsg_UDPSocket_LeaveGroup,
+ PP_NetAddress_Private /* net_addr */)
+IPC_MESSAGE_CONTROL0(PpapiPluginMsg_UDPSocket_LeaveGroupReply)
// URLLoader ------------------------------------------------------------------
diff --git a/ppapi/proxy/udp_socket_resource.cc b/ppapi/proxy/udp_socket_resource.cc
index d815b9f..25a0f88 100644
--- a/ppapi/proxy/udp_socket_resource.cc
+++ b/ppapi/proxy/udp_socket_resource.cc
@@ -79,11 +79,26 @@ int32_t UDPSocketResource::SetOption1_0(
PP_UDPSocket_Option name,
const PP_Var& value,
scoped_refptr<TrackedCallback> callback) {
+ if (name > PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE)
+ return PP_ERROR_BADARGUMENT;
+
return SetOptionImpl(name, value,
true, // Check bind() state.
callback);
}
+int32_t UDPSocketResource::SetOption1_1(
+ PP_UDPSocket_Option name,
+ const PP_Var& value,
+ scoped_refptr<TrackedCallback> callback) {
+ if (name > PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE)
+ return PP_ERROR_BADARGUMENT;
+
+ return SetOptionImpl(name, value,
+ false, // Check bind() state.
+ callback);
+}
+
int32_t UDPSocketResource::SetOption(
PP_UDPSocket_Option name,
const PP_Var& value,
@@ -93,5 +108,27 @@ int32_t UDPSocketResource::SetOption(
callback);
}
+int32_t UDPSocketResource::JoinGroup(
+ PP_Resource group,
+ scoped_refptr<TrackedCallback> callback) {
+ EnterNetAddressNoLock enter(group, true);
+ if (enter.failed())
+ return PP_ERROR_BADRESOURCE;
+
+ return JoinGroupImpl(&enter.object()->GetNetAddressPrivate(),
+ callback);
+}
+
+int32_t UDPSocketResource::LeaveGroup(
+ PP_Resource group,
+ scoped_refptr<TrackedCallback> callback) {
+ EnterNetAddressNoLock enter(group, true);
+ if (enter.failed())
+ return PP_ERROR_BADRESOURCE;
+
+ return LeaveGroupImpl(&enter.object()->GetNetAddressPrivate(),
+ callback);
+}
+
} // namespace proxy
} // namespace ppapi
diff --git a/ppapi/proxy/udp_socket_resource.h b/ppapi/proxy/udp_socket_resource.h
index 81aad26..1516067 100644
--- a/ppapi/proxy/udp_socket_resource.h
+++ b/ppapi/proxy/udp_socket_resource.h
@@ -40,9 +40,17 @@ class PPAPI_PROXY_EXPORT UDPSocketResource : public UDPSocketResourceBase,
PP_UDPSocket_Option name,
const PP_Var& value,
scoped_refptr<TrackedCallback> callback) override;
+ virtual int32_t SetOption1_1(
+ PP_UDPSocket_Option name,
+ const PP_Var& value,
+ scoped_refptr<TrackedCallback> callback) override;
virtual int32_t SetOption(PP_UDPSocket_Option name,
const PP_Var& value,
scoped_refptr<TrackedCallback> callback) override;
+ virtual int32_t JoinGroup(PP_Resource group,
+ scoped_refptr<TrackedCallback> callback) override;
+ virtual int32_t LeaveGroup(PP_Resource group,
+ scoped_refptr<TrackedCallback> callback) override;
private:
DISALLOW_COPY_AND_ASSIGN(UDPSocketResource);
diff --git a/ppapi/proxy/udp_socket_resource_base.cc b/ppapi/proxy/udp_socket_resource_base.cc
index 97864d5..e61e16b 100644
--- a/ppapi/proxy/udp_socket_resource_base.cc
+++ b/ppapi/proxy/udp_socket_resource_base.cc
@@ -68,10 +68,12 @@ int32_t UDPSocketResourceBase::SetOptionImpl(
if (closed_)
return PP_ERROR_FAILED;
- SocketOptionData option_data;
+ // Check if socket is expected to be bound or not according to the option.
switch (name) {
case PP_UDPSOCKET_OPTION_ADDRESS_REUSE:
- case PP_UDPSOCKET_OPTION_BROADCAST: {
+ case PP_UDPSOCKET_OPTION_BROADCAST:
+ case PP_UDPSOCKET_OPTION_MULTICAST_LOOP:
+ case PP_UDPSOCKET_OPTION_MULTICAST_TTL: {
if ((check_bind_state || name == PP_UDPSOCKET_OPTION_ADDRESS_REUSE) &&
bind_called_) {
// SetOption should fail in this case in order to give predictable
@@ -80,6 +82,21 @@ int32_t UDPSocketResourceBase::SetOptionImpl(
// of Bind().
return PP_ERROR_FAILED;
}
+ break;
+ }
+ case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE:
+ case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: {
+ if (check_bind_state && !bound_)
+ return PP_ERROR_FAILED;
+ break;
+ }
+ }
+
+ SocketOptionData option_data;
+ switch (name) {
+ case PP_UDPSOCKET_OPTION_ADDRESS_REUSE:
+ case PP_UDPSOCKET_OPTION_BROADCAST:
+ case PP_UDPSOCKET_OPTION_MULTICAST_LOOP: {
if (value.type != PP_VARTYPE_BOOL)
return PP_ERROR_BADARGUMENT;
option_data.SetBool(PP_ToBool(value.value.as_bool));
@@ -87,13 +104,18 @@ int32_t UDPSocketResourceBase::SetOptionImpl(
}
case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE:
case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: {
- if (check_bind_state && !bound_)
- return PP_ERROR_FAILED;
if (value.type != PP_VARTYPE_INT32)
return PP_ERROR_BADARGUMENT;
option_data.SetInt32(value.value.as_int);
break;
}
+ case PP_UDPSOCKET_OPTION_MULTICAST_TTL: {
+ int32_t ival = value.value.as_int;
+ if (value.type != PP_VARTYPE_INT32 && (ival < 0 || ival > 255))
+ return PP_ERROR_BADARGUMENT;
+ option_data.SetInt32(ival);
+ break;
+ }
default: {
NOTREACHED();
return PP_ERROR_BADARGUMENT;
@@ -103,7 +125,7 @@ int32_t UDPSocketResourceBase::SetOptionImpl(
Call<PpapiPluginMsg_UDPSocket_SetOptionReply>(
BROWSER,
PpapiHostMsg_UDPSocket_SetOption(name, option_data),
- base::Bind(&UDPSocketResourceBase::OnPluginMsgSetOptionReply,
+ base::Bind(&UDPSocketResourceBase::OnPluginMsgGeneralReply,
base::Unretained(this),
callback),
callback);
@@ -233,6 +255,36 @@ void UDPSocketResourceBase::CloseImpl() {
bytes_to_read_ = -1;
}
+int32_t UDPSocketResourceBase::JoinGroupImpl(
+ const PP_NetAddress_Private *group,
+ scoped_refptr<TrackedCallback> callback) {
+ DCHECK(group);
+
+ Call<PpapiPluginMsg_UDPSocket_JoinGroupReply>(
+ BROWSER,
+ PpapiHostMsg_UDPSocket_JoinGroup(*group),
+ base::Bind(&UDPSocketResourceBase::OnPluginMsgGeneralReply,
+ base::Unretained(this),
+ callback),
+ callback);
+ return PP_OK_COMPLETIONPENDING;
+}
+
+int32_t UDPSocketResourceBase::LeaveGroupImpl(
+ const PP_NetAddress_Private *group,
+ scoped_refptr<TrackedCallback> callback) {
+ DCHECK(group);
+
+ Call<PpapiPluginMsg_UDPSocket_LeaveGroupReply>(
+ BROWSER,
+ PpapiHostMsg_UDPSocket_LeaveGroup(*group),
+ base::Bind(&UDPSocketResourceBase::OnPluginMsgGeneralReply,
+ base::Unretained(this),
+ callback),
+ callback);
+ return PP_OK_COMPLETIONPENDING;
+}
+
void UDPSocketResourceBase::OnReplyReceived(
const ResourceMessageReplyParams& params,
const IPC::Message& msg) {
@@ -251,7 +303,7 @@ void UDPSocketResourceBase::PostAbortIfNecessary(
(*callback)->PostAbort();
}
-void UDPSocketResourceBase::OnPluginMsgSetOptionReply(
+void UDPSocketResourceBase::OnPluginMsgGeneralReply(
scoped_refptr<TrackedCallback> callback,
const ResourceMessageReplyParams& params) {
if (TrackedCallback::IsPending(callback))
diff --git a/ppapi/proxy/udp_socket_resource_base.h b/ppapi/proxy/udp_socket_resource_base.h
index 9e75ae7..61ed664 100644
--- a/ppapi/proxy/udp_socket_resource_base.h
+++ b/ppapi/proxy/udp_socket_resource_base.h
@@ -73,6 +73,10 @@ class PPAPI_PROXY_EXPORT UDPSocketResourceBase: public PluginResource {
const PP_NetAddress_Private* addr,
scoped_refptr<TrackedCallback> callback);
void CloseImpl();
+ int32_t JoinGroupImpl(const PP_NetAddress_Private *group,
+ scoped_refptr<TrackedCallback> callback);
+ int32_t LeaveGroupImpl(const PP_NetAddress_Private *group,
+ scoped_refptr<TrackedCallback> callback);
private:
struct RecvBuffer {
@@ -88,8 +92,8 @@ class PPAPI_PROXY_EXPORT UDPSocketResourceBase: public PluginResource {
void PostAbortIfNecessary(scoped_refptr<TrackedCallback>* callback);
// IPC message handlers.
- void OnPluginMsgSetOptionReply(scoped_refptr<TrackedCallback> callback,
- const ResourceMessageReplyParams& params);
+ void OnPluginMsgGeneralReply(scoped_refptr<TrackedCallback> callback,
+ const ResourceMessageReplyParams& params);
void OnPluginMsgBindReply(const ResourceMessageReplyParams& params,
const PP_NetAddress_Private& bound_addr);
void OnPluginMsgPushRecvResult(const ResourceMessageReplyParams& params,
diff --git a/ppapi/shared_impl/private/net_address_private_impl.cc b/ppapi/shared_impl/private/net_address_private_impl.cc
index 43df743..7515592 100644
--- a/ppapi/shared_impl/private/net_address_private_impl.cc
+++ b/ppapi/shared_impl/private/net_address_private_impl.cc
@@ -518,6 +518,12 @@ std::string NetAddressPrivateImpl::DescribeNetAddress(
}
// static
+void NetAddressPrivateImpl::GetAnyAddress(PP_Bool is_ipv6,
+ PP_NetAddress_Private* addr) {
+ ppapi::GetAnyAddress(is_ipv6, addr);
+}
+
+// static
void NetAddressPrivateImpl::CreateNetAddressPrivateFromIPv4Address(
const PP_NetAddress_IPv4& ipv4_addr,
PP_NetAddress_Private* addr) {
diff --git a/ppapi/shared_impl/private/net_address_private_impl.h b/ppapi/shared_impl/private/net_address_private_impl.h
index d7126354..814633b 100644
--- a/ppapi/shared_impl/private/net_address_private_impl.h
+++ b/ppapi/shared_impl/private/net_address_private_impl.h
@@ -37,6 +37,8 @@ class PPAPI_SHARED_EXPORT NetAddressPrivateImpl {
static std::string DescribeNetAddress(const PP_NetAddress_Private& addr,
bool include_port);
+ static void GetAnyAddress(PP_Bool is_ipv6, PP_NetAddress_Private* addr);
+
// Conversion methods to make PPB_NetAddress resource work with
// PP_NetAddress_Private.
// TODO(yzshen): Remove them once PPB_NetAddress resource doesn't use
diff --git a/ppapi/tests/test_udp_socket.cc b/ppapi/tests/test_udp_socket.cc
index 89ea036..b82019e 100644
--- a/ppapi/tests/test_udp_socket.cc
+++ b/ppapi/tests/test_udp_socket.cc
@@ -47,7 +47,10 @@ pp::NetAddress ReplacePort(const pp::InstanceHandle& instance,
} // namespace
-TestUDPSocket::TestUDPSocket(TestingInstance* instance) : TestCase(instance) {
+TestUDPSocket::TestUDPSocket(TestingInstance* instance)
+ : TestCase(instance),
+ socket_interface_1_0_(NULL),
+ socket_interface_1_1_(NULL) {
}
bool TestUDPSocket::Init() {
@@ -71,19 +74,36 @@ bool TestUDPSocket::Init() {
if (!init_address)
instance_->AppendError("Can't init address");
+ socket_interface_1_0_ =
+ static_cast<const PPB_UDPSocket_1_0*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_INTERFACE_1_0));
+ if (!socket_interface_1_0_)
+ instance_->AppendError("PPB_UDPSocket_1_0 interface not available");
+
+ socket_interface_1_1_ =
+ static_cast<const PPB_UDPSocket_1_1*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_UDPSOCKET_INTERFACE_1_1));
+ if (!socket_interface_1_1_)
+ instance_->AppendError("PPB_UDPSocket_1_1 interface not available");
+
return tcp_socket_is_available &&
udp_socket_is_available &&
net_address_is_available &&
init_address &&
CheckTestingInterface() &&
- EnsureRunningOverHTTP();
+ EnsureRunningOverHTTP() &&
+ socket_interface_1_0_ != NULL &&
+ socket_interface_1_1_ != NULL;
}
void TestUDPSocket::RunTests(const std::string& filter) {
RUN_CALLBACK_TEST(TestUDPSocket, ReadWrite, filter);
RUN_CALLBACK_TEST(TestUDPSocket, Broadcast, filter);
+ RUN_CALLBACK_TEST(TestUDPSocket, SetOption_1_0, filter);
+ RUN_CALLBACK_TEST(TestUDPSocket, SetOption_1_1, filter);
RUN_CALLBACK_TEST(TestUDPSocket, SetOption, filter);
RUN_CALLBACK_TEST(TestUDPSocket, ParallelSend, filter);
+ RUN_CALLBACK_TEST(TestUDPSocket, Multicast, filter);
}
std::string TestUDPSocket::GetLocalAddress(pp::NetAddress* address) {
@@ -131,16 +151,18 @@ std::string TestUDPSocket::LookupPortAndBindUDPSocket(
ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address));
bool is_free_port_found = false;
+ std::string ret;
for (uint16_t port = kPortScanFrom; port < kPortScanTo; ++port) {
pp::NetAddress new_address = ReplacePort(instance_, base_address, port);
ASSERT_NE(0, new_address.pp_resource());
- if (BindUDPSocket(socket, new_address).empty()) {
+ ret = BindUDPSocket(socket, new_address);
+ if (ret.empty()) {
is_free_port_found = true;
break;
}
}
if (!is_free_port_found)
- return "Can't find available port";
+ return "Can't find available port (" + ret + ")";
*address = socket->GetBoundAddress();
ASSERT_NE(0, address->pp_resource());
@@ -188,6 +210,22 @@ std::string TestUDPSocket::PassMessage(pp::UDPSocket* target,
PASS();
}
+std::string TestUDPSocket::SetMulticastOptions(pp::UDPSocket* socket) {
+ TestCompletionCallback callback(instance_->pp_instance(), callback_type());
+ callback.WaitForResult(socket->SetOption(
+ PP_UDPSOCKET_OPTION_MULTICAST_LOOP, pp::Var(true),
+ callback.GetCallback()));
+ CHECK_CALLBACK_BEHAVIOR(callback);
+ ASSERT_EQ(PP_OK, callback.result());
+
+ callback.WaitForResult(socket->SetOption(
+ PP_UDPSOCKET_OPTION_MULTICAST_TTL, pp::Var(1), callback.GetCallback()));
+ CHECK_CALLBACK_BEHAVIOR(callback);
+ ASSERT_EQ(PP_OK, callback.result());
+
+ PASS();
+}
+
std::string TestUDPSocket::TestReadWrite() {
pp::UDPSocket server_socket(instance_), client_socket(instance_);
pp::NetAddress server_address, client_address;
@@ -258,10 +296,77 @@ std::string TestUDPSocket::TestBroadcast() {
PASS();
}
+int32_t TestUDPSocket::SetOptionValue(UDPSocketSetOption func,
+ PP_Resource socket,
+ PP_UDPSocket_Option option,
+ const PP_Var& value) {
+ PP_TimeTicks start_time(NowInTimeTicks());
+ TestCompletionCallback cb(instance_->pp_instance(), callback_type());
+ cb.WaitForResult(func(socket, option, value,
+ cb.GetCallback().pp_completion_callback()));
+
+ // Expanded from CHECK_CALLBACK_BEHAVIOR macro.
+ if (cb.failed()) {
+ std::string msg = MakeFailureMessage(__FILE__, __LINE__,
+ cb.errors().c_str());
+
+ instance_->LogTest("SetOptionValue", msg, start_time);
+ return PP_ERROR_FAILED;
+ }
+ return cb.result();
+}
+
+std::string TestUDPSocket::TestSetOption_1_0() {
+ PP_Resource socket = socket_interface_1_0_->Create(instance_->pp_instance());
+ ASSERT_NE(0, socket);
+
+ // Multicast options are not supported in interface 1.0.
+ ASSERT_EQ(PP_ERROR_BADARGUMENT,
+ SetOptionValue(socket_interface_1_0_->SetOption,
+ socket,
+ PP_UDPSOCKET_OPTION_MULTICAST_LOOP,
+ PP_MakeBool(PP_TRUE)));
+
+ ASSERT_EQ(PP_ERROR_BADARGUMENT,
+ SetOptionValue(socket_interface_1_0_->SetOption,
+ socket,
+ PP_UDPSOCKET_OPTION_MULTICAST_TTL,
+ PP_MakeInt32(1)));
+
+ socket_interface_1_0_->Close(socket);
+ pp::Module::Get()->core()->ReleaseResource(socket);
+
+ PASS();
+}
+
+std::string TestUDPSocket::TestSetOption_1_1() {
+ PP_Resource socket = socket_interface_1_1_->Create(instance_->pp_instance());
+ ASSERT_NE(0, socket);
+
+ // Multicast options are not supported in interface 1.1.
+ ASSERT_EQ(PP_ERROR_BADARGUMENT,
+ SetOptionValue(socket_interface_1_1_->SetOption,
+ socket,
+ PP_UDPSOCKET_OPTION_MULTICAST_LOOP,
+ PP_MakeBool(PP_TRUE)));
+
+ ASSERT_EQ(PP_ERROR_BADARGUMENT,
+ SetOptionValue(socket_interface_1_1_->SetOption,
+ socket,
+ PP_UDPSOCKET_OPTION_MULTICAST_TTL,
+ PP_MakeInt32(1)));
+
+ socket_interface_1_1_->Close(socket);
+ pp::Module::Get()->core()->ReleaseResource(socket);
+
+ PASS();
+}
+
std::string TestUDPSocket::TestSetOption() {
pp::UDPSocket socket(instance_);
ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&socket));
+ ASSERT_SUBTEST_SUCCESS(SetMulticastOptions(&socket));
// Try to pass incorrect option value's type.
TestCompletionCallback callback(instance_->pp_instance(), callback_type());
@@ -270,6 +375,17 @@ std::string TestUDPSocket::TestSetOption() {
CHECK_CALLBACK_BEHAVIOR(callback);
ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result());
+ // Invalid multicast TTL values (less than 0 and greater than 255).
+ callback.WaitForResult(socket.SetOption(
+ PP_UDPSOCKET_OPTION_MULTICAST_TTL, pp::Var(-1), callback.GetCallback()));
+ CHECK_CALLBACK_BEHAVIOR(callback);
+ ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result());
+
+ callback.WaitForResult(socket.SetOption(
+ PP_UDPSOCKET_OPTION_MULTICAST_TTL, pp::Var(256), callback.GetCallback()));
+ CHECK_CALLBACK_BEHAVIOR(callback);
+ ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result());
+
callback.WaitForResult(socket.SetOption(
PP_UDPSOCKET_OPTION_BROADCAST, pp::Var(false), callback.GetCallback()));
CHECK_CALLBACK_BEHAVIOR(callback);
@@ -388,3 +504,15 @@ std::string TestUDPSocket::TestParallelSend() {
PASS();
}
+
+std::string TestUDPSocket::TestMulticast() {
+ pp::UDPSocket server1(instance_), server2(instance_);
+
+ ASSERT_SUBTEST_SUCCESS(SetMulticastOptions(&server1));
+ ASSERT_SUBTEST_SUCCESS(SetMulticastOptions(&server2));
+
+ server1.Close();
+ server2.Close();
+
+ PASS();
+}
diff --git a/ppapi/tests/test_udp_socket.h b/ppapi/tests/test_udp_socket.h
index 2a2a473..ee3e672 100644
--- a/ppapi/tests/test_udp_socket.h
+++ b/ppapi/tests/test_udp_socket.h
@@ -8,9 +8,17 @@
#include <string>
#include "ppapi/c/pp_stdint.h"
+#include "ppapi/c/ppb_udp_socket.h"
#include "ppapi/cpp/net_address.h"
#include "ppapi/tests/test_case.h"
+namespace {
+typedef int32_t (*UDPSocketSetOption)(PP_Resource udp_socket,
+ PP_UDPSocket_Option name,
+ struct PP_Var value,
+ struct PP_CompletionCallback callback);
+}
+
namespace pp {
class UDPSocket;
}
@@ -39,13 +47,24 @@ class TestUDPSocket: public TestCase {
const pp::NetAddress& target_address,
const std::string& message,
pp::NetAddress* recvfrom_address);
+ std::string SetMulticastOptions(pp::UDPSocket* socket);
std::string TestReadWrite();
std::string TestBroadcast();
+ int32_t SetOptionValue(UDPSocketSetOption func,
+ PP_Resource socket,
+ PP_UDPSocket_Option option,
+ const PP_Var& value);
+ std::string TestSetOption_1_0();
+ std::string TestSetOption_1_1();
std::string TestSetOption();
std::string TestParallelSend();
+ std::string TestMulticast();
pp::NetAddress address_;
+
+ const PPB_UDPSocket_1_0* socket_interface_1_0_;
+ const PPB_UDPSocket_1_1* socket_interface_1_1_;
};
#endif // PPAPI_TESTS_TEST_UDP_SOCKET_H_
diff --git a/ppapi/thunk/interfaces_ppb_public_dev_channel.h b/ppapi/thunk/interfaces_ppb_public_dev_channel.h
index c84d706..51f7c1c 100644
--- a/ppapi/thunk/interfaces_ppb_public_dev_channel.h
+++ b/ppapi/thunk/interfaces_ppb_public_dev_channel.h
@@ -12,6 +12,7 @@ PROXIED_IFACE(PPB_COMPOSITOR_INTERFACE_0_1, PPB_Compositor_0_1)
PROXIED_IFACE(PPB_COMPOSITORLAYER_INTERFACE_0_1, PPB_CompositorLayer_0_1)
PROXIED_IFACE(PPB_MESSAGING_INTERFACE_1_1_DEPRECATED,
PPB_Messaging_1_1_Deprecated)
+PROXIED_IFACE(PPB_UDPSOCKET_INTERFACE_1_2, PPB_UDPSocket_1_2)
PROXIED_IFACE(PPB_VIDEODECODER_INTERFACE_0_1, PPB_VideoDecoder_0_1)
PROXIED_IFACE(PPB_VIDEOENCODER_INTERFACE_0_1, PPB_VideoEncoder_0_1)
diff --git a/ppapi/thunk/ppb_udp_socket_api.h b/ppapi/thunk/ppb_udp_socket_api.h
index 3a03ea7..028c562 100644
--- a/ppapi/thunk/ppb_udp_socket_api.h
+++ b/ppapi/thunk/ppb_udp_socket_api.h
@@ -34,9 +34,16 @@ class PPAPI_THUNK_EXPORT PPB_UDPSocket_API {
virtual int32_t SetOption1_0(PP_UDPSocket_Option name,
const PP_Var& value,
scoped_refptr<TrackedCallback> callback) = 0;
+ virtual int32_t SetOption1_1(PP_UDPSocket_Option name,
+ const PP_Var& value,
+ scoped_refptr<TrackedCallback> callback) = 0;
virtual int32_t SetOption(PP_UDPSocket_Option name,
const PP_Var& value,
scoped_refptr<TrackedCallback> callback) = 0;
+ virtual int32_t JoinGroup(PP_Resource group,
+ scoped_refptr<TrackedCallback> callback) = 0;
+ virtual int32_t LeaveGroup(PP_Resource group,
+ scoped_refptr<TrackedCallback> callback) = 0;
};
} // namespace thunk
diff --git a/ppapi/thunk/ppb_udp_socket_thunk.cc b/ppapi/thunk/ppb_udp_socket_thunk.cc
index 7eca736..8b77161 100644
--- a/ppapi/thunk/ppb_udp_socket_thunk.cc
+++ b/ppapi/thunk/ppb_udp_socket_thunk.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// From ppb_udp_socket.idl modified Mon Jun 24 15:10:54 2013.
+// From ppb_udp_socket.idl modified Fri Feb 20 20:28:39 2015.
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
@@ -83,11 +83,11 @@ void Close(PP_Resource udp_socket) {
enter.object()->Close();
}
-int32_t SetOption1_0(PP_Resource udp_socket,
- PP_UDPSocket_Option name,
- struct PP_Var value,
- struct PP_CompletionCallback callback) {
- VLOG(4) << "PPB_UDPSocket::SetOption1_0()";
+int32_t SetOption_1_0(PP_Resource udp_socket,
+ PP_UDPSocket_Option name,
+ struct PP_Var value,
+ struct PP_CompletionCallback callback) {
+ VLOG(4) << "PPB_UDPSocket::SetOption()";
EnterResource<PPB_UDPSocket_API> enter(udp_socket, callback, true);
if (enter.failed())
return enter.retval();
@@ -95,6 +95,18 @@ int32_t SetOption1_0(PP_Resource udp_socket,
enter.object()->SetOption1_0(name, value, enter.callback()));
}
+int32_t SetOption_1_1(PP_Resource udp_socket,
+ PP_UDPSocket_Option name,
+ struct PP_Var value,
+ struct PP_CompletionCallback callback) {
+ VLOG(4) << "PPB_UDPSocket::SetOption()";
+ EnterResource<PPB_UDPSocket_API> enter(udp_socket, callback, true);
+ if (enter.failed())
+ return enter.retval();
+ return enter.SetResult(
+ enter.object()->SetOption1_1(name, value, enter.callback()));
+}
+
int32_t SetOption(PP_Resource udp_socket,
PP_UDPSocket_Option name,
struct PP_Var value,
@@ -107,27 +119,54 @@ int32_t SetOption(PP_Resource udp_socket,
enter.object()->SetOption(name, value, enter.callback()));
}
-const PPB_UDPSocket_1_0 g_ppb_udpsocket_thunk_1_0 = {
- &Create,
- &IsUDPSocket,
- &Bind,
- &GetBoundAddress,
- &RecvFrom,
- &SendTo,
- &Close,
- &SetOption1_0
-};
-
-const PPB_UDPSocket_1_1 g_ppb_udpsocket_thunk_1_1 = {
- &Create,
- &IsUDPSocket,
- &Bind,
- &GetBoundAddress,
- &RecvFrom,
- &SendTo,
- &Close,
- &SetOption
-};
+int32_t JoinGroup(PP_Resource udp_socket,
+ PP_Resource group,
+ struct PP_CompletionCallback callback) {
+ VLOG(4) << "PPB_UDPSocket::JoinGroup()";
+ EnterResource<PPB_UDPSocket_API> enter(udp_socket, callback, true);
+ if (enter.failed())
+ return enter.retval();
+ return enter.SetResult(enter.object()->JoinGroup(group, enter.callback()));
+}
+
+int32_t LeaveGroup(PP_Resource udp_socket,
+ PP_Resource group,
+ struct PP_CompletionCallback callback) {
+ VLOG(4) << "PPB_UDPSocket::LeaveGroup()";
+ EnterResource<PPB_UDPSocket_API> enter(udp_socket, callback, true);
+ if (enter.failed())
+ return enter.retval();
+ return enter.SetResult(enter.object()->LeaveGroup(group, enter.callback()));
+}
+
+const PPB_UDPSocket_1_0 g_ppb_udpsocket_thunk_1_0 = {&Create,
+ &IsUDPSocket,
+ &Bind,
+ &GetBoundAddress,
+ &RecvFrom,
+ &SendTo,
+ &Close,
+ &SetOption_1_0};
+
+const PPB_UDPSocket_1_1 g_ppb_udpsocket_thunk_1_1 = {&Create,
+ &IsUDPSocket,
+ &Bind,
+ &GetBoundAddress,
+ &RecvFrom,
+ &SendTo,
+ &Close,
+ &SetOption_1_1};
+
+const PPB_UDPSocket_1_2 g_ppb_udpsocket_thunk_1_2 = {&Create,
+ &IsUDPSocket,
+ &Bind,
+ &GetBoundAddress,
+ &RecvFrom,
+ &SendTo,
+ &Close,
+ &SetOption,
+ &JoinGroup,
+ &LeaveGroup};
} // namespace
@@ -139,5 +178,9 @@ PPAPI_THUNK_EXPORT const PPB_UDPSocket_1_1* GetPPB_UDPSocket_1_1_Thunk() {
return &g_ppb_udpsocket_thunk_1_1;
}
+PPAPI_THUNK_EXPORT const PPB_UDPSocket_1_2* GetPPB_UDPSocket_1_2_Thunk() {
+ return &g_ppb_udpsocket_thunk_1_2;
+}
+
} // namespace thunk
} // namespace ppapi