summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/renderer_host/pepper/pepper_message_filter.cc131
-rw-r--r--content/browser/renderer_host/pepper/pepper_message_filter.h29
-rw-r--r--content/browser/renderer_host/pepper/pepper_tcp_socket.cc254
-rw-r--r--content/browser/renderer_host/pepper/pepper_tcp_socket.h33
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.cc39
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.h20
-rw-r--r--ppapi/api/dev/ppb_tcp_socket_dev.idl5
-rw-r--r--ppapi/c/dev/ppb_tcp_socket_dev.h9
-rw-r--r--ppapi/proxy/ppapi_messages.h33
-rw-r--r--ppapi/proxy/ppb_tcp_socket_private_proxy.cc34
-rw-r--r--ppapi/proxy/ppb_tcp_socket_private_proxy.h13
-rw-r--r--ppapi/proxy/ppb_tcp_socket_proxy.cc42
-rw-r--r--ppapi/proxy/ppb_tcp_socket_proxy.h13
-rw-r--r--ppapi/shared_impl/private/tcp_socket_private_impl.cc22
-rw-r--r--ppapi/shared_impl/private/tcp_socket_private_impl.h3
-rw-r--r--ppapi/shared_impl/tcp_socket_shared.cc75
-rw-r--r--ppapi/shared_impl/tcp_socket_shared.h35
-rw-r--r--ppapi/tests/test_tcp_socket.cc61
-rw-r--r--webkit/plugins/ppapi/mock_plugin_delegate.cc7
-rw-r--r--webkit/plugins/ppapi/mock_plugin_delegate.h6
-rw-r--r--webkit/plugins/ppapi/plugin_delegate.h8
-rw-r--r--webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc9
-rw-r--r--webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h4
23 files changed, 564 insertions, 321 deletions
diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.cc b/content/browser/renderer_host/pepper/pepper_message_filter.cc
index 8db9bc4..573ff03 100644
--- a/content/browser/renderer_host/pepper/pepper_message_filter.cc
+++ b/content/browser/renderer_host/pepper/pepper_message_filter.cc
@@ -37,6 +37,7 @@
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/api_id.h"
#include "ppapi/shared_impl/private/net_address_private_impl.h"
+#include "ppapi/shared_impl/socket_option_data.h"
using ppapi::NetAddressPrivateImpl;
@@ -96,11 +97,8 @@ PepperMessageFilter::PepperMessageFilter(
void PepperMessageFilter::OverrideThreadForMessage(
const IPC::Message& message,
BrowserThread::ID* thread) {
- if (message.type() == PpapiHostMsg_PPBTCPServerSocket_Listen::ID ||
- message.type() == PpapiHostMsg_PPBTCPSocket_Connect::ID ||
- message.type() == PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress::ID) {
+ if (message.type() == PpapiHostMsg_PPBTCPServerSocket_Listen::ID)
*thread = BrowserThread::UI;
- }
}
bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg,
@@ -109,6 +107,8 @@ bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg,
IPC_BEGIN_MESSAGE_MAP_EX(PepperMessageFilter, msg, *message_was_ok)
// TCP messages.
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Create, OnTCPCreate)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_CreatePrivate,
+ OnTCPCreatePrivate)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Connect, OnTCPConnect)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress,
OnTCPConnectWithNetAddress)
@@ -117,8 +117,7 @@ bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg,
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Read, OnTCPRead)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Write, OnTCPWrite)
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Disconnect, OnTCPDisconnect)
- IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_SetBoolOption,
- OnTCPSetBoolOption)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_SetOption, OnTCPSetOption)
// TCP Server messages.
IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPServerSocket_Listen,
@@ -170,16 +169,19 @@ uint32 PepperMessageFilter::AddAcceptedTCPSocket(
int32 routing_id,
uint32 plugin_dispatcher_id,
net::StreamSocket* socket) {
- scoped_ptr<net::StreamSocket> s(socket);
+ scoped_ptr<net::StreamSocket> s(socket);
uint32 tcp_socket_id = GenerateSocketID();
if (tcp_socket_id != kInvalidSocketID) {
+ // Currently all TCP sockets created this way correspond to
+ // PPB_TCPSocket_Private.
tcp_sockets_[tcp_socket_id] = linked_ptr<PepperTCPSocket>(
new PepperTCPSocket(this,
routing_id,
plugin_dispatcher_id,
tcp_socket_id,
- s.release()));
+ s.release(),
+ true /* private_api */));
}
return tcp_socket_id;
}
@@ -205,80 +207,103 @@ PepperMessageFilter::~PepperMessageFilter() {
void PepperMessageFilter::OnTCPCreate(int32 routing_id,
uint32 plugin_dispatcher_id,
uint32* socket_id) {
- *socket_id = GenerateSocketID();
- if (*socket_id == kInvalidSocketID)
- return;
+ CreateTCPSocket(routing_id, plugin_dispatcher_id, false, socket_id);
+}
- tcp_sockets_[*socket_id] = linked_ptr<PepperTCPSocket>(
- new PepperTCPSocket(this, routing_id, plugin_dispatcher_id, *socket_id));
+void PepperMessageFilter::OnTCPCreatePrivate(int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ uint32* socket_id) {
+ CreateTCPSocket(routing_id, plugin_dispatcher_id, true, socket_id);
}
void PepperMessageFilter::OnTCPConnect(int32 routing_id,
uint32 socket_id,
const std::string& host,
uint16_t port) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id);
+ if (iter == tcp_sockets_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ // This is only supported by PPB_TCPSocket_Private.
+ if (!iter->second->private_api()) {
+ NOTREACHED();
+ return;
+ }
+
content::SocketPermissionRequest params(
content::SocketPermissionRequest::TCP_CONNECT, host, port);
- bool allowed = CanUseSocketAPIs(routing_id, params);
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&PepperMessageFilter::CanUseSocketAPIs, this,
+ routing_id, params, true /* private_api */),
base::Bind(&PepperMessageFilter::DoTCPConnect, this,
- allowed, routing_id, socket_id, host, port));
+ routing_id, socket_id, host, port));
}
-void PepperMessageFilter::DoTCPConnect(bool allowed,
- int32 routing_id,
+void PepperMessageFilter::DoTCPConnect(int32 routing_id,
uint32 socket_id,
const std::string& host,
- uint16_t port) {
+ uint16_t port,
+ bool allowed) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id);
if (iter == tcp_sockets_.end()) {
// Due to current permission check process (IO -> UI -> IO) some
- // calls to TCPSocketPrivate interface can be intermixed (like
- // Connect and Close). So, NOTREACHED() is not needed there.
+ // calls to the TCP socket interface can be intermixed (like
+ // Connect and Close). So, NOTREACHED() is not appropriate here.
return;
}
if (routing_id == iter->second->routing_id() && allowed)
iter->second->Connect(host, port);
else
- iter->second->SendConnectACKError();
+ iter->second->SendConnectACKError(PP_ERROR_NOACCESS);
}
void PepperMessageFilter::OnTCPConnectWithNetAddress(
int32 routing_id,
uint32 socket_id,
const PP_NetAddress_Private& net_addr) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- bool allowed = CanUseSocketAPIs(
- routing_id,
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id);
+ if (iter == tcp_sockets_.end()) {
+ NOTREACHED();
+ return;
+ }
+
+ content::SocketPermissionRequest params =
pepper_socket_utils::CreateSocketPermissionRequest(
- content::SocketPermissionRequest::TCP_CONNECT, net_addr));
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
+ content::SocketPermissionRequest::TCP_CONNECT, net_addr);
+ BrowserThread::PostTaskAndReplyWithResult(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&PepperMessageFilter::CanUseSocketAPIs, this,
+ routing_id, params, iter->second->private_api()),
base::Bind(&PepperMessageFilter::DoTCPConnectWithNetAddress, this,
- allowed, routing_id, socket_id, net_addr));
+ routing_id, socket_id, net_addr));
}
void PepperMessageFilter::DoTCPConnectWithNetAddress(
- bool allowed,
int32 routing_id,
uint32 socket_id,
- const PP_NetAddress_Private& net_addr) {
+ const PP_NetAddress_Private& net_addr,
+ bool allowed) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id);
if (iter == tcp_sockets_.end()) {
// Due to current permission check process (IO -> UI -> IO) some
- // calls to TCPSocketPrivate interface can be intermixed (like
+ // calls to the TCP socket interface can be intermixed (like
// ConnectWithNetAddress and Close). So, NOTREACHED() is not
- // needed there.
+ // appropriate here.
return;
}
if (routing_id == iter->second->routing_id() && allowed)
iter->second->ConnectWithNetAddress(net_addr);
else
- iter->second->SendConnectACKError();
+ iter->second->SendConnectACKError(PP_ERROR_NOACCESS);
}
void PepperMessageFilter::OnTCPSSLHandshake(
@@ -293,6 +318,12 @@ void PepperMessageFilter::OnTCPSSLHandshake(
return;
}
+ // This is only supported by PPB_TCPSocket_Private.
+ if (!iter->second->private_api()) {
+ NOTREACHED();
+ return;
+ }
+
iter->second->SSLHandshake(server_name, server_port, trusted_certs,
untrusted_certs);
}
@@ -331,16 +362,16 @@ void PepperMessageFilter::OnTCPDisconnect(uint32 socket_id) {
tcp_sockets_.erase(iter);
}
-void PepperMessageFilter::OnTCPSetBoolOption(uint32 socket_id,
- uint32_t name,
- bool value) {
+void PepperMessageFilter::OnTCPSetOption(uint32 socket_id,
+ PP_TCPSocket_Option_Dev name,
+ const ppapi::SocketOptionData& value) {
TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id);
if (iter == tcp_sockets_.end()) {
NOTREACHED();
return;
}
- iter->second->SetBoolOption(name, value);
+ iter->second->SetOption(name, value);
}
void PepperMessageFilter::OnTCPServerListen(int32 routing_id,
@@ -352,7 +383,8 @@ void PepperMessageFilter::OnTCPServerListen(int32 routing_id,
bool allowed = CanUseSocketAPIs(
routing_id,
pepper_socket_utils::CreateSocketPermissionRequest(
- content::SocketPermissionRequest::TCP_LISTEN, addr));
+ content::SocketPermissionRequest::TCP_LISTEN, addr),
+ true /* private_api */);
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
base::Bind(&PepperMessageFilter::DoTCPServerListen,
this,
@@ -470,8 +502,10 @@ uint32 PepperMessageFilter::GenerateSocketID() {
return socket_id;
}
-bool PepperMessageFilter::CanUseSocketAPIs(int32 render_id,
- const content::SocketPermissionRequest& params) {
+bool PepperMessageFilter::CanUseSocketAPIs(
+ int32 render_id,
+ const content::SocketPermissionRequest& params,
+ bool private_api) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// External plugins always get their own PepperMessageFilter, initialized with
@@ -487,7 +521,7 @@ bool PepperMessageFilter::CanUseSocketAPIs(int32 render_id,
RenderViewHostImpl::FromID(process_id_, render_id);
return pepper_socket_utils::CanUseSocketAPIs(external_plugin,
- true,
+ private_api,
params,
render_view_host);
}
@@ -539,4 +573,17 @@ void PepperMessageFilter::SendNetworkList(
}
}
+void PepperMessageFilter::CreateTCPSocket(int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ bool private_api,
+ uint32* socket_id) {
+ *socket_id = GenerateSocketID();
+ if (*socket_id == kInvalidSocketID)
+ return;
+
+ tcp_sockets_[*socket_id] = linked_ptr<PepperTCPSocket>(
+ new PepperTCPSocket(this, routing_id, plugin_dispatcher_id, *socket_id,
+ private_api));
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.h b/content/browser/renderer_host/pepper/pepper_message_filter.h
index a745768..02c7abb 100644
--- a/content/browser/renderer_host/pepper/pepper_message_filter.h
+++ b/content/browser/renderer_host/pepper/pepper_message_filter.h
@@ -23,6 +23,7 @@
#include "net/http/transport_security_state.h"
#include "net/socket/stream_socket.h"
#include "net/ssl/ssl_config_service.h"
+#include "ppapi/c/dev/ppb_tcp_socket_dev.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/c/private/ppb_flash.h"
@@ -42,6 +43,7 @@ class HostResolver;
namespace ppapi {
class PPB_X509Certificate_Fields;
+class SocketOptionData;
}
namespace content {
@@ -125,6 +127,9 @@ class PepperMessageFilter
void OnTCPCreate(int32 routing_id,
uint32 plugin_dispatcher_id,
uint32* socket_id);
+ void OnTCPCreatePrivate(int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ uint32* socket_id);
void OnTCPConnect(int32 routing_id,
uint32 socket_id,
const std::string& host,
@@ -141,7 +146,9 @@ class PepperMessageFilter
void OnTCPRead(uint32 socket_id, int32_t bytes_to_read);
void OnTCPWrite(uint32 socket_id, const std::string& data);
void OnTCPDisconnect(uint32 socket_id);
- void OnTCPSetBoolOption(uint32 socket_id, uint32_t name, bool value);
+ void OnTCPSetOption(uint32 socket_id,
+ PP_TCPSocket_Option_Dev name,
+ const ppapi::SocketOptionData& value);
void OnTCPServerListen(int32 routing_id,
uint32 plugin_dispatcher_id,
PP_Resource socket_resource,
@@ -153,15 +160,15 @@ class PepperMessageFilter
void OnNetworkMonitorStart(uint32 plugin_dispatcher_id);
void OnNetworkMonitorStop(uint32 plugin_dispatcher_id);
- void DoTCPConnect(bool allowed,
- int32 routing_id,
+ void DoTCPConnect(int32 routing_id,
uint32 socket_id,
const std::string& host,
- uint16_t port);
- void DoTCPConnectWithNetAddress(bool allowed,
- int32 routing_id,
+ uint16_t port,
+ bool allowed);
+ void DoTCPConnectWithNetAddress(int32 routing_id,
uint32 socket_id,
- const PP_NetAddress_Private& net_addr);
+ const PP_NetAddress_Private& net_addr,
+ bool allowed);
void DoTCPServerListen(bool allowed,
int32 routing_id,
uint32 plugin_dispatcher_id,
@@ -177,12 +184,16 @@ class PepperMessageFilter
// Return true if render with given ID can use socket APIs.
bool CanUseSocketAPIs(int32 render_id,
- const content::SocketPermissionRequest& params);
+ const content::SocketPermissionRequest& params,
+ bool private_api);
void GetAndSendNetworkList();
void DoGetNetworkList();
void SendNetworkList(scoped_ptr<net::NetworkInterfaceList> list);
-
+ void CreateTCPSocket(int32 routing_id,
+ uint32 plugin_dispatcher_id,
+ bool private_api,
+ uint32* socket_id);
enum PluginType {
PLUGIN_TYPE_IN_PROCESS,
PLUGIN_TYPE_OUT_OF_PROCESS,
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket.cc b/content/browser/renderer_host/pepper/pepper_tcp_socket.cc
index 1f58e08..2dfb41b 100644
--- a/content/browser/renderer_host/pepper/pepper_tcp_socket.cc
+++ b/content/browser/renderer_host/pepper/pepper_tcp_socket.cc
@@ -25,11 +25,14 @@
#include "net/socket/client_socket_handle.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/tcp_client_socket.h"
+#include "ppapi/host/error_conversion.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/private/net_address_private_impl.h"
#include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
-#include "ppapi/shared_impl/private/tcp_socket_private_impl.h"
+#include "ppapi/shared_impl/socket_option_data.h"
+#include "ppapi/shared_impl/tcp_socket_shared.h"
+using ppapi::host::NetErrorToPepperError;
using ppapi::NetAddressPrivateImpl;
namespace content {
@@ -38,11 +41,13 @@ PepperTCPSocket::PepperTCPSocket(
PepperMessageFilter* manager,
int32 routing_id,
uint32 plugin_dispatcher_id,
- uint32 socket_id)
+ uint32 socket_id,
+ bool private_api)
: manager_(manager),
routing_id_(routing_id),
plugin_dispatcher_id_(plugin_dispatcher_id),
socket_id_(socket_id),
+ private_api_(private_api),
connection_state_(BEFORE_CONNECT),
end_of_file_reached_(false) {
DCHECK(manager);
@@ -53,11 +58,13 @@ PepperTCPSocket::PepperTCPSocket(
int32 routing_id,
uint32 plugin_dispatcher_id,
uint32 socket_id,
- net::StreamSocket* socket)
+ net::StreamSocket* socket,
+ bool private_api)
: manager_(manager),
routing_id_(routing_id),
plugin_dispatcher_id_(plugin_dispatcher_id),
socket_id_(socket_id),
+ private_api_(private_api),
connection_state_(CONNECTED),
end_of_file_reached_(false),
socket_(socket) {
@@ -74,7 +81,7 @@ void PepperTCPSocket::Connect(const std::string& host, uint16_t port) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (connection_state_ != BEFORE_CONNECT) {
- SendConnectACKError();
+ SendConnectACKError(PP_ERROR_FAILED);
return;
}
@@ -82,25 +89,28 @@ void PepperTCPSocket::Connect(const std::string& host, uint16_t port) {
net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port));
resolver_.reset(new net::SingleRequestHostResolver(
manager_->GetHostResolver()));
- int result = resolver_->Resolve(
+ int net_result = resolver_->Resolve(
request_info, &address_list_,
base::Bind(&PepperTCPSocket::OnResolveCompleted, base::Unretained(this)),
net::BoundNetLog());
- if (result != net::ERR_IO_PENDING)
- OnResolveCompleted(result);
+ if (net_result != net::ERR_IO_PENDING)
+ OnResolveCompleted(net_result);
}
void PepperTCPSocket::ConnectWithNetAddress(
const PP_NetAddress_Private& net_addr) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (connection_state_ != BEFORE_CONNECT) {
+ SendConnectACKError(PP_ERROR_FAILED);
+ return;
+ }
+
net::IPAddressNumber address;
int port;
- if (connection_state_ != BEFORE_CONNECT ||
- !NetAddressPrivateImpl::NetAddressToIPEndPoint(net_addr,
- &address,
+ if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(net_addr, &address,
&port)) {
- SendConnectACKError();
+ SendConnectACKError(PP_ERROR_ADDRESS_INVALID);
return;
}
@@ -147,49 +157,59 @@ void PepperTCPSocket::SSLHandshake(
return;
}
- int result = socket_->Connect(
+ int net_result = socket_->Connect(
base::Bind(&PepperTCPSocket::OnSSLHandshakeCompleted,
base::Unretained(this)));
- if (result != net::ERR_IO_PENDING)
- OnSSLHandshakeCompleted(result);
+ if (net_result != net::ERR_IO_PENDING)
+ OnSSLHandshakeCompleted(net_result);
}
void PepperTCPSocket::Read(int32 bytes_to_read) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!IsConnected() || end_of_file_reached_ || read_buffer_.get() ||
- bytes_to_read <= 0) {
- SendReadACKError();
+ if (!IsConnected() || end_of_file_reached_) {
+ SendReadACKError(PP_ERROR_FAILED);
return;
}
- if (bytes_to_read > ppapi::TCPSocketPrivateImpl::kMaxReadSize) {
- NOTREACHED();
- bytes_to_read = ppapi::TCPSocketPrivateImpl::kMaxReadSize;
+ if (read_buffer_.get()) {
+ SendReadACKError(PP_ERROR_INPROGRESS);
+ return;
+ }
+
+ if (bytes_to_read <= 0 ||
+ bytes_to_read > ppapi::TCPSocketShared::kMaxReadSize) {
+ SendReadACKError(PP_ERROR_BADARGUMENT);
+ return;
}
read_buffer_ = new net::IOBuffer(bytes_to_read);
- int result = socket_->Read(
+ int net_result = socket_->Read(
read_buffer_.get(),
bytes_to_read,
base::Bind(&PepperTCPSocket::OnReadCompleted, base::Unretained(this)));
- if (result != net::ERR_IO_PENDING)
- OnReadCompleted(result);
+ if (net_result != net::ERR_IO_PENDING)
+ OnReadCompleted(net_result);
}
void PepperTCPSocket::Write(const std::string& data) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (!IsConnected() || write_buffer_base_.get() || write_buffer_.get() ||
- data.empty()) {
- SendWriteACKError();
+ if (!IsConnected()) {
+ SendWriteACKError(PP_ERROR_FAILED);
return;
}
- int data_size = data.size();
- if (data_size > ppapi::TCPSocketPrivateImpl::kMaxWriteSize) {
- NOTREACHED();
- data_size = ppapi::TCPSocketPrivateImpl::kMaxWriteSize;
+ if (write_buffer_base_.get() || write_buffer_.get()) {
+ SendWriteACKError(PP_ERROR_INPROGRESS);
+ return;
+ }
+
+ size_t data_size = data.size();
+ if (data_size == 0 ||
+ data_size > static_cast<size_t>(ppapi::TCPSocketShared::kMaxWriteSize)) {
+ SendWriteACKError(PP_ERROR_BADARGUMENT);
+ return;
}
write_buffer_base_ = new net::IOBuffer(data_size);
@@ -199,26 +219,62 @@ void PepperTCPSocket::Write(const std::string& data) {
DoWrite();
}
-void PepperTCPSocket::SetBoolOption(uint32_t name, bool value) {
+void PepperTCPSocket::SetOption(PP_TCPSocket_Option_Dev name,
+ const ppapi::SocketOptionData& value) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DCHECK(socket_.get());
+
+ if (!IsConnected() || IsSsl()) {
+ SendSetOptionACK(PP_ERROR_FAILED);
+ return;
+ }
+
+ net::TCPClientSocket* tcp_socket =
+ static_cast<net::TCPClientSocket*>(socket_.get());
+ DCHECK(tcp_socket);
switch (name) {
- case PP_TCPSOCKETOPTION_NO_DELAY:
- if (!IsSsl()) {
- net::TCPClientSocket* tcp_socket =
- static_cast<net::TCPClientSocket*>(socket_.get());
- SendSetBoolOptionACK(tcp_socket->SetNoDelay(value));
+ case PP_TCPSOCKET_OPTION_NO_DELAY: {
+ bool boolean_value = false;
+ if (!value.GetBool(&boolean_value)) {
+ SendSetOptionACK(PP_ERROR_BADARGUMENT);
+ return;
+ }
+
+ SendSetOptionACK(
+ tcp_socket->SetNoDelay(boolean_value) ? PP_OK : PP_ERROR_FAILED);
+ return;
+ }
+ case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE:
+ case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: {
+ int32_t integer_value = 0;
+ if (!value.GetInt32(&integer_value) || integer_value <= 0) {
+ SendSetOptionACK(PP_ERROR_BADARGUMENT);
+ return;
+ }
+
+ bool result = false;
+ if (name == PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE) {
+ if (integer_value > ppapi::TCPSocketShared::kMaxSendBufferSize) {
+ SendSetOptionACK(PP_ERROR_BADARGUMENT);
+ return;
+ }
+ result = tcp_socket->SetSendBufferSize(integer_value);
} else {
- SendSetBoolOptionACK(false);
+ if (integer_value > ppapi::TCPSocketShared::kMaxReceiveBufferSize) {
+ SendSetOptionACK(PP_ERROR_BADARGUMENT);
+ return;
+ }
+ result = tcp_socket->SetReceiveBufferSize(integer_value);
}
+ SendSetOptionACK(result ? PP_OK : PP_ERROR_FAILED);
return;
- default:
- break;
+ }
+ default: {
+ NOTREACHED();
+ SendSetOptionACK(PP_ERROR_BADARGUMENT);
+ return;
+ }
}
-
- NOTREACHED();
- SendSetBoolOptionACK(false);
}
void PepperTCPSocket::StartConnect(const net::AddressList& addresses) {
@@ -226,16 +282,16 @@ void PepperTCPSocket::StartConnect(const net::AddressList& addresses) {
socket_.reset(new net::TCPClientSocket(addresses, NULL,
net::NetLog::Source()));
- int result = socket_->Connect(
+ int net_result = socket_->Connect(
base::Bind(&PepperTCPSocket::OnConnectCompleted,
base::Unretained(this)));
- if (result != net::ERR_IO_PENDING)
- OnConnectCompleted(result);
+ if (net_result != net::ERR_IO_PENDING)
+ OnConnectCompleted(net_result);
}
-void PepperTCPSocket::SendConnectACKError() {
+void PepperTCPSocket::SendConnectACKError(int32_t error) {
manager_->Send(new PpapiMsg_PPBTCPSocket_ConnectACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, false,
+ routing_id_, plugin_dispatcher_id_, socket_id_, error,
NetAddressPrivateImpl::kInvalidNetAddress,
NetAddressPrivateImpl::kInvalidNetAddress));
}
@@ -299,14 +355,15 @@ bool PepperTCPSocket::GetCertificateFields(
return GetCertificateFields(*cert.get(), fields);
}
-void PepperTCPSocket::SendReadACKError() {
+void PepperTCPSocket::SendReadACKError(int32_t error) {
manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, false, std::string()));
+ routing_id_, plugin_dispatcher_id_, socket_id_, error, std::string()));
}
-void PepperTCPSocket::SendWriteACKError() {
+void PepperTCPSocket::SendWriteACKError(int32_t error) {
+ DCHECK_GT(0, error);
manager_->Send(new PpapiMsg_PPBTCPSocket_WriteACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, false, 0));
+ routing_id_, plugin_dispatcher_id_, socket_id_, error));
}
void PepperTCPSocket::SendSSLHandshakeACK(bool succeeded) {
@@ -328,16 +385,16 @@ void PepperTCPSocket::SendSSLHandshakeACK(bool succeeded) {
certificate_fields));
}
-void PepperTCPSocket::SendSetBoolOptionACK(bool succeeded) {
- manager_->Send(new PpapiMsg_PPBTCPSocket_SetBoolOptionACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, succeeded));
+void PepperTCPSocket::SendSetOptionACK(int32_t result) {
+ manager_->Send(new PpapiMsg_PPBTCPSocket_SetOptionACK(
+ routing_id_, plugin_dispatcher_id_, socket_id_, result));
}
-void PepperTCPSocket::OnResolveCompleted(int result) {
+void PepperTCPSocket::OnResolveCompleted(int net_result) {
DCHECK(connection_state_ == CONNECT_IN_PROGRESS);
- if (result != net::OK) {
- SendConnectACKError();
+ if (net_result != net::OK) {
+ SendConnectACKError(NetErrorToPepperError(net_result));
connection_state_ = BEFORE_CONNECT;
return;
}
@@ -345,86 +402,97 @@ void PepperTCPSocket::OnResolveCompleted(int result) {
StartConnect(address_list_);
}
-void PepperTCPSocket::OnConnectCompleted(int result) {
+void PepperTCPSocket::OnConnectCompleted(int net_result) {
DCHECK(connection_state_ == CONNECT_IN_PROGRESS && socket_.get());
- if (result != net::OK) {
- SendConnectACKError();
- connection_state_ = BEFORE_CONNECT;
- } else {
+ int32_t pp_result = NetErrorToPepperError(net_result);
+ do {
+ if (pp_result != PP_OK)
+ break;
+
net::IPEndPoint ip_end_point_local;
net::IPEndPoint ip_end_point_remote;
+ pp_result = NetErrorToPepperError(
+ socket_->GetLocalAddress(&ip_end_point_local));
+ if (pp_result != PP_OK)
+ break;
+ pp_result = NetErrorToPepperError(
+ socket_->GetPeerAddress(&ip_end_point_remote));
+ if (pp_result != PP_OK)
+ break;
+
PP_NetAddress_Private local_addr =
NetAddressPrivateImpl::kInvalidNetAddress;
PP_NetAddress_Private remote_addr =
NetAddressPrivateImpl::kInvalidNetAddress;
-
- if (socket_->GetLocalAddress(&ip_end_point_local) != net::OK ||
- !NetAddressPrivateImpl::IPEndPointToNetAddress(
+ if (!NetAddressPrivateImpl::IPEndPointToNetAddress(
ip_end_point_local.address(),
ip_end_point_local.port(),
&local_addr) ||
- socket_->GetPeerAddress(&ip_end_point_remote) != net::OK ||
!NetAddressPrivateImpl::IPEndPointToNetAddress(
ip_end_point_remote.address(),
ip_end_point_remote.port(),
&remote_addr)) {
- SendConnectACKError();
- connection_state_ = BEFORE_CONNECT;
- } else {
- manager_->Send(new PpapiMsg_PPBTCPSocket_ConnectACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, true,
- local_addr, remote_addr));
- connection_state_ = CONNECTED;
+ pp_result = PP_ERROR_ADDRESS_INVALID;
+ break;
}
- }
+
+ manager_->Send(new PpapiMsg_PPBTCPSocket_ConnectACK(
+ routing_id_, plugin_dispatcher_id_, socket_id_, PP_OK,
+ local_addr, remote_addr));
+ connection_state_ = CONNECTED;
+ return;
+ } while (false);
+
+ SendConnectACKError(pp_result);
+ connection_state_ = BEFORE_CONNECT;
}
-void PepperTCPSocket::OnSSLHandshakeCompleted(int result) {
+void PepperTCPSocket::OnSSLHandshakeCompleted(int net_result) {
DCHECK(connection_state_ == SSL_HANDSHAKE_IN_PROGRESS);
- bool succeeded = result == net::OK;
+ bool succeeded = net_result == net::OK;
SendSSLHandshakeACK(succeeded);
connection_state_ = succeeded ? SSL_CONNECTED : SSL_HANDSHAKE_FAILED;
}
-void PepperTCPSocket::OnReadCompleted(int result) {
+void PepperTCPSocket::OnReadCompleted(int net_result) {
DCHECK(read_buffer_.get());
- if (result > 0) {
+ if (net_result > 0) {
manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, true,
- std::string(read_buffer_->data(), result)));
- } else if (result == 0) {
+ routing_id_, plugin_dispatcher_id_, socket_id_, PP_OK,
+ std::string(read_buffer_->data(), net_result)));
+ } else if (net_result == 0) {
end_of_file_reached_ = true;
manager_->Send(new PpapiMsg_PPBTCPSocket_ReadACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, true, std::string()));
+ routing_id_, plugin_dispatcher_id_, socket_id_, PP_OK, std::string()));
} else {
- SendReadACKError();
+ SendReadACKError(NetErrorToPepperError(net_result));
}
read_buffer_ = NULL;
}
-void PepperTCPSocket::OnWriteCompleted(int result) {
+void PepperTCPSocket::OnWriteCompleted(int net_result) {
DCHECK(write_buffer_base_.get());
DCHECK(write_buffer_.get());
// Note: For partial writes of 0 bytes, don't continue writing to avoid a
// likely infinite loop.
- if (result > 0) {
- write_buffer_->DidConsume(result);
+ if (net_result > 0) {
+ write_buffer_->DidConsume(net_result);
if (write_buffer_->BytesRemaining() > 0) {
DoWrite();
return;
}
}
- if (result >= 0) {
+ if (net_result >= 0) {
manager_->Send(new PpapiMsg_PPBTCPSocket_WriteACK(
- routing_id_, plugin_dispatcher_id_, socket_id_, true,
+ routing_id_, plugin_dispatcher_id_, socket_id_,
write_buffer_->BytesConsumed()));
} else {
- SendWriteACKError();
+ SendWriteACKError(NetErrorToPepperError(net_result));
}
write_buffer_ = NULL;
@@ -446,12 +514,12 @@ void PepperTCPSocket::DoWrite() {
DCHECK(write_buffer_.get());
DCHECK_GT(write_buffer_->BytesRemaining(), 0);
- int result = socket_->Write(
+ int net_result = socket_->Write(
write_buffer_.get(),
write_buffer_->BytesRemaining(),
base::Bind(&PepperTCPSocket::OnWriteCompleted, base::Unretained(this)));
- if (result != net::ERR_IO_PENDING)
- OnWriteCompleted(result);
+ if (net_result != net::ERR_IO_PENDING)
+ OnWriteCompleted(net_result);
}
} // namespace content
diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket.h b/content/browser/renderer_host/pepper/pepper_tcp_socket.h
index bfc8693..5292d6a 100644
--- a/content/browser/renderer_host/pepper/pepper_tcp_socket.h
+++ b/content/browser/renderer_host/pepper/pepper_tcp_socket.h
@@ -12,12 +12,14 @@
#include "base/memory/scoped_ptr.h"
#include "net/base/address_list.h"
#include "net/base/completion_callback.h"
+#include "ppapi/c/dev/ppb_tcp_socket_dev.h"
#include "ppapi/c/pp_stdint.h"
struct PP_NetAddress_Private;
namespace ppapi {
class PPB_X509Certificate_Fields;
+class SocketOptionData;
}
namespace net {
@@ -32,13 +34,14 @@ namespace content {
class PepperMessageFilter;
// PepperTCPSocket is used by PepperMessageFilter to handle requests from
-// the Pepper TCP socket API (PPB_TCPSocket_Private).
+// the Pepper TCP socket API (PPB_TCPSocket and PPB_TCPSocket_Private).
class PepperTCPSocket {
public:
PepperTCPSocket(PepperMessageFilter* manager,
int32 routing_id,
uint32 plugin_dispatcher_id,
- uint32 socket_id);
+ uint32 socket_id,
+ bool private_api);
// Used for creation already connected sockets. Takes ownership of
// |socket|.
@@ -46,10 +49,12 @@ class PepperTCPSocket {
int32 routing_id,
uint32 plugin_dispatcher_id,
uint32 socket_id,
- net::StreamSocket* socket);
+ net::StreamSocket* socket,
+ bool private_api);
~PepperTCPSocket();
int routing_id() { return routing_id_; }
+ bool private_api() const { return private_api_; }
void Connect(const std::string& host, uint16_t port);
void ConnectWithNetAddress(const PP_NetAddress_Private& net_addr);
@@ -60,9 +65,10 @@ class PepperTCPSocket {
const std::vector<std::vector<char> >& untrusted_certs);
void Read(int32 bytes_to_read);
void Write(const std::string& data);
- void SetBoolOption(uint32_t name, bool value);
+ void SetOption(PP_TCPSocket_Option_Dev name,
+ const ppapi::SocketOptionData& value);
- void SendConnectACKError();
+ void SendConnectACKError(int32_t error);
// Extracts the certificate field data from a |net::X509Certificate| into
// |PPB_X509Certificate_Fields|.
@@ -93,16 +99,16 @@ class PepperTCPSocket {
void StartConnect(const net::AddressList& addresses);
- void SendReadACKError();
- void SendWriteACKError();
+ void SendReadACKError(int32_t error);
+ void SendWriteACKError(int32_t error);
void SendSSLHandshakeACK(bool succeeded);
- void SendSetBoolOptionACK(bool succeeded);
+ void SendSetOptionACK(int32_t result);
- void OnResolveCompleted(int result);
- void OnConnectCompleted(int result);
- void OnSSLHandshakeCompleted(int result);
- void OnReadCompleted(int result);
- void OnWriteCompleted(int result);
+ void OnResolveCompleted(int net_result);
+ void OnConnectCompleted(int net_result);
+ void OnSSLHandshakeCompleted(int net_result);
+ void OnReadCompleted(int net_result);
+ void OnWriteCompleted(int net_result);
bool IsConnected() const;
bool IsSsl() const;
@@ -115,6 +121,7 @@ class PepperTCPSocket {
int32 routing_id_;
uint32 plugin_dispatcher_id_;
uint32 socket_id_;
+ bool private_api_;
ConnectionState connection_state_;
bool end_of_file_reached_;
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
index a22d624..0793387 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
@@ -81,6 +81,7 @@
#include "ppapi/shared_impl/ppb_device_ref_shared.h"
#include "ppapi/shared_impl/ppp_instance_combined.h"
#include "ppapi/shared_impl/resource_tracker.h"
+#include "ppapi/shared_impl/socket_option_data.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_tcp_server_socket_private_api.h"
#include "third_party/WebKit/public/web/WebCursorInfo.h"
@@ -1148,8 +1149,11 @@ PepperPluginDelegateImpl::GetFileThreadMessageLoopProxy() {
}
uint32 PepperPluginDelegateImpl::TCPSocketCreate() {
+ // This was used for PPB_TCPSocket_Private creation. And it shouldn't be
+ // needed anymore.
+ // TODO(yzshen): Remove TCP socket-related contents from the plugin delegate.
uint32 socket_id = 0;
- render_view_->Send(new PpapiHostMsg_PPBTCPSocket_Create(
+ render_view_->Send(new PpapiHostMsg_PPBTCPSocket_CreatePrivate(
render_view_->routing_id(), 0, &socket_id));
return socket_id;
}
@@ -1207,13 +1211,13 @@ void PepperPluginDelegateImpl::TCPSocketDisconnect(uint32 socket_id) {
tcp_sockets_.Remove(socket_id);
}
-void PepperPluginDelegateImpl::TCPSocketSetBoolOption(
+void PepperPluginDelegateImpl::TCPSocketSetOption(
uint32 socket_id,
- PP_TCPSocketOption_Private name,
- bool value) {
+ PP_TCPSocket_Option_Dev name,
+ const ppapi::SocketOptionData& value) {
DCHECK(tcp_sockets_.Lookup(socket_id));
render_view_->Send(
- new PpapiHostMsg_PPBTCPSocket_SetBoolOption(socket_id, name, value));
+ new PpapiHostMsg_PPBTCPSocket_SetOption(socket_id, name, value));
}
void PepperPluginDelegateImpl::RegisterTCPSocket(
@@ -1491,8 +1495,8 @@ bool PepperPluginDelegateImpl::OnMessageReceived(const IPC::Message& message) {
OnTCPSocketSSLHandshakeACK)
IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ReadACK, OnTCPSocketReadACK)
IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_WriteACK, OnTCPSocketWriteACK)
- IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetBoolOptionACK,
- OnTCPSocketSetBoolOptionACK)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetOptionACK,
+ OnTCPSocketSetOptionACK)
IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPServerSocket_ListenACK,
OnTCPServerSocketListenACK)
IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPServerSocket_AcceptACK,
@@ -1511,14 +1515,14 @@ void PepperPluginDelegateImpl::OnDestruct() {
void PepperPluginDelegateImpl::OnTCPSocketConnectACK(
uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const PP_NetAddress_Private& local_addr,
const PP_NetAddress_Private& remote_addr) {
webkit::ppapi::PPB_TCPSocket_Private_Impl* socket =
tcp_sockets_.Lookup(socket_id);
if (socket)
- socket->OnConnectCompleted(succeeded, local_addr, remote_addr);
- if (!succeeded)
+ socket->OnConnectCompleted(result, local_addr, remote_addr);
+ if (result != PP_OK)
tcp_sockets_.Remove(socket_id);
}
@@ -1535,32 +1539,31 @@ void PepperPluginDelegateImpl::OnTCPSocketSSLHandshakeACK(
void PepperPluginDelegateImpl::OnTCPSocketReadACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const std::string& data) {
webkit::ppapi::PPB_TCPSocket_Private_Impl* socket =
tcp_sockets_.Lookup(socket_id);
if (socket)
- socket->OnReadCompleted(succeeded, data);
+ socket->OnReadCompleted(result, data);
}
void PepperPluginDelegateImpl::OnTCPSocketWriteACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
- int32_t bytes_written) {
+ int32_t result) {
webkit::ppapi::PPB_TCPSocket_Private_Impl* socket =
tcp_sockets_.Lookup(socket_id);
if (socket)
- socket->OnWriteCompleted(succeeded, bytes_written);
+ socket->OnWriteCompleted(result);
}
-void PepperPluginDelegateImpl::OnTCPSocketSetBoolOptionACK(
+void PepperPluginDelegateImpl::OnTCPSocketSetOptionACK(
uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded) {
+ int32_t result) {
webkit::ppapi::PPB_TCPSocket_Private_Impl* socket =
tcp_sockets_.Lookup(socket_id);
if (socket)
- socket->OnSetOptionCompleted(succeeded);
+ socket->OnSetOptionCompleted(result);
}
void PepperPluginDelegateImpl::OnTCPServerSocketListenACK(
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.h b/content/renderer/pepper/pepper_plugin_delegate_impl.h
index 1c0089a..83f9f82 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.h
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.h
@@ -282,9 +282,10 @@ class PepperPluginDelegateImpl
virtual void TCPSocketWrite(uint32 socket_id,
const std::string& buffer) OVERRIDE;
virtual void TCPSocketDisconnect(uint32 socket_id) OVERRIDE;
- virtual void TCPSocketSetBoolOption(uint32 socket_id,
- PP_TCPSocketOption_Private name,
- bool value) OVERRIDE;
+ virtual void TCPSocketSetOption(
+ uint32 socket_id,
+ PP_TCPSocket_Option_Dev name,
+ const ppapi::SocketOptionData& value) OVERRIDE;
virtual void RegisterTCPSocket(
webkit::ppapi::PPB_TCPSocket_Private_Impl* socket,
uint32 socket_id) OVERRIDE;
@@ -341,7 +342,7 @@ class PepperPluginDelegateImpl
void OnTCPSocketConnectACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const PP_NetAddress_Private& local_addr,
const PP_NetAddress_Private& remote_addr);
void OnTCPSocketSSLHandshakeACK(
@@ -351,15 +352,14 @@ class PepperPluginDelegateImpl
const ppapi::PPB_X509Certificate_Fields& certificate_fields);
void OnTCPSocketReadACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const std::string& data);
void OnTCPSocketWriteACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
- int32_t bytes_written);
- void OnTCPSocketSetBoolOptionACK(uint32 plugin_dispatcher_id,
- uint32 socket_id,
- bool succeeded);
+ int32_t result);
+ void OnTCPSocketSetOptionACK(uint32 plugin_dispatcher_id,
+ uint32 socket_id,
+ int32_t result);
void OnTCPServerSocketListenACK(uint32 plugin_dispatcher_id,
PP_Resource socket_resource,
uint32 socket_id,
diff --git a/ppapi/api/dev/ppb_tcp_socket_dev.idl b/ppapi/api/dev/ppb_tcp_socket_dev.idl
index dfc038a..920a9e9 100644
--- a/ppapi/api/dev/ppb_tcp_socket_dev.idl
+++ b/ppapi/api/dev/ppb_tcp_socket_dev.idl
@@ -17,10 +17,12 @@ label Chrome {
enum PP_TCPSocket_Option_Dev {
// Disables coalescing of small writes to make TCP segments, and instead
// deliver data immediately. Value type is PP_VARTYPE_BOOL.
+ // This option can only be set after a successful Connect() call.
PP_TCPSOCKET_OPTION_NO_DELAY = 0,
// Specifies the socket send buffer in bytes. Value's type should be
// PP_VARTYPE_INT32.
+ // This option can only be set after a successful Connect() call.
// Note: This is only treated as a hint for the browser to set the buffer
// size. Even if SetOption() reports that this option has been successfully
// set, the browser doesn't guarantee to conform to it.
@@ -28,6 +30,7 @@ enum PP_TCPSocket_Option_Dev {
// Specifies the socket receive buffer in bytes. Value's type should be
// PP_VARTYPE_INT32.
+ // This option can only be set after a successful Connect() call.
// Note: This is only treated as a hint for the browser to set the buffer
// size. Even if SetOption() reports that this option has been successfully
// set, the browser doesn't guarantee to conform to it.
@@ -106,7 +109,7 @@ interface PPB_TCPSocket_Dev {
* Sets an option on |tcp_socket|. Supported |name| and |value| parameters
* are as described for PP_TCPSocketOption_Dev. |callback| will be
* invoked with PP_OK if setting the option succeeds, or an error code
- * otherwise. The socket must be connected before SetOption is called.
+ * otherwise.
*/
int32_t SetOption([in] PP_Resource tcp_socket,
[in] PP_TCPSocket_Option_Dev name,
diff --git a/ppapi/c/dev/ppb_tcp_socket_dev.h b/ppapi/c/dev/ppb_tcp_socket_dev.h
index d59bc31..044a03e 100644
--- a/ppapi/c/dev/ppb_tcp_socket_dev.h
+++ b/ppapi/c/dev/ppb_tcp_socket_dev.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From dev/ppb_tcp_socket_dev.idl modified Wed Jun 12 11:16:37 2013. */
+/* From dev/ppb_tcp_socket_dev.idl modified Tue Jun 18 15:48:42 2013. */
#ifndef PPAPI_C_DEV_PPB_TCP_SOCKET_DEV_H_
#define PPAPI_C_DEV_PPB_TCP_SOCKET_DEV_H_
@@ -31,16 +31,19 @@
*/
typedef enum {
/* Disables coalescing of small writes to make TCP segments, and instead
- * deliver data immediately. Value type is PP_VARTYPE_BOOL. */
+ * deliver data immediately. Value type is PP_VARTYPE_BOOL.
+ * This option can only be set after a successful Connect() call. */
PP_TCPSOCKET_OPTION_NO_DELAY = 0,
/* Specifies the socket send buffer in bytes. Value's type should be
* PP_VARTYPE_INT32.
+ * This option can only be set after a successful Connect() call.
* Note: This is only treated as a hint for the browser to set the buffer
* size. Even if SetOption() reports that this option has been successfully
* set, the browser doesn't guarantee to conform to it. */
PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE = 1,
/* Specifies the socket receive buffer in bytes. Value's type should be
* PP_VARTYPE_INT32.
+ * This option can only be set after a successful Connect() call.
* Note: This is only treated as a hint for the browser to set the buffer
* size. Even if SetOption() reports that this option has been successfully
* set, the browser doesn't guarantee to conform to it. */
@@ -119,7 +122,7 @@ struct PPB_TCPSocket_Dev_0_1 {
* Sets an option on |tcp_socket|. Supported |name| and |value| parameters
* are as described for PP_TCPSocketOption_Dev. |callback| will be
* invoked with PP_OK if setting the option succeeds, or an error code
- * otherwise. The socket must be connected before SetOption is called.
+ * otherwise.
*/
int32_t (*SetOption)(PP_Resource tcp_socket,
PP_TCPSocket_Option_Dev name,
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index ddc2581..a977dca 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -21,6 +21,7 @@
#include "ipc/ipc_platform_file.h"
#include "ppapi/c/dev/pp_video_capture_dev.h"
#include "ppapi/c/dev/pp_video_dev.h"
+#include "ppapi/c/dev/ppb_tcp_socket_dev.h"
#include "ppapi/c/dev/ppb_text_input_dev.h"
#include "ppapi/c/dev/ppb_truetype_font_dev.h"
#include "ppapi/c/dev/ppb_udp_socket_dev.h"
@@ -43,7 +44,6 @@
#include "ppapi/c/private/ppb_host_resolver_private.h"
#include "ppapi/c/private/ppb_net_address_private.h"
#include "ppapi/c/private/ppb_pdf.h"
-#include "ppapi/c/private/ppb_tcp_socket_private.h"
#include "ppapi/c/private/ppp_flash_browser_operations.h"
#include "ppapi/c/private/ppb_talk_private.h"
#include "ppapi/proxy/host_resolver_private_resource.h"
@@ -96,6 +96,8 @@ IPC_ENUM_TRAITS(PP_ResourceString)
IPC_ENUM_TRAITS_MAX_VALUE(PP_TalkEvent, PP_TALKEVENT_NUM_EVENTS - 1)
IPC_ENUM_TRAITS_MAX_VALUE(PP_TalkPermission,
PP_TALKPERMISSION_NUM_PERMISSIONS - 1)
+IPC_ENUM_TRAITS_MAX_VALUE(PP_TCPSocket_Option_Dev,
+ PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE)
IPC_ENUM_TRAITS(PP_TextInput_Type)
IPC_ENUM_TRAITS(PP_TrueTypeFontFamily_Dev)
IPC_ENUM_TRAITS(PP_TrueTypeFontStyle_Dev)
@@ -700,11 +702,11 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPPContentDecryptor_DecryptAndDecode,
std::string /* serialized_block_info */)
#endif // !defined(OS_NACL) && !defined(NACL_WIN64)
-// PPB_TCPSocket_Private.
+// PPB_TCPSocket and PPB_TCPSocket_Private.
IPC_MESSAGE_ROUTED5(PpapiMsg_PPBTCPSocket_ConnectACK,
uint32 /* plugin_dispatcher_id */,
uint32 /* socket_id */,
- bool /* succeeded */,
+ int32_t /* result */,
PP_NetAddress_Private /* local_addr */,
PP_NetAddress_Private /* remote_addr */)
IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPSocket_SSLHandshakeACK,
@@ -715,17 +717,16 @@ IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPSocket_SSLHandshakeACK,
IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPSocket_ReadACK,
uint32 /* plugin_dispatcher_id */,
uint32 /* socket_id */,
- bool /* succeeded */,
+ int32_t /* result */,
std::string /* data */)
-IPC_MESSAGE_ROUTED4(PpapiMsg_PPBTCPSocket_WriteACK,
+IPC_MESSAGE_ROUTED3(PpapiMsg_PPBTCPSocket_WriteACK,
uint32 /* plugin_dispatcher_id */,
uint32 /* socket_id */,
- bool /* succeeded */,
- int32_t /* bytes_written */)
-IPC_MESSAGE_ROUTED3(PpapiMsg_PPBTCPSocket_SetBoolOptionACK,
+ int32_t /* result */)
+IPC_MESSAGE_ROUTED3(PpapiMsg_PPBTCPSocket_SetOptionACK,
uint32 /* plugin_dispatcher_id */,
uint32 /* socket_id */,
- bool /* succeeded */)
+ int32_t /* result */)
// PPB_TCPServerSocket_Private.
@@ -1185,11 +1186,17 @@ IPC_SYNC_MESSAGE_ROUTED1_0(PpapiHostMsg_PPBFlashMessageLoop_Quit,
ppapi::HostResource /* flash_message_loop */)
#endif // !defined(OS_NACL) && !defined(NACL_WIN64)
-// PPB_TCPSocket_Private.
+// PPB_TCPSocket and PPB_TCPSocket_Private.
+// Creates a PPB_TCPSocket resource.
IPC_SYNC_MESSAGE_CONTROL2_1(PpapiHostMsg_PPBTCPSocket_Create,
int32 /* routing_id */,
uint32 /* plugin_dispatcher_id */,
uint32 /* socket_id */)
+// Creates a PPB_TCPSocket_Private resource.
+IPC_SYNC_MESSAGE_CONTROL2_1(PpapiHostMsg_PPBTCPSocket_CreatePrivate,
+ int32 /* routing_id */,
+ uint32 /* plugin_dispatcher_id */,
+ uint32 /* socket_id */)
IPC_MESSAGE_CONTROL4(PpapiHostMsg_PPBTCPSocket_Connect,
int32 /* routing_id */,
uint32 /* socket_id */,
@@ -1213,10 +1220,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,
+IPC_MESSAGE_CONTROL3(PpapiHostMsg_PPBTCPSocket_SetOption,
uint32 /* socket_id */,
- uint32 /* name */,
- bool /* value */)
+ PP_TCPSocket_Option_Dev /* name */,
+ ppapi::SocketOptionData /* value */)
// PPB_TCPServerSocket_Private.
IPC_MESSAGE_CONTROL5(PpapiHostMsg_PPBTCPServerSocket_Listen,
diff --git a/ppapi/proxy/ppb_tcp_socket_private_proxy.cc b/ppapi/proxy/ppb_tcp_socket_private_proxy.cc
index 7f7fb78..7075657 100644
--- a/ppapi/proxy/ppb_tcp_socket_private_proxy.cc
+++ b/ppapi/proxy/ppb_tcp_socket_private_proxy.cc
@@ -14,6 +14,7 @@
#include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
#include "ppapi/shared_impl/private/tcp_socket_private_impl.h"
#include "ppapi/shared_impl/resource.h"
+#include "ppapi/shared_impl/socket_option_data.h"
#include "ppapi/thunk/thunk.h"
namespace ppapi {
@@ -46,8 +47,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;
+ virtual void SendSetOption(PP_TCPSocket_Option_Dev name,
+ const SocketOptionData& value) OVERRIDE;
private:
void SendToBrowser(IPC::Message* msg);
@@ -118,9 +119,10 @@ void TCPSocket::SendDisconnect() {
SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Disconnect(socket_id_));
}
-void TCPSocket::SendSetBoolOption(PP_TCPSocketOption_Private name, bool value) {
+void TCPSocket::SendSetOption(PP_TCPSocket_Option_Dev name,
+ const SocketOptionData& value) {
SendToBrowser(
- new PpapiHostMsg_PPBTCPSocket_SetBoolOption(socket_id_, name, value));
+ new PpapiHostMsg_PPBTCPSocket_SetOption(socket_id_, name, value));
}
void TCPSocket::SendToBrowser(IPC::Message* msg) {
@@ -147,7 +149,7 @@ PP_Resource PPB_TCPSocket_Private_Proxy::CreateProxyResource(
uint32 socket_id = 0;
PluginGlobals::Get()->GetBrowserSender()->Send(
- new PpapiHostMsg_PPBTCPSocket_Create(
+ new PpapiHostMsg_PPBTCPSocket_CreatePrivate(
API_ID_PPB_TCPSOCKET_PRIVATE, dispatcher->plugin_dispatcher_id(),
&socket_id));
if (socket_id == 0)
@@ -177,8 +179,7 @@ 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_HANDLER(PpapiMsg_PPBTCPSocket_SetOptionACK, OnMsgSetOptionACK)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -187,7 +188,7 @@ bool PPB_TCPSocket_Private_Proxy::OnMessageReceived(const IPC::Message& msg) {
void PPB_TCPSocket_Private_Proxy::OnMsgConnectACK(
uint32 /* plugin_dispatcher_id */,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const PP_NetAddress_Private& local_addr,
const PP_NetAddress_Private& remote_addr) {
if (!g_id_to_socket) {
@@ -197,7 +198,7 @@ void PPB_TCPSocket_Private_Proxy::OnMsgConnectACK(
IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
if (iter == g_id_to_socket->end())
return;
- iter->second->OnConnectCompleted(succeeded, local_addr, remote_addr);
+ iter->second->OnConnectCompleted(result, local_addr, remote_addr);
}
void PPB_TCPSocket_Private_Proxy::OnMsgSSLHandshakeACK(
@@ -218,7 +219,7 @@ void PPB_TCPSocket_Private_Proxy::OnMsgSSLHandshakeACK(
void PPB_TCPSocket_Private_Proxy::OnMsgReadACK(
uint32 /* plugin_dispatcher_id */,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const std::string& data) {
if (!g_id_to_socket) {
NOTREACHED();
@@ -227,14 +228,13 @@ void PPB_TCPSocket_Private_Proxy::OnMsgReadACK(
IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
if (iter == g_id_to_socket->end())
return;
- iter->second->OnReadCompleted(succeeded, data);
+ iter->second->OnReadCompleted(result, data);
}
void PPB_TCPSocket_Private_Proxy::OnMsgWriteACK(
uint32 /* plugin_dispatcher_id */,
uint32 socket_id,
- bool succeeded,
- int32_t bytes_written) {
+ int32_t result) {
if (!g_id_to_socket) {
NOTREACHED();
return;
@@ -242,13 +242,13 @@ void PPB_TCPSocket_Private_Proxy::OnMsgWriteACK(
IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
if (iter == g_id_to_socket->end())
return;
- iter->second->OnWriteCompleted(succeeded, bytes_written);
+ iter->second->OnWriteCompleted(result);
}
-void PPB_TCPSocket_Private_Proxy::OnMsgSetBoolOptionACK(
+void PPB_TCPSocket_Private_Proxy::OnMsgSetOptionACK(
uint32 /* plugin_dispatcher_id */,
uint32 socket_id,
- bool succeeded) {
+ int32_t result) {
if (!g_id_to_socket) {
NOTREACHED();
return;
@@ -256,7 +256,7 @@ void PPB_TCPSocket_Private_Proxy::OnMsgSetBoolOptionACK(
IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
if (iter == g_id_to_socket->end())
return;
- iter->second->OnSetOptionCompleted(succeeded);
+ iter->second->OnSetOptionCompleted(result);
}
} // namespace proxy
diff --git a/ppapi/proxy/ppb_tcp_socket_private_proxy.h b/ppapi/proxy/ppb_tcp_socket_private_proxy.h
index 6f0f0f4..0813531 100644
--- a/ppapi/proxy/ppb_tcp_socket_private_proxy.h
+++ b/ppapi/proxy/ppb_tcp_socket_private_proxy.h
@@ -41,7 +41,7 @@ class PPB_TCPSocket_Private_Proxy : public InterfaceProxy {
// Browser->plugin message handlers.
void OnMsgConnectACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const PP_NetAddress_Private& local_addr,
const PP_NetAddress_Private& remote_addr);
void OnMsgSSLHandshakeACK(
@@ -51,15 +51,14 @@ class PPB_TCPSocket_Private_Proxy : public InterfaceProxy {
const PPB_X509Certificate_Fields& certificate_fields);
void OnMsgReadACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const std::string& data);
void OnMsgWriteACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
- int32_t bytes_written);
- void OnMsgSetBoolOptionACK(uint32 plugin_dispatcher_id,
- uint32 socket_id,
- bool succeeded);
+ int32_t result);
+ void OnMsgSetOptionACK(uint32 plugin_dispatcher_id,
+ uint32 socket_id,
+ int32_t result);
DISALLOW_COPY_AND_ASSIGN(PPB_TCPSocket_Private_Proxy);
};
diff --git a/ppapi/proxy/ppb_tcp_socket_proxy.cc b/ppapi/proxy/ppb_tcp_socket_proxy.cc
index 1b6bd8a..6e41c91 100644
--- a/ppapi/proxy/ppb_tcp_socket_proxy.cc
+++ b/ppapi/proxy/ppb_tcp_socket_proxy.cc
@@ -11,6 +11,7 @@
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/resource.h"
+#include "ppapi/shared_impl/socket_option_data.h"
#include "ppapi/shared_impl/tcp_socket_shared.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_net_address_api.h"
@@ -66,8 +67,8 @@ class TCPSocket : public thunk::PPB_TCPSocket_API,
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;
+ virtual void SendSetOption(PP_TCPSocket_Option_Dev name,
+ const SocketOptionData& value) OVERRIDE;
virtual Resource* GetOwnerResource() OVERRIDE;
private:
@@ -146,11 +147,7 @@ void TCPSocket::Close() {
int32_t TCPSocket::SetOption(PP_TCPSocket_Option_Dev name,
const PP_Var& value,
scoped_refptr<TrackedCallback> callback) {
- // TODO(yzshen): Add support for other options.
- if (name == PP_TCPSOCKET_OPTION_NO_DELAY)
- return SetOptionImpl(PP_TCPSOCKETOPTION_NO_DELAY, value, callback);
-
- return PP_ERROR_NOTSUPPORTED;
+ return SetOptionImpl(name, value, callback);
}
void TCPSocket::SendConnect(const std::string& host, uint16_t port) {
@@ -186,9 +183,10 @@ void TCPSocket::SendDisconnect() {
SendToBrowser(new PpapiHostMsg_PPBTCPSocket_Disconnect(socket_id_));
}
-void TCPSocket::SendSetBoolOption(PP_TCPSocketOption_Private name, bool value) {
+void TCPSocket::SendSetOption(PP_TCPSocket_Option_Dev name,
+ const SocketOptionData& value) {
SendToBrowser(
- new PpapiHostMsg_PPBTCPSocket_SetBoolOption(socket_id_, name, value));
+ new PpapiHostMsg_PPBTCPSocket_SetOption(socket_id_, name, value));
}
Resource* TCPSocket::GetOwnerResource() {
@@ -234,8 +232,8 @@ bool PPB_TCPSocket_Proxy::OnMessageReceived(const IPC::Message& msg) {
OnMsgConnectACK)
IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ReadACK, OnMsgReadACK)
IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_WriteACK, OnMsgWriteACK)
- IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetBoolOptionACK,
- OnMsgSetBoolOptionACK)
+ IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetOptionACK,
+ OnMsgSetOptionACK)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -244,7 +242,7 @@ bool PPB_TCPSocket_Proxy::OnMessageReceived(const IPC::Message& msg) {
void PPB_TCPSocket_Proxy::OnMsgConnectACK(
uint32 /* plugin_dispatcher_id */,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const PP_NetAddress_Private& local_addr,
const PP_NetAddress_Private& remote_addr) {
if (!g_id_to_socket) {
@@ -254,12 +252,12 @@ void PPB_TCPSocket_Proxy::OnMsgConnectACK(
IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
if (iter == g_id_to_socket->end())
return;
- iter->second->OnConnectCompleted(succeeded, local_addr, remote_addr);
+ iter->second->OnConnectCompleted(result, local_addr, remote_addr);
}
void PPB_TCPSocket_Proxy::OnMsgReadACK(uint32 /* plugin_dispatcher_id */,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const std::string& data) {
if (!g_id_to_socket) {
NOTREACHED();
@@ -268,13 +266,12 @@ void PPB_TCPSocket_Proxy::OnMsgReadACK(uint32 /* plugin_dispatcher_id */,
IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
if (iter == g_id_to_socket->end())
return;
- iter->second->OnReadCompleted(succeeded, data);
+ iter->second->OnReadCompleted(result, data);
}
void PPB_TCPSocket_Proxy::OnMsgWriteACK(uint32 /* plugin_dispatcher_id */,
uint32 socket_id,
- bool succeeded,
- int32_t bytes_written) {
+ int32_t result) {
if (!g_id_to_socket) {
NOTREACHED();
return;
@@ -282,13 +279,12 @@ void PPB_TCPSocket_Proxy::OnMsgWriteACK(uint32 /* plugin_dispatcher_id */,
IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
if (iter == g_id_to_socket->end())
return;
- iter->second->OnWriteCompleted(succeeded, bytes_written);
+ iter->second->OnWriteCompleted(result);
}
-void PPB_TCPSocket_Proxy::OnMsgSetBoolOptionACK(
- uint32 /* plugin_dispatcher_id */,
- uint32 socket_id,
- bool succeeded) {
+void PPB_TCPSocket_Proxy::OnMsgSetOptionACK(uint32 /* plugin_dispatcher_id */,
+ uint32 socket_id,
+ int32_t result) {
if (!g_id_to_socket) {
NOTREACHED();
return;
@@ -296,7 +292,7 @@ void PPB_TCPSocket_Proxy::OnMsgSetBoolOptionACK(
IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
if (iter == g_id_to_socket->end())
return;
- iter->second->OnSetOptionCompleted(succeeded);
+ iter->second->OnSetOptionCompleted(result);
}
} // namespace proxy
diff --git a/ppapi/proxy/ppb_tcp_socket_proxy.h b/ppapi/proxy/ppb_tcp_socket_proxy.h
index 35314a3..c5a3de8 100644
--- a/ppapi/proxy/ppb_tcp_socket_proxy.h
+++ b/ppapi/proxy/ppb_tcp_socket_proxy.h
@@ -34,20 +34,19 @@ class PPB_TCPSocket_Proxy : public InterfaceProxy {
// Browser->plugin message handlers.
void OnMsgConnectACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const PP_NetAddress_Private& local_addr,
const PP_NetAddress_Private& remote_addr);
void OnMsgReadACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
+ int32_t result,
const std::string& data);
void OnMsgWriteACK(uint32 plugin_dispatcher_id,
uint32 socket_id,
- bool succeeded,
- int32_t bytes_written);
- void OnMsgSetBoolOptionACK(uint32 plugin_dispatcher_id,
- uint32 socket_id,
- bool succeeded);
+ int32_t result);
+ void OnMsgSetOptionACK(uint32 plugin_dispatcher_id,
+ uint32 socket_id,
+ int32_t result);
DISALLOW_COPY_AND_ASSIGN(PPB_TCPSocket_Proxy);
};
diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.cc b/ppapi/shared_impl/private/tcp_socket_private_impl.cc
index 832603c..ce8f03a 100644
--- a/ppapi/shared_impl/private/tcp_socket_private_impl.cc
+++ b/ppapi/shared_impl/private/tcp_socket_private_impl.cc
@@ -4,6 +4,9 @@
#include "ppapi/shared_impl/private/tcp_socket_private_impl.h"
+#include "base/logging.h"
+#include "ppapi/c/pp_errors.h"
+
namespace ppapi {
TCPSocketPrivateImpl::TCPSocketPrivateImpl(PP_Instance instance,
@@ -85,11 +88,28 @@ int32_t TCPSocketPrivateImpl::SetOption(
PP_TCPSocketOption_Private name,
const PP_Var& value,
scoped_refptr<TrackedCallback> callback) {
- return SetOptionImpl(name, value, callback);
+ switch (name) {
+ case PP_TCPSOCKETOPTION_INVALID:
+ return PP_ERROR_BADARGUMENT;
+ case PP_TCPSOCKETOPTION_NO_DELAY:
+ return SetOptionImpl(PP_TCPSOCKET_OPTION_NO_DELAY, value, callback);
+ default:
+ NOTREACHED();
+ return PP_ERROR_BADARGUMENT;
+ }
}
Resource* TCPSocketPrivateImpl::GetOwnerResource() {
return this;
}
+int32_t TCPSocketPrivateImpl::OverridePPError(int32_t pp_error) {
+ // PPB_TCPSocket_Private treats all errors from the browser process as
+ // PP_ERROR_FAILED.
+ if (pp_error < 0)
+ return PP_ERROR_FAILED;
+
+ return pp_error;
+}
+
} // namespace ppapi
diff --git a/ppapi/shared_impl/private/tcp_socket_private_impl.h b/ppapi/shared_impl/private/tcp_socket_private_impl.h
index 62fba8e..36303fa 100644
--- a/ppapi/shared_impl/private/tcp_socket_private_impl.h
+++ b/ppapi/shared_impl/private/tcp_socket_private_impl.h
@@ -62,6 +62,9 @@ class PPAPI_SHARED_EXPORT TCPSocketPrivateImpl
// TCPSocketShared implementation.
virtual Resource* GetOwnerResource() OVERRIDE;
+ // TCPSocketShared overrides.
+ virtual int32_t OverridePPError(int32_t pp_error) OVERRIDE;
+
private:
DISALLOW_COPY_AND_ASSIGN(TCPSocketPrivateImpl);
};
diff --git a/ppapi/shared_impl/tcp_socket_shared.cc b/ppapi/shared_impl/tcp_socket_shared.cc
index 8799c49..9656637 100644
--- a/ppapi/shared_impl/tcp_socket_shared.cc
+++ b/ppapi/shared_impl/tcp_socket_shared.cc
@@ -11,10 +11,12 @@
#include "base/basictypes.h"
#include "base/bind.h"
#include "base/logging.h"
+#include "ppapi/c/pp_bool.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h"
+#include "ppapi/shared_impl/socket_option_data.h"
#include "ppapi/shared_impl/var_tracker.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/enter.h"
@@ -24,6 +26,10 @@ namespace ppapi {
const int32_t TCPSocketShared::kMaxReadSize = 1024 * 1024;
const int32_t TCPSocketShared::kMaxWriteSize = 1024 * 1024;
+const int32_t TCPSocketShared::kMaxSendBufferSize =
+ 1024 * TCPSocketShared::kMaxWriteSize;
+const int32_t TCPSocketShared::kMaxReceiveBufferSize =
+ 1024 * TCPSocketShared::kMaxReadSize;
TCPSocketShared::TCPSocketShared(ResourceObjectType resource_type,
uint32 socket_id)
@@ -35,7 +41,7 @@ TCPSocketShared::~TCPSocketShared() {
}
void TCPSocketShared::OnConnectCompleted(
- bool succeeded,
+ int32_t result,
const PP_NetAddress_Private& local_addr,
const PP_NetAddress_Private& remote_addr) {
if (connection_state_ != BEFORE_CONNECT ||
@@ -44,12 +50,13 @@ void TCPSocketShared::OnConnectCompleted(
return;
}
- if (succeeded) {
+ result = OverridePPError(result);
+ if (result == PP_OK) {
local_addr_ = local_addr;
remote_addr_ = remote_addr;
connection_state_ = CONNECTED;
}
- connect_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED);
+ connect_callback_->Run(result);
}
void TCPSocketShared::OnSSLHandshakeCompleted(
@@ -78,13 +85,15 @@ void TCPSocketShared::OnSSLHandshakeCompleted(
}
}
-void TCPSocketShared::OnReadCompleted(bool succeeded,
+void TCPSocketShared::OnReadCompleted(int32_t result,
const std::string& data) {
if (!TrackedCallback::IsPending(read_callback_) || !read_buffer_) {
NOTREACHED();
return;
}
+ result = OverridePPError(result);
+ bool succeeded = result == PP_OK;
if (succeeded) {
CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
if (!data.empty())
@@ -94,29 +103,35 @@ void TCPSocketShared::OnReadCompleted(bool succeeded,
bytes_to_read_ = -1;
read_callback_->Run(
- succeeded ? static_cast<int32_t>(data.size()) :
- static_cast<int32_t>(PP_ERROR_FAILED));
+ succeeded ? static_cast<int32_t>(data.size()) : result);
}
-void TCPSocketShared::OnWriteCompleted(bool succeeded,
- int32_t bytes_written) {
- if (!TrackedCallback::IsPending(write_callback_) ||
- (succeeded && bytes_written < 0)) {
+void TCPSocketShared::OnWriteCompleted(int32_t result) {
+ if (!TrackedCallback::IsPending(write_callback_)) {
NOTREACHED();
return;
}
- write_callback_->Run(
- succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
+ result = OverridePPError(result);
+ write_callback_->Run(result);
}
-void TCPSocketShared::OnSetOptionCompleted(bool succeeded) {
- if (!TrackedCallback::IsPending(set_option_callback_)) {
+void TCPSocketShared::OnSetOptionCompleted(int32_t result) {
+ if (set_option_callbacks_.empty()) {
NOTREACHED();
return;
}
- set_option_callback_->Run(succeeded ? PP_OK : PP_ERROR_FAILED);
+ result = OverridePPError(result);
+ scoped_refptr<TrackedCallback> callback = set_option_callbacks_.front();
+ set_option_callbacks_.pop();
+
+ if (TrackedCallback::IsPending(callback))
+ callback->Run(result);
+}
+
+int32_t TCPSocketShared::OverridePPError(int32_t pp_error) {
+ return pp_error;
}
int32_t TCPSocketShared::ConnectImpl(const char* host,
@@ -283,32 +298,42 @@ void TCPSocketShared::DisconnectImpl() {
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 TCPSocketShared::SetOptionImpl(
- PP_TCPSocketOption_Private name,
+ PP_TCPSocket_Option_Dev 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;
+ SocketOptionData option_data;
switch (name) {
- case PP_TCPSOCKETOPTION_NO_DELAY:
+ case PP_TCPSOCKET_OPTION_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:
+ option_data.SetBool(PP_ToBool(value.value.as_bool));
+ break;
+ }
+ case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE:
+ case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: {
+ if (value.type != PP_VARTYPE_INT32)
+ return PP_ERROR_BADARGUMENT;
+ option_data.SetInt32(value.value.as_int);
+ break;
+ }
+ default: {
+ NOTREACHED();
return PP_ERROR_BADARGUMENT;
+ }
}
+
+ set_option_callbacks_.push(callback);
+ SendSetOption(name, option_data);
+ return PP_OK_COMPLETIONPENDING;
}
void TCPSocketShared::Init(uint32 socket_id) {
diff --git a/ppapi/shared_impl/tcp_socket_shared.h b/ppapi/shared_impl/tcp_socket_shared.h
index bd5e56b..46b29dc 100644
--- a/ppapi/shared_impl/tcp_socket_shared.h
+++ b/ppapi/shared_impl/tcp_socket_shared.h
@@ -5,11 +5,13 @@
#ifndef PPAPI_SHARED_IMPL_TCP_SOCKET_SHARED_H_
#define PPAPI_SHARED_IMPL_TCP_SOCKET_SHARED_H_
+#include <queue>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
-#include "ppapi/c/private/ppb_tcp_socket_private.h"
+#include "ppapi/c/dev/ppb_tcp_socket_dev.h"
+#include "ppapi/c/private/ppb_net_address_private.h"
#include "ppapi/shared_impl/resource.h"
#include "ppapi/shared_impl/tracked_callback.h"
@@ -17,6 +19,7 @@ namespace ppapi {
class PPB_X509Certificate_Fields;
class PPB_X509Certificate_Private_Shared;
+class SocketOptionData;
// This class provides the shared implementation for both PPB_TCPSocket and
// PPB_TCPSocket_Private.
@@ -29,16 +32,27 @@ class PPAPI_SHARED_EXPORT TCPSocketShared {
// message is allowed to carry.
static const int32_t kMaxWriteSize;
+ // The maximum number that we allow for setting
+ // PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE. This number is only for input
+ // argument sanity check, it doesn't mean the browser guarantees to support
+ // such a buffer size.
+ static const int32_t kMaxSendBufferSize;
+ // The maximum number that we allow for setting
+ // PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE. This number is only for input
+ // argument sanity check, it doesn't mean the browser guarantees to support
+ // such a buffer size.
+ static const int32_t kMaxReceiveBufferSize;
+
// Notifications on operations completion.
- void OnConnectCompleted(bool succeeded,
+ void OnConnectCompleted(int32_t result,
const PP_NetAddress_Private& local_addr,
const PP_NetAddress_Private& remote_addr);
void OnSSLHandshakeCompleted(
bool succeeded,
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);
+ void OnReadCompleted(int32_t result, const std::string& data);
+ void OnWriteCompleted(int32_t result);
+ void OnSetOptionCompleted(int32_t result);
// Send functions that need to be implemented differently for the
// proxied and non-proxied derived classes.
@@ -52,11 +66,14 @@ class PPAPI_SHARED_EXPORT TCPSocketShared {
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;
+ virtual void SendSetOption(PP_TCPSocket_Option_Dev name,
+ const SocketOptionData& value) = 0;
virtual Resource* GetOwnerResource() = 0;
+ // Used to override PP_Error codes received from the browser side.
+ virtual int32_t OverridePPError(int32_t pp_error);
+
protected:
enum ConnectionState {
// Before a connection is successfully established (including a connect
@@ -94,7 +111,7 @@ class PPAPI_SHARED_EXPORT TCPSocketShared {
int32_t bytes_to_write,
scoped_refptr<TrackedCallback> callback);
void DisconnectImpl();
- int32_t SetOptionImpl(PP_TCPSocketOption_Private name,
+ int32_t SetOptionImpl(PP_TCPSocket_Option_Dev name,
const PP_Var& value,
scoped_refptr<TrackedCallback> callback);
@@ -111,7 +128,7 @@ class PPAPI_SHARED_EXPORT TCPSocketShared {
scoped_refptr<TrackedCallback> ssl_handshake_callback_;
scoped_refptr<TrackedCallback> read_callback_;
scoped_refptr<TrackedCallback> write_callback_;
- scoped_refptr<TrackedCallback> set_option_callback_;
+ std::queue<scoped_refptr<TrackedCallback> > set_option_callbacks_;
char* read_buffer_;
int32_t bytes_to_read_;
diff --git a/ppapi/tests/test_tcp_socket.cc b/ppapi/tests/test_tcp_socket.cc
index 7a14fe7..d177a31 100644
--- a/ppapi/tests/test_tcp_socket.cc
+++ b/ppapi/tests/test_tcp_socket.cc
@@ -92,21 +92,52 @@ std::string TestTCPSocket::TestReadWrite() {
std::string TestTCPSocket::TestSetOption() {
pp::TCPSocket_Dev socket(instance_);
- TestCompletionCallback cb(instance_->pp_instance(), callback_type());
-
- cb.WaitForResult(
- socket.SetOption(PP_TCPSOCKET_OPTION_NO_DELAY, true, cb.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(cb);
- ASSERT_EQ(PP_ERROR_FAILED, cb.result());
-
- cb.WaitForResult(socket.Connect(addr_, cb.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(cb);
- ASSERT_EQ(PP_OK, cb.result());
-
- cb.WaitForResult(
- socket.SetOption(PP_TCPSOCKET_OPTION_NO_DELAY, true, cb.GetCallback()));
- CHECK_CALLBACK_BEHAVIOR(cb);
- ASSERT_EQ(PP_OK, cb.result());
+ TestCompletionCallback cb_1(instance_->pp_instance(), callback_type());
+ TestCompletionCallback cb_2(instance_->pp_instance(), callback_type());
+ TestCompletionCallback cb_3(instance_->pp_instance(), callback_type());
+
+ // These options cannot be set before the socket is connected.
+ int32_t result_1 = socket.SetOption(PP_TCPSOCKET_OPTION_NO_DELAY,
+ true, cb_1.GetCallback());
+ int32_t result_2 = socket.SetOption(PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE,
+ 256, cb_2.GetCallback());
+ int32_t result_3 = socket.SetOption(PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE,
+ 512, cb_3.GetCallback());
+
+ cb_1.WaitForResult(result_1);
+ CHECK_CALLBACK_BEHAVIOR(cb_1);
+ ASSERT_EQ(PP_ERROR_FAILED, cb_1.result());
+
+ cb_2.WaitForResult(result_2);
+ CHECK_CALLBACK_BEHAVIOR(cb_2);
+ ASSERT_EQ(PP_ERROR_FAILED, cb_2.result());
+
+ cb_3.WaitForResult(result_3);
+ CHECK_CALLBACK_BEHAVIOR(cb_3);
+ ASSERT_EQ(PP_ERROR_FAILED, cb_3.result());
+
+ cb_1.WaitForResult(socket.Connect(addr_, cb_1.GetCallback()));
+ CHECK_CALLBACK_BEHAVIOR(cb_1);
+ ASSERT_EQ(PP_OK, cb_1.result());
+
+ result_1 = socket.SetOption(PP_TCPSOCKET_OPTION_NO_DELAY,
+ false, cb_1.GetCallback());
+ result_2 = socket.SetOption(PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE,
+ 512, cb_2.GetCallback());
+ result_3 = socket.SetOption(PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE,
+ 1024, cb_3.GetCallback());
+
+ cb_1.WaitForResult(result_1);
+ CHECK_CALLBACK_BEHAVIOR(cb_1);
+ ASSERT_EQ(PP_OK, cb_1.result());
+
+ cb_2.WaitForResult(result_2);
+ CHECK_CALLBACK_BEHAVIOR(cb_2);
+ ASSERT_EQ(PP_OK, cb_2.result());
+
+ cb_3.WaitForResult(result_3);
+ CHECK_CALLBACK_BEHAVIOR(cb_3);
+ ASSERT_EQ(PP_OK, cb_3.result());
PASS();
}
diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.cc b/webkit/plugins/ppapi/mock_plugin_delegate.cc
index 5f27a2e..10c0253d 100644
--- a/webkit/plugins/ppapi/mock_plugin_delegate.cc
+++ b/webkit/plugins/ppapi/mock_plugin_delegate.cc
@@ -283,9 +283,10 @@ void MockPluginDelegate::TCPSocketWrite(uint32 socket_id,
const std::string& buffer) {
}
-void MockPluginDelegate::TCPSocketSetBoolOption(uint32 socket_id,
- PP_TCPSocketOption_Private name,
- bool value) {
+void MockPluginDelegate::TCPSocketSetOption(
+ uint32 socket_id,
+ PP_TCPSocket_Option_Dev name,
+ const ::ppapi::SocketOptionData& value) {
}
void MockPluginDelegate::TCPSocketDisconnect(uint32 socket_id) {
diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.h b/webkit/plugins/ppapi/mock_plugin_delegate.h
index c1d74f0..7d1abb3 100644
--- a/webkit/plugins/ppapi/mock_plugin_delegate.h
+++ b/webkit/plugins/ppapi/mock_plugin_delegate.h
@@ -132,9 +132,9 @@ class MockPluginDelegate : public PluginDelegate {
virtual void TCPSocketRead(uint32 socket_id, int32_t bytes_to_read);
virtual void TCPSocketWrite(uint32 socket_id, const std::string& buffer);
virtual void TCPSocketDisconnect(uint32 socket_id);
- virtual void TCPSocketSetBoolOption(uint32 socket_id,
- PP_TCPSocketOption_Private name,
- bool value);
+ virtual void TCPSocketSetOption(uint32 socket_id,
+ PP_TCPSocket_Option_Dev name,
+ const ::ppapi::SocketOptionData& value);
virtual void RegisterTCPSocket(PPB_TCPSocket_Private_Impl* socket,
uint32 socket_id);
virtual void TCPServerSocketListen(PP_Resource socket_resource,
diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h
index 962c78b..1e1dfb5 100644
--- a/webkit/plugins/ppapi/plugin_delegate.h
+++ b/webkit/plugins/ppapi/plugin_delegate.h
@@ -22,6 +22,7 @@
#include "media/video/video_decode_accelerator.h"
#include "ppapi/c/dev/pp_video_dev.h"
#include "ppapi/c/dev/ppb_device_ref_dev.h"
+#include "ppapi/c/dev/ppb_tcp_socket_dev.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_file_info.h"
@@ -69,6 +70,7 @@ struct Mailbox;
namespace ppapi {
class PepperFilePath;
class PPB_X509Certificate_Fields;
+class SocketOptionData;
struct DeviceRefData;
struct HostPortPair;
struct Preferences;
@@ -571,9 +573,9 @@ class PluginDelegate {
virtual void TCPSocketRead(uint32 socket_id, int32_t bytes_to_read) = 0;
virtual void TCPSocketWrite(uint32 socket_id, const std::string& buffer) = 0;
virtual void TCPSocketDisconnect(uint32 socket_id) = 0;
- virtual void TCPSocketSetBoolOption(uint32 socket_id,
- PP_TCPSocketOption_Private name,
- bool value) = 0;
+ virtual void TCPSocketSetOption(uint32 socket_id,
+ PP_TCPSocket_Option_Dev name,
+ const ::ppapi::SocketOptionData& value) = 0;
virtual void RegisterTCPSocket(PPB_TCPSocket_Private_Impl* socket,
uint32 socket_id) = 0;
diff --git a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc
index b2c80d1..318a206 100644
--- a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc
+++ b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.cc
@@ -4,6 +4,7 @@
#include "webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h"
+#include "ppapi/shared_impl/socket_option_data.h"
#include "webkit/plugins/ppapi/host_globals.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
@@ -110,14 +111,14 @@ void PPB_TCPSocket_Private_Impl::SendDisconnect() {
plugin_delegate->TCPSocketDisconnect(socket_id_);
}
-void PPB_TCPSocket_Private_Impl::SendSetBoolOption(
- PP_TCPSocketOption_Private name,
- bool value) {
+void PPB_TCPSocket_Private_Impl::SendSetOption(
+ PP_TCPSocket_Option_Dev name,
+ const ::ppapi::SocketOptionData& value) {
PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
if (!plugin_delegate)
return;
- plugin_delegate->TCPSocketSetBoolOption(socket_id_, name, value);
+ plugin_delegate->TCPSocketSetOption(socket_id_, name, value);
}
PluginDelegate* PPB_TCPSocket_Private_Impl::GetPluginDelegate(
diff --git a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h
index 80d077a..9d7545e 100644
--- a/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h
+++ b/webkit/plugins/ppapi/ppb_tcp_socket_private_impl.h
@@ -35,8 +35,8 @@ class PPB_TCPSocket_Private_Impl : public ::ppapi::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;
+ virtual void SendSetOption(PP_TCPSocket_Option_Dev name,
+ const ::ppapi::SocketOptionData& value) OVERRIDE;
private:
PPB_TCPSocket_Private_Impl(PP_Instance instance, uint32 socket_id);