diff options
author | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-22 11:17:08 +0000 |
---|---|---|
committer | wez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-22 11:17:08 +0000 |
commit | 466a583aa3b19736c510b0c10d481eb3787a6c8c (patch) | |
tree | 9f9951426645a7e60fc1153bb78bdd32ba6ab45a /ppapi | |
parent | 6601b6d4374c6d7e3ef93ff7ab79eb040ae71c02 (diff) | |
download | chromium_src-466a583aa3b19736c510b0c10d481eb3787a6c8c.zip chromium_src-466a583aa3b19736c510b0c10d481eb3787a6c8c.tar.gz chromium_src-466a583aa3b19736c510b0c10d481eb3787a6c8c.tar.bz2 |
Provide a way to disable Nagle's algorithm on Pepper TCP sockets.
This CL adds a SetSocketFeature() API to PPB_TCPSocket_Private, supporting one
option, to control Nagle's algorithim on the underlying socket.
BUG=170248
Review URL: https://chromiumcodereview.appspot.com/12220050
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@184087 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi')
-rw-r--r-- | ppapi/api/private/ppb_tcp_socket_private.idl | 27 | ||||
-rw-r--r-- | ppapi/c/pp_macros.h | 4 | ||||
-rw-r--r-- | ppapi/c/private/ppb_tcp_socket_private.h | 70 | ||||
-rw-r--r-- | ppapi/cpp/private/tcp_socket_private.cc | 69 | ||||
-rw-r--r-- | ppapi/cpp/private/tcp_socket_private.h | 3 | ||||
-rw-r--r-- | ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c | 108 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 8 | ||||
-rw-r--r-- | ppapi/proxy/ppb_tcp_socket_private_proxy.cc | 23 | ||||
-rw-r--r-- | ppapi/proxy/ppb_tcp_socket_private_proxy.h | 3 | ||||
-rw-r--r-- | ppapi/shared_impl/private/tcp_socket_private_impl.cc | 32 | ||||
-rw-r--r-- | ppapi/shared_impl/private/tcp_socket_private_impl.h | 7 | ||||
-rw-r--r-- | ppapi/tests/test_tcp_socket_private.cc | 34 | ||||
-rw-r--r-- | ppapi/tests/test_tcp_socket_private.h | 1 | ||||
-rw-r--r-- | ppapi/thunk/interfaces_ppb_private_no_permissions.h | 2 | ||||
-rw-r--r-- | ppapi/thunk/ppb_tcp_socket_private_api.h | 3 | ||||
-rw-r--r-- | ppapi/thunk/ppb_tcp_socket_private_thunk.cc | 33 |
16 files changed, 416 insertions, 11 deletions
diff --git a/ppapi/api/private/ppb_tcp_socket_private.idl b/ppapi/api/private/ppb_tcp_socket_private.idl index 385dee6..5c5d54a 100644 --- a/ppapi/api/private/ppb_tcp_socket_private.idl +++ b/ppapi/api/private/ppb_tcp_socket_private.idl @@ -9,7 +9,19 @@ label Chrome { M17 = 0.3, - M20 = 0.4 + M20 = 0.4, + M27 = 0.5 +}; + +[assert_size(4)] +enum PP_TCPSocketOption_Private { + // Special value used for testing. Guaranteed to fail SetOption(). + PP_TCPSOCKETOPTION_INVALID = 0, + + // Disable coalescing of small writes to make TCP segments, and instead + // deliver data immediately. For SSL sockets, this option must be set before + // SSLHandshake() is called. Value type is PP_VARTYPE_BOOL. + PP_TCPSOCKETOPTION_NO_DELAY = 1 }; /** @@ -134,4 +146,17 @@ interface PPB_TCPSocket_Private { * method. */ void Disconnect([in] PP_Resource tcp_socket); + + /** + * Sets an option on |tcp_socket|. Supported |name| and |value| parameters + * are as described for PP_TCPSocketOption_Private. |callback| will be + * invoked with PP_OK if setting the option succeeds, or an error code + * otherwise. The socket must be connection before SetOption is called. + */ + [version=0.5] + int32_t SetOption([in] PP_Resource tcp_socket, + [in] PP_TCPSocketOption_Private name, + [in] PP_Var value, + [in] PP_CompletionCallback callback); + }; diff --git a/ppapi/c/pp_macros.h b/ppapi/c/pp_macros.h index 1f8b6d8..fa83391 100644 --- a/ppapi/c/pp_macros.h +++ b/ppapi/c/pp_macros.h @@ -3,13 +3,13 @@ * found in the LICENSE file. */ -/* From pp_macros.idl modified Wed Jan 9 18:07:46 2013. */ +/* From pp_macros.idl modified Wed Jan 30 13:26:34 2013. */ #ifndef PPAPI_C_PP_MACROS_H_ #define PPAPI_C_PP_MACROS_H_ -#define PPAPI_RELEASE 25 +#define PPAPI_RELEASE 27 /** * @file diff --git a/ppapi/c/private/ppb_tcp_socket_private.h b/ppapi/c/private/ppb_tcp_socket_private.h index 7d6ca46..6aad467 100644 --- a/ppapi/c/private/ppb_tcp_socket_private.h +++ b/ppapi/c/private/ppb_tcp_socket_private.h @@ -3,7 +3,7 @@ * found in the LICENSE file. */ -/* From private/ppb_tcp_socket_private.idl modified Fri Apr 6 14:42:45 2012. */ +/* From private/ppb_tcp_socket_private.idl modified Sun Feb 10 00:28:07 2013. */ #ifndef PPAPI_C_PRIVATE_PPB_TCP_SOCKET_PRIVATE_H_ #define PPAPI_C_PRIVATE_PPB_TCP_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_TCPSOCKET_PRIVATE_INTERFACE_0_3 "PPB_TCPSocket_Private;0.3" #define PPB_TCPSOCKET_PRIVATE_INTERFACE_0_4 "PPB_TCPSocket_Private;0.4" -#define PPB_TCPSOCKET_PRIVATE_INTERFACE PPB_TCPSOCKET_PRIVATE_INTERFACE_0_4 +#define PPB_TCPSOCKET_PRIVATE_INTERFACE_0_5 "PPB_TCPSocket_Private;0.5" +#define PPB_TCPSOCKET_PRIVATE_INTERFACE PPB_TCPSOCKET_PRIVATE_INTERFACE_0_5 /** * @file @@ -27,6 +29,23 @@ /** + * @addtogroup Enums + * @{ + */ +typedef enum { + /* Special value used for testing. Guaranteed to fail SetOption(). */ + PP_TCPSOCKETOPTION_INVALID = 0, + /* Disable coalescing of small writes to make TCP segments, and instead + * deliver data immediately. For SSL sockets, this option must be set before + * SSLHandshake() is called. Value type is PP_VARTYPE_BOOL. */ + PP_TCPSOCKETOPTION_NO_DELAY = 1 +} PP_TCPSocketOption_Private; +PP_COMPILE_ASSERT_SIZE_IN_BYTES(PP_TCPSocketOption_Private, 4); +/** + * @} + */ + +/** * @addtogroup Interfaces * @{ */ @@ -34,7 +53,7 @@ * The <code>PPB_TCPSocket_Private</code> interface provides TCP socket * operations. */ -struct PPB_TCPSocket_Private_0_4 { +struct PPB_TCPSocket_Private_0_5 { /** * Allocates a TCP socket resource. */ @@ -139,9 +158,19 @@ struct PPB_TCPSocket_Private_0_4 { * method. */ void (*Disconnect)(PP_Resource tcp_socket); + /** + * Sets an option on |tcp_socket|. Supported |name| and |value| parameters + * are as described for PP_TCPSocketOption_Private. |callback| will be + * invoked with PP_OK if setting the option succeeds, or an error code + * otherwise. The socket must be connection before SetOption is called. + */ + int32_t (*SetOption)(PP_Resource tcp_socket, + PP_TCPSocketOption_Private name, + struct PP_Var value, + struct PP_CompletionCallback callback); }; -typedef struct PPB_TCPSocket_Private_0_4 PPB_TCPSocket_Private; +typedef struct PPB_TCPSocket_Private_0_5 PPB_TCPSocket_Private; struct PPB_TCPSocket_Private_0_3 { PP_Resource (*Create)(PP_Instance instance); @@ -171,6 +200,39 @@ struct PPB_TCPSocket_Private_0_3 { struct PP_CompletionCallback callback); void (*Disconnect)(PP_Resource tcp_socket); }; + +struct PPB_TCPSocket_Private_0_4 { + PP_Resource (*Create)(PP_Instance instance); + PP_Bool (*IsTCPSocket)(PP_Resource resource); + int32_t (*Connect)(PP_Resource tcp_socket, + const char* host, + uint16_t port, + struct PP_CompletionCallback callback); + int32_t (*ConnectWithNetAddress)(PP_Resource tcp_socket, + const struct PP_NetAddress_Private* addr, + struct PP_CompletionCallback callback); + PP_Bool (*GetLocalAddress)(PP_Resource tcp_socket, + struct PP_NetAddress_Private* local_addr); + PP_Bool (*GetRemoteAddress)(PP_Resource tcp_socket, + struct PP_NetAddress_Private* remote_addr); + int32_t (*SSLHandshake)(PP_Resource tcp_socket, + const char* server_name, + uint16_t server_port, + struct PP_CompletionCallback callback); + PP_Resource (*GetServerCertificate)(PP_Resource tcp_socket); + PP_Bool (*AddChainBuildingCertificate)(PP_Resource tcp_socket, + PP_Resource certificate, + PP_Bool is_trusted); + int32_t (*Read)(PP_Resource tcp_socket, + char* buffer, + int32_t bytes_to_read, + struct PP_CompletionCallback callback); + int32_t (*Write)(PP_Resource tcp_socket, + const char* buffer, + int32_t bytes_to_write, + struct PP_CompletionCallback callback); + void (*Disconnect)(PP_Resource tcp_socket); +}; /** * @} */ diff --git a/ppapi/cpp/private/tcp_socket_private.cc b/ppapi/cpp/private/tcp_socket_private.cc index f60f2ef..996e0a0 100644 --- a/ppapi/cpp/private/tcp_socket_private.cc +++ b/ppapi/cpp/private/tcp_socket_private.cc @@ -15,6 +15,10 @@ namespace pp { namespace { +template <> const char* interface_name<PPB_TCPSocket_Private_0_5>() { + return PPB_TCPSOCKET_PRIVATE_INTERFACE_0_5; +} + template <> const char* interface_name<PPB_TCPSocket_Private_0_4>() { return PPB_TCPSOCKET_PRIVATE_INTERFACE_0_4; } @@ -26,7 +30,10 @@ template <> const char* interface_name<PPB_TCPSocket_Private_0_3>() { } // namespace TCPSocketPrivate::TCPSocketPrivate(const InstanceHandle& instance) { - if (has_interface<PPB_TCPSocket_Private_0_4>()) { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + PassRefFromConstructor(get_interface<PPB_TCPSocket_Private_0_5>()->Create( + instance.pp_instance())); + } else if (has_interface<PPB_TCPSocket_Private_0_4>()) { PassRefFromConstructor(get_interface<PPB_TCPSocket_Private_0_4>()->Create( instance.pp_instance())); } else if (has_interface<PPB_TCPSocket_Private_0_3>()) { @@ -41,13 +48,18 @@ TCPSocketPrivate::TCPSocketPrivate(PassRef, PP_Resource resource) // static bool TCPSocketPrivate::IsAvailable() { - return has_interface<PPB_TCPSocket_Private_0_4>() || + return has_interface<PPB_TCPSocket_Private_0_5>() || + has_interface<PPB_TCPSocket_Private_0_4>() || has_interface<PPB_TCPSocket_Private_0_3>(); } int32_t TCPSocketPrivate::Connect(const char* host, uint16_t port, const CompletionCallback& callback) { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + return get_interface<PPB_TCPSocket_Private_0_5>()->Connect( + pp_resource(), host, port, callback.pp_completion_callback()); + } if (has_interface<PPB_TCPSocket_Private_0_4>()) { return get_interface<PPB_TCPSocket_Private_0_4>()->Connect( pp_resource(), host, port, callback.pp_completion_callback()); @@ -62,6 +74,10 @@ int32_t TCPSocketPrivate::Connect(const char* host, int32_t TCPSocketPrivate::ConnectWithNetAddress( const PP_NetAddress_Private* addr, const CompletionCallback& callback) { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + return get_interface<PPB_TCPSocket_Private_0_5>()->ConnectWithNetAddress( + pp_resource(), addr, callback.pp_completion_callback()); + } if (has_interface<PPB_TCPSocket_Private_0_4>()) { return get_interface<PPB_TCPSocket_Private_0_4>()->ConnectWithNetAddress( pp_resource(), addr, callback.pp_completion_callback()); @@ -74,6 +90,11 @@ int32_t TCPSocketPrivate::ConnectWithNetAddress( } bool TCPSocketPrivate::GetLocalAddress(PP_NetAddress_Private* local_addr) { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + PP_Bool result = get_interface<PPB_TCPSocket_Private_0_5>()-> + GetLocalAddress(pp_resource(), local_addr); + return PP_ToBool(result); + } if (has_interface<PPB_TCPSocket_Private_0_4>()) { PP_Bool result = get_interface<PPB_TCPSocket_Private_0_4>()-> GetLocalAddress(pp_resource(), local_addr); @@ -88,6 +109,11 @@ bool TCPSocketPrivate::GetLocalAddress(PP_NetAddress_Private* local_addr) { } bool TCPSocketPrivate::GetRemoteAddress(PP_NetAddress_Private* remote_addr) { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + PP_Bool result = get_interface<PPB_TCPSocket_Private_0_5>()-> + GetRemoteAddress(pp_resource(), remote_addr); + return PP_ToBool(result); + } if (has_interface<PPB_TCPSocket_Private_0_4>()) { PP_Bool result = get_interface<PPB_TCPSocket_Private_0_4>()-> GetRemoteAddress(pp_resource(), remote_addr); @@ -104,6 +130,11 @@ bool TCPSocketPrivate::GetRemoteAddress(PP_NetAddress_Private* remote_addr) { int32_t TCPSocketPrivate::SSLHandshake(const char* server_name, uint16_t server_port, const CompletionCallback& callback) { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + return get_interface<PPB_TCPSocket_Private_0_5>()->SSLHandshake( + pp_resource(), server_name, server_port, + callback.pp_completion_callback()); + } if (has_interface<PPB_TCPSocket_Private_0_4>()) { return get_interface<PPB_TCPSocket_Private_0_4>()->SSLHandshake( pp_resource(), server_name, server_port, @@ -118,6 +149,11 @@ int32_t TCPSocketPrivate::SSLHandshake(const char* server_name, } X509CertificatePrivate TCPSocketPrivate::GetServerCertificate() { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + return X509CertificatePrivate(PASS_REF, + get_interface<PPB_TCPSocket_Private_0_5>()->GetServerCertificate( + pp_resource())); + } if (has_interface<PPB_TCPSocket_Private_0_4>()) { return X509CertificatePrivate(PASS_REF, get_interface<PPB_TCPSocket_Private_0_4>()->GetServerCertificate( @@ -129,6 +165,11 @@ X509CertificatePrivate TCPSocketPrivate::GetServerCertificate() { bool TCPSocketPrivate::AddChainBuildingCertificate( const X509CertificatePrivate& cert, bool trusted) { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + return PP_ToBool(get_interface<PPB_TCPSocket_Private_0_5>()-> + AddChainBuildingCertificate(pp_resource(), cert.pp_resource(), + PP_FromBool(trusted))); + } if (has_interface<PPB_TCPSocket_Private_0_4>()) { return PP_ToBool(get_interface<PPB_TCPSocket_Private_0_4>()-> AddChainBuildingCertificate(pp_resource(), cert.pp_resource(), @@ -140,6 +181,11 @@ bool TCPSocketPrivate::AddChainBuildingCertificate( int32_t TCPSocketPrivate::Read(char* buffer, int32_t bytes_to_read, const CompletionCallback& callback) { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + return get_interface<PPB_TCPSocket_Private_0_5>()->Read( + pp_resource(), buffer, bytes_to_read, + callback.pp_completion_callback()); + } if (has_interface<PPB_TCPSocket_Private_0_4>()) { return get_interface<PPB_TCPSocket_Private_0_4>()->Read( pp_resource(), buffer, bytes_to_read, @@ -156,6 +202,11 @@ int32_t TCPSocketPrivate::Read(char* buffer, int32_t TCPSocketPrivate::Write(const char* buffer, int32_t bytes_to_write, const CompletionCallback& callback) { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + return get_interface<PPB_TCPSocket_Private_0_5>()->Write( + pp_resource(), buffer, bytes_to_write, + callback.pp_completion_callback()); + } if (has_interface<PPB_TCPSocket_Private_0_4>()) { return get_interface<PPB_TCPSocket_Private_0_4>()->Write( pp_resource(), buffer, bytes_to_write, @@ -170,6 +221,10 @@ int32_t TCPSocketPrivate::Write(const char* buffer, } void TCPSocketPrivate::Disconnect() { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + return get_interface<PPB_TCPSocket_Private_0_5>()->Disconnect( + pp_resource()); + } if (has_interface<PPB_TCPSocket_Private_0_4>()) { return get_interface<PPB_TCPSocket_Private_0_4>()->Disconnect( pp_resource()); @@ -180,4 +235,14 @@ void TCPSocketPrivate::Disconnect() { } } +int32_t TCPSocketPrivate::SetOption(PP_TCPSocketOption_Private name, + const Var& value, + const CompletionCallback& callback) { + if (has_interface<PPB_TCPSocket_Private_0_5>()) { + return get_interface<PPB_TCPSocket_Private_0_5>()->SetOption( + pp_resource(), name, value.pp_var(), callback.pp_completion_callback()); + } + return callback.MayForce(PP_ERROR_NOINTERFACE); +} + } // namespace pp diff --git a/ppapi/cpp/private/tcp_socket_private.h b/ppapi/cpp/private/tcp_socket_private.h index 5f2b771..12e435e 100644 --- a/ppapi/cpp/private/tcp_socket_private.h +++ b/ppapi/cpp/private/tcp_socket_private.h @@ -46,6 +46,9 @@ class TCPSocketPrivate : public Resource { int32_t bytes_to_write, const CompletionCallback& callback); void Disconnect(); + int32_t SetOption(PP_TCPSocketOption_Private name, + const Var& value, + 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 62d984a..270a5c3 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 @@ -1,4 +1,4 @@ -/* Copyright (c) 2012 The Chromium Authors. All rights reserved. +/* Copyright (c) 2013 The Chromium Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -252,6 +252,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Talk_Private_1_0; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TCPServerSocket_Private_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_3; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_4; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_2; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_3; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_4; @@ -3254,6 +3255,88 @@ void Pnacl_M20_PPB_TCPSocket_Private_Disconnect(PP_Resource tcp_socket) { /* End wrapper methods for PPB_TCPSocket_Private_0_4 */ +/* Begin wrapper methods for PPB_TCPSocket_Private_0_5 */ + +static __attribute__((pnaclcall)) +PP_Resource Pnacl_M27_PPB_TCPSocket_Private_Create(PP_Instance instance) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->Create(instance); +} + +static __attribute__((pnaclcall)) +PP_Bool Pnacl_M27_PPB_TCPSocket_Private_IsTCPSocket(PP_Resource resource) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->IsTCPSocket(resource); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M27_PPB_TCPSocket_Private_Connect(PP_Resource tcp_socket, const char* host, uint16_t port, struct PP_CompletionCallback callback) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->Connect(tcp_socket, host, port, callback); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M27_PPB_TCPSocket_Private_ConnectWithNetAddress(PP_Resource tcp_socket, const struct PP_NetAddress_Private* addr, struct PP_CompletionCallback callback) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->ConnectWithNetAddress(tcp_socket, addr, callback); +} + +static __attribute__((pnaclcall)) +PP_Bool Pnacl_M27_PPB_TCPSocket_Private_GetLocalAddress(PP_Resource tcp_socket, struct PP_NetAddress_Private* local_addr) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->GetLocalAddress(tcp_socket, local_addr); +} + +static __attribute__((pnaclcall)) +PP_Bool Pnacl_M27_PPB_TCPSocket_Private_GetRemoteAddress(PP_Resource tcp_socket, struct PP_NetAddress_Private* remote_addr) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->GetRemoteAddress(tcp_socket, remote_addr); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M27_PPB_TCPSocket_Private_SSLHandshake(PP_Resource tcp_socket, const char* server_name, uint16_t server_port, struct PP_CompletionCallback callback) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->SSLHandshake(tcp_socket, server_name, server_port, callback); +} + +static __attribute__((pnaclcall)) +PP_Resource Pnacl_M27_PPB_TCPSocket_Private_GetServerCertificate(PP_Resource tcp_socket) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->GetServerCertificate(tcp_socket); +} + +static __attribute__((pnaclcall)) +PP_Bool Pnacl_M27_PPB_TCPSocket_Private_AddChainBuildingCertificate(PP_Resource tcp_socket, PP_Resource certificate, PP_Bool is_trusted) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->AddChainBuildingCertificate(tcp_socket, certificate, is_trusted); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M27_PPB_TCPSocket_Private_Read(PP_Resource tcp_socket, char* buffer, int32_t bytes_to_read, struct PP_CompletionCallback callback) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->Read(tcp_socket, buffer, bytes_to_read, callback); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M27_PPB_TCPSocket_Private_Write(PP_Resource tcp_socket, const char* buffer, int32_t bytes_to_write, struct PP_CompletionCallback callback) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->Write(tcp_socket, buffer, bytes_to_write, callback); +} + +static __attribute__((pnaclcall)) +void Pnacl_M27_PPB_TCPSocket_Private_Disconnect(PP_Resource tcp_socket) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + iface->Disconnect(tcp_socket); +} + +static __attribute__((pnaclcall)) +int32_t Pnacl_M27_PPB_TCPSocket_Private_SetOption(PP_Resource tcp_socket, PP_TCPSocketOption_Private name, struct PP_Var value, struct PP_CompletionCallback callback) { + const struct PPB_TCPSocket_Private_0_5 *iface = Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5.real_iface; + return iface->SetOption(tcp_socket, name, value, callback); +} + +/* End wrapper methods for PPB_TCPSocket_Private_0_5 */ + /* Begin wrapper methods for PPB_UDPSocket_Private_0_2 */ static __attribute__((pnaclcall)) @@ -4289,6 +4372,22 @@ struct PPB_TCPSocket_Private_0_4 Pnacl_Wrappers_PPB_TCPSocket_Private_0_4 = { .Disconnect = (void (*)(PP_Resource tcp_socket))&Pnacl_M20_PPB_TCPSocket_Private_Disconnect }; +struct PPB_TCPSocket_Private_0_5 Pnacl_Wrappers_PPB_TCPSocket_Private_0_5 = { + .Create = (PP_Resource (*)(PP_Instance instance))&Pnacl_M27_PPB_TCPSocket_Private_Create, + .IsTCPSocket = (PP_Bool (*)(PP_Resource resource))&Pnacl_M27_PPB_TCPSocket_Private_IsTCPSocket, + .Connect = (int32_t (*)(PP_Resource tcp_socket, const char* host, uint16_t port, struct PP_CompletionCallback callback))&Pnacl_M27_PPB_TCPSocket_Private_Connect, + .ConnectWithNetAddress = (int32_t (*)(PP_Resource tcp_socket, const struct PP_NetAddress_Private* addr, struct PP_CompletionCallback callback))&Pnacl_M27_PPB_TCPSocket_Private_ConnectWithNetAddress, + .GetLocalAddress = (PP_Bool (*)(PP_Resource tcp_socket, struct PP_NetAddress_Private* local_addr))&Pnacl_M27_PPB_TCPSocket_Private_GetLocalAddress, + .GetRemoteAddress = (PP_Bool (*)(PP_Resource tcp_socket, struct PP_NetAddress_Private* remote_addr))&Pnacl_M27_PPB_TCPSocket_Private_GetRemoteAddress, + .SSLHandshake = (int32_t (*)(PP_Resource tcp_socket, const char* server_name, uint16_t server_port, struct PP_CompletionCallback callback))&Pnacl_M27_PPB_TCPSocket_Private_SSLHandshake, + .GetServerCertificate = (PP_Resource (*)(PP_Resource tcp_socket))&Pnacl_M27_PPB_TCPSocket_Private_GetServerCertificate, + .AddChainBuildingCertificate = (PP_Bool (*)(PP_Resource tcp_socket, PP_Resource certificate, PP_Bool is_trusted))&Pnacl_M27_PPB_TCPSocket_Private_AddChainBuildingCertificate, + .Read = (int32_t (*)(PP_Resource tcp_socket, char* buffer, int32_t bytes_to_read, struct PP_CompletionCallback callback))&Pnacl_M27_PPB_TCPSocket_Private_Read, + .Write = (int32_t (*)(PP_Resource tcp_socket, const char* buffer, int32_t bytes_to_write, struct PP_CompletionCallback callback))&Pnacl_M27_PPB_TCPSocket_Private_Write, + .Disconnect = (void (*)(PP_Resource tcp_socket))&Pnacl_M27_PPB_TCPSocket_Private_Disconnect, + .SetOption = (int32_t (*)(PP_Resource tcp_socket, PP_TCPSocketOption_Private name, struct PP_Var value, struct PP_CompletionCallback callback))&Pnacl_M27_PPB_TCPSocket_Private_SetOption +}; + struct PPB_UDPSocket_Private_0_2 Pnacl_Wrappers_PPB_UDPSocket_Private_0_2 = { .Create = (PP_Resource (*)(PP_Instance instance_id))&Pnacl_M17_PPB_UDPSocket_Private_Create, .IsUDPSocket = (PP_Bool (*)(PP_Resource resource_id))&Pnacl_M17_PPB_UDPSocket_Private_IsUDPSocket, @@ -5113,6 +5212,12 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_4 = { .real_iface = NULL }; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5 = { + .iface_macro = PPB_TCPSOCKET_PRIVATE_INTERFACE_0_5, + .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_TCPSocket_Private_0_5, + .real_iface = NULL +}; + static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_2 = { .iface_macro = PPB_UDPSOCKET_PRIVATE_INTERFACE_0_2, .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_UDPSocket_Private_0_2, @@ -5282,6 +5387,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = { &Pnacl_WrapperInfo_PPB_TCPServerSocket_Private_0_1, &Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_3, &Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_4, + &Pnacl_WrapperInfo_PPB_TCPSocket_Private_0_5, &Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_2, &Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_3, &Pnacl_WrapperInfo_PPB_UDPSocket_Private_0_4, diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index e1d496a..f27c803 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -674,6 +674,10 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPSocket_WriteACK, uint32 /* socket_id */, bool /* succeeded */, int32_t /* bytes_written */) +IPC_MESSAGE_ROUTED3(PpapiMsg_PPBTCPSocket_SetBoolOptionACK, + uint32 /* plugin_dispatcher_id */, + uint32 /* socket_id */, + bool /* succeeded */) // PPB_URLLoader_Trusted IPC_MESSAGE_ROUTED1( @@ -1200,6 +1204,10 @@ IPC_MESSAGE_CONTROL2(PpapiHostMsg_PPBTCPSocket_Write, std::string /* data */) IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBTCPSocket_Disconnect, uint32 /* socket_id */) +IPC_MESSAGE_CONTROL3(PpapiHostMsg_PPBTCPSocket_SetBoolOption, + uint32 /* socket_id */, + uint32 /* name */, + bool /* value */) // UDPSocketPrivate. IPC_MESSAGE_CONTROL0(PpapiHostMsg_UDPSocketPrivate_Create) diff --git a/ppapi/proxy/ppb_tcp_socket_private_proxy.cc b/ppapi/proxy/ppb_tcp_socket_private_proxy.cc index 7f11b28..7f7fb78 100644 --- a/ppapi/proxy/ppb_tcp_socket_private_proxy.cc +++ b/ppapi/proxy/ppb_tcp_socket_private_proxy.cc @@ -46,6 +46,8 @@ class TCPSocket : public TCPSocketPrivateImpl { virtual void SendRead(int32_t bytes_to_read) OVERRIDE; virtual void SendWrite(const std::string& buffer) OVERRIDE; virtual void SendDisconnect() OVERRIDE; + virtual void SendSetBoolOption(PP_TCPSocketOption_Private name, + bool value) OVERRIDE; private: void SendToBrowser(IPC::Message* msg); @@ -116,6 +118,11 @@ void TCPSocket::SendDisconnect() { SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Disconnect(socket_id_)); } +void TCPSocket::SendSetBoolOption(PP_TCPSocketOption_Private name, bool value) { + SendToBrowser( + new PpapiHostMsg_PPBTCPSocket_SetBoolOption(socket_id_, name, value)); +} + void TCPSocket::SendToBrowser(IPC::Message* msg) { PluginGlobals::Get()->GetBrowserSender()->Send(msg); } @@ -170,6 +177,8 @@ bool PPB_TCPSocket_Private_Proxy::OnMessageReceived(const IPC::Message& msg) { OnMsgSSLHandshakeACK) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ReadACK, OnMsgReadACK) IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_WriteACK, OnMsgWriteACK) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetBoolOptionACK, + OnMsgSetBoolOptionACK) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -236,5 +245,19 @@ void PPB_TCPSocket_Private_Proxy::OnMsgWriteACK( iter->second->OnWriteCompleted(succeeded, bytes_written); } +void PPB_TCPSocket_Private_Proxy::OnMsgSetBoolOptionACK( + uint32 /* plugin_dispatcher_id */, + uint32 socket_id, + bool succeeded) { + if (!g_id_to_socket) { + NOTREACHED(); + return; + } + IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id); + if (iter == g_id_to_socket->end()) + return; + iter->second->OnSetOptionCompleted(succeeded); +} + } // namespace proxy } // namespace ppapi diff --git a/ppapi/proxy/ppb_tcp_socket_private_proxy.h b/ppapi/proxy/ppb_tcp_socket_private_proxy.h index 4667216..ffceca7 100644 --- a/ppapi/proxy/ppb_tcp_socket_private_proxy.h +++ b/ppapi/proxy/ppb_tcp_socket_private_proxy.h @@ -57,6 +57,9 @@ class PPB_TCPSocket_Private_Proxy : public InterfaceProxy { uint32 socket_id, bool succeeded, int32_t bytes_written); + void OnMsgSetBoolOptionACK(uint32 plugin_dispatcher_id, + uint32 socket_id, + bool succeeded); DISALLOW_COPY_AND_ASSIGN(PPB_TCPSocket_Private_Proxy); }; diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.cc b/ppapi/shared_impl/private/tcp_socket_private_impl.cc index e2c645f0..87cc600 100644 --- a/ppapi/shared_impl/private/tcp_socket_private_impl.cc +++ b/ppapi/shared_impl/private/tcp_socket_private_impl.cc @@ -212,11 +212,34 @@ void TCPSocketPrivateImpl::Disconnect() { PostAbortIfNecessary(&ssl_handshake_callback_); PostAbortIfNecessary(&read_callback_); PostAbortIfNecessary(&write_callback_); + PostAbortIfNecessary(&set_option_callback_); read_buffer_ = NULL; bytes_to_read_ = -1; server_certificate_ = NULL; } +int32_t TCPSocketPrivateImpl::SetOption( + PP_TCPSocketOption_Private name, + const PP_Var& value, + scoped_refptr<TrackedCallback> callback) { + if (!IsConnected()) + return PP_ERROR_FAILED; + if (TrackedCallback::IsPending(set_option_callback_)) + return PP_ERROR_INPROGRESS; + + set_option_callback_ = callback; + + switch (name) { + case PP_TCPSOCKETOPTION_NO_DELAY: + if (value.type != PP_VARTYPE_BOOL) + return PP_ERROR_BADARGUMENT; + SendSetBoolOption(name, PP_ToBool(value.value.as_bool)); + return PP_OK_COMPLETIONPENDING; + default: + return PP_ERROR_BADARGUMENT; + } +} + void TCPSocketPrivateImpl::OnConnectCompleted( bool succeeded, const PP_NetAddress_Private& local_addr, @@ -293,6 +316,15 @@ void TCPSocketPrivateImpl::OnWriteCompleted(bool succeeded, succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED)); } +void TCPSocketPrivateImpl::OnSetOptionCompleted(bool succeeded) { + if (!TrackedCallback::IsPending(set_option_callback_)) { + NOTREACHED(); + return; + } + + set_option_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED); +} + void TCPSocketPrivateImpl::Init(uint32 socket_id) { DCHECK(socket_id != 0); socket_id_ = socket_id; diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.h b/ppapi/shared_impl/private/tcp_socket_private_impl.h index 2792102..95057e7 100644 --- a/ppapi/shared_impl/private/tcp_socket_private_impl.h +++ b/ppapi/shared_impl/private/tcp_socket_private_impl.h @@ -66,6 +66,9 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl int32_t bytes_to_write, scoped_refptr<TrackedCallback> callback) OVERRIDE; virtual void Disconnect() OVERRIDE; + virtual int32_t SetOption(PP_TCPSocketOption_Private name, + const PP_Var& value, + scoped_refptr<TrackedCallback> callback) OVERRIDE; // Notifications on operations completion. void OnConnectCompleted(bool succeeded, @@ -76,6 +79,7 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl const PPB_X509Certificate_Fields& certificate_fields); void OnReadCompleted(bool succeeded, const std::string& data); void OnWriteCompleted(bool succeeded, int32_t bytes_written); + void OnSetOptionCompleted(bool succeeded); // Send functions that need to be implemented differently for the // proxied and non-proxied derived classes. @@ -89,6 +93,8 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl virtual void SendRead(int32_t bytes_to_read) = 0; virtual void SendWrite(const std::string& buffer) = 0; virtual void SendDisconnect() = 0; + virtual void SendSetBoolOption(PP_TCPSocketOption_Private name, + bool value) = 0; protected: enum ConnectionState { @@ -117,6 +123,7 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl scoped_refptr<TrackedCallback> ssl_handshake_callback_; scoped_refptr<TrackedCallback> read_callback_; scoped_refptr<TrackedCallback> write_callback_; + scoped_refptr<TrackedCallback> set_option_callback_; char* read_buffer_; int32_t bytes_to_read_; diff --git a/ppapi/tests/test_tcp_socket_private.cc b/ppapi/tests/test_tcp_socket_private.cc index 6bffe49..17fbe1a 100644 --- a/ppapi/tests/test_tcp_socket_private.cc +++ b/ppapi/tests/test_tcp_socket_private.cc @@ -51,6 +51,7 @@ void TestTCPSocketPrivate::RunTests(const std::string& filter) { RUN_TEST_FORCEASYNC_AND_NOT(ReadWrite, filter); RUN_TEST_FORCEASYNC_AND_NOT(ReadWriteSSL, filter); RUN_TEST_FORCEASYNC_AND_NOT(ConnectAddress, filter); + RUN_TEST_FORCEASYNC_AND_NOT(SetOption, filter); } std::string TestTCPSocketPrivate::TestBasic() { @@ -160,6 +161,39 @@ std::string TestTCPSocketPrivate::TestConnectAddress() { PASS(); } +std::string TestTCPSocketPrivate::TestSetOption() { + pp::TCPSocketPrivate socket(instance_); + TestCompletionCallback cb(instance_->pp_instance(), force_async_); + + int32_t rv = socket.SetOption(PP_TCPSOCKETOPTION_NO_DELAY, true, cb); + ASSERT_TRUE(!force_async_ || rv == PP_OK_COMPLETIONPENDING); + if (rv == PP_OK_COMPLETIONPENDING) + rv = cb.WaitForResult(); + ASSERT_EQ(PP_ERROR_FAILED, rv); + + rv = socket.Connect(host_.c_str(), port_, cb); + ASSERT_TRUE(!force_async_ || rv == PP_OK_COMPLETIONPENDING); + if (rv == PP_OK_COMPLETIONPENDING) + rv = cb.WaitForResult(); + ASSERT_EQ(PP_OK, rv); + + rv = socket.SetOption(PP_TCPSOCKETOPTION_NO_DELAY, true, cb); + ASSERT_TRUE(!force_async_ || rv == PP_OK_COMPLETIONPENDING); + if (rv == PP_OK_COMPLETIONPENDING) + rv = cb.WaitForResult(); + ASSERT_EQ(PP_OK, rv); + + rv = socket.SetOption(PP_TCPSOCKETOPTION_INVALID, true, cb); + ASSERT_TRUE(!force_async_ || rv == PP_OK_COMPLETIONPENDING); + if (rv == PP_OK_COMPLETIONPENDING) + rv = cb.WaitForResult(); + ASSERT_EQ(PP_ERROR_BADARGUMENT, rv); + + socket.Disconnect(); + + PASS(); +} + int32_t TestTCPSocketPrivate::ReadFirstLineFromSocket( pp::TCPSocketPrivate* socket, std::string* s) { diff --git a/ppapi/tests/test_tcp_socket_private.h b/ppapi/tests/test_tcp_socket_private.h index 4c31853..a7b747f 100644 --- a/ppapi/tests/test_tcp_socket_private.h +++ b/ppapi/tests/test_tcp_socket_private.h @@ -27,6 +27,7 @@ class TestTCPSocketPrivate : public TestCase { std::string TestReadWrite(); std::string TestReadWriteSSL(); std::string TestConnectAddress(); + std::string TestSetOption(); int32_t ReadFirstLineFromSocket(pp::TCPSocketPrivate* socket, std::string* s); int32_t WriteStringToSocket(pp::TCPSocketPrivate* socket, diff --git a/ppapi/thunk/interfaces_ppb_private_no_permissions.h b/ppapi/thunk/interfaces_ppb_private_no_permissions.h index 793d1bb..059f603 100644 --- a/ppapi/thunk/interfaces_ppb_private_no_permissions.h +++ b/ppapi/thunk/interfaces_ppb_private_no_permissions.h @@ -23,6 +23,8 @@ PROXIED_IFACE(PPB_TCPSocket_Private, PPB_TCPSOCKET_PRIVATE_INTERFACE_0_3, PPB_TCPSocket_Private_0_3) PROXIED_IFACE(PPB_TCPSocket_Private, PPB_TCPSOCKET_PRIVATE_INTERFACE_0_4, PPB_TCPSocket_Private_0_4) +PROXIED_IFACE(PPB_TCPSocket_Private, PPB_TCPSOCKET_PRIVATE_INTERFACE_0_5, + PPB_TCPSocket_Private_0_5) PROXIED_IFACE(NoAPIName, PPB_UDPSOCKET_PRIVATE_INTERFACE_0_2, PPB_UDPSocket_Private_0_2) PROXIED_IFACE(NoAPIName, PPB_UDPSOCKET_PRIVATE_INTERFACE_0_3, diff --git a/ppapi/thunk/ppb_tcp_socket_private_api.h b/ppapi/thunk/ppb_tcp_socket_private_api.h index 1311a20..ebc8070 100644 --- a/ppapi/thunk/ppb_tcp_socket_private_api.h +++ b/ppapi/thunk/ppb_tcp_socket_private_api.h @@ -40,6 +40,9 @@ class PPAPI_THUNK_EXPORT PPB_TCPSocket_Private_API { int32_t bytes_to_write, scoped_refptr<TrackedCallback> callback) = 0; virtual void Disconnect() = 0; + virtual int32_t SetOption(PP_TCPSocketOption_Private name, + const PP_Var& value, + scoped_refptr<TrackedCallback> callback) = 0; }; } // namespace thunk diff --git a/ppapi/thunk/ppb_tcp_socket_private_thunk.cc b/ppapi/thunk/ppb_tcp_socket_private_thunk.cc index 425f5ad..928f073 100644 --- a/ppapi/thunk/ppb_tcp_socket_private_thunk.cc +++ b/ppapi/thunk/ppb_tcp_socket_private_thunk.cc @@ -121,6 +121,17 @@ void Disconnect(PP_Resource tcp_socket) { enter.object()->Disconnect(); } +int32_t SetOption(PP_Resource tcp_socket, + PP_TCPSocketOption_Private name, + PP_Var value, + PP_CompletionCallback callback) { + EnterTCP enter(tcp_socket, callback, true); + if (enter.failed()) + return enter.retval(); + return enter.SetResult( + enter.object()->SetOption(name, value, enter.callback())); +} + const PPB_TCPSocket_Private_0_3 g_ppb_tcp_socket_thunk_0_3 = { &Create, &IsTCPSocket, @@ -134,7 +145,7 @@ const PPB_TCPSocket_Private_0_3 g_ppb_tcp_socket_thunk_0_3 = { &Disconnect }; -const PPB_TCPSocket_Private g_ppb_tcp_socket_thunk_0_4 = { +const PPB_TCPSocket_Private_0_4 g_ppb_tcp_socket_thunk_0_4 = { &Create, &IsTCPSocket, &Connect, @@ -149,6 +160,22 @@ const PPB_TCPSocket_Private g_ppb_tcp_socket_thunk_0_4 = { &Disconnect }; +const PPB_TCPSocket_Private_0_5 g_ppb_tcp_socket_thunk_0_5 = { + &Create, + &IsTCPSocket, + &Connect, + &ConnectWithNetAddress, + &GetLocalAddress, + &GetRemoteAddress, + &SSLHandshake, + &GetServerCertificate, + &AddChainBuildingCertificate, + &Read, + &Write, + &Disconnect, + &SetOption +}; + } // namespace const PPB_TCPSocket_Private_0_3* GetPPB_TCPSocket_Private_0_3_Thunk() { @@ -159,5 +186,9 @@ const PPB_TCPSocket_Private_0_4* GetPPB_TCPSocket_Private_0_4_Thunk() { return &g_ppb_tcp_socket_thunk_0_4; } +const PPB_TCPSocket_Private_0_5* GetPPB_TCPSocket_Private_0_5_Thunk() { + return &g_ppb_tcp_socket_thunk_0_5; +} + } // namespace thunk } // namespace ppapi |