17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file. 47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/proxy/tcp_socket_resource_base.h" 67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 7424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include <cstring> 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/bind.h" 107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/logging.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/c/pp_bool.h" 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/proxy/error_conversion.h" 14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_globals.h" 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/shared_impl/socket_option_data.h" 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/shared_impl/var.h" 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/shared_impl/var_tracker.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/thunk/enter.h" 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/thunk/ppb_x509_certificate_private_api.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace ppapi { 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace proxy { 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const int32_t TCPSocketResourceBase::kMaxReadSize = 1024 * 1024; 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const int32_t TCPSocketResourceBase::kMaxWriteSize = 1024 * 1024; 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const int32_t TCPSocketResourceBase::kMaxSendBufferSize = 29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1024 * TCPSocketResourceBase::kMaxWriteSize; 30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const int32_t TCPSocketResourceBase::kMaxReceiveBufferSize = 31424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 1024 * TCPSocketResourceBase::kMaxReadSize; 32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TCPSocketResourceBase::TCPSocketResourceBase(Connection connection, 34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PP_Instance instance, 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TCPSocketVersion version) 36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) : PluginResource(connection, instance), 3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_(TCPSocketState::INITIAL), 38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) read_buffer_(NULL), 39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bytes_to_read_(-1), 4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accepted_tcp_socket_(NULL), 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) version_(version) { 42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) local_addr_.size = 0; 43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memset(local_addr_.data, 0, 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) arraysize(local_addr_.data) * sizeof(*local_addr_.data)); 45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) remote_addr_.size = 0; 46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memset(remote_addr_.data, 0, 47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) arraysize(remote_addr_.data) * sizeof(*remote_addr_.data)); 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TCPSocketResourceBase::TCPSocketResourceBase( 51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Connection connection, 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PP_Instance instance, 5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TCPSocketVersion version, 547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const PP_NetAddress_Private& local_addr, 55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PP_NetAddress_Private& remote_addr) 56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) : PluginResource(connection, instance), 5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_(TCPSocketState::CONNECTED), 58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) read_buffer_(NULL), 59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bytes_to_read_(-1), 60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) local_addr_(local_addr), 61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) remote_addr_(remote_addr), 6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accepted_tcp_socket_(NULL), 6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) version_(version) { 647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TCPSocketResourceBase::~TCPSocketResourceBase() { 6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CloseImpl(); 6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int32_t TCPSocketResourceBase::BindImpl( 7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const PP_NetAddress_Private* addr, 7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!addr) 7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.IsPending(TCPSocketState::BIND)) 7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_INPROGRESS; 7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::BIND)) 7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bind_callback_ = callback; 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.SetPendingTransition(TCPSocketState::BIND); 8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_BindReply>( 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) BROWSER, 8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PpapiHostMsg_TCPSocket_Bind(*addr), 8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgBindReply, 87d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::Unretained(this)), 88d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) callback); 8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t TCPSocketResourceBase::ConnectImpl( 93424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char* host, 94424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) uint16_t port, 95424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!host) 977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.IsPending(TCPSocketState::CONNECT)) 9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_INPROGRESS; 10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::CONNECT)) 1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_FAILED; 1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) connect_callback_ = callback; 10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.SetPendingTransition(TCPSocketState::CONNECT); 105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_ConnectReply>( 107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BROWSER, 108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiHostMsg_TCPSocket_Connect(host, port), 109424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgConnectReply, 110d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::Unretained(this)), 111d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) callback); 1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t TCPSocketResourceBase::ConnectWithNetAddressImpl( 1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const PP_NetAddress_Private* addr, 1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!addr) 1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.IsPending(TCPSocketState::CONNECT)) 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_INPROGRESS; 12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::CONNECT)) 1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_FAILED; 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) connect_callback_ = callback; 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.SetPendingTransition(TCPSocketState::CONNECT); 127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_ConnectReply>( 129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BROWSER, 130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiHostMsg_TCPSocket_ConnectWithNetAddress(*addr), 131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgConnectReply, 132d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::Unretained(this)), 133d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) callback); 1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PP_Bool TCPSocketResourceBase::GetLocalAddressImpl( 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_NetAddress_Private* local_addr) { 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsBound() || !local_addr) 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_FALSE; 1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *local_addr = local_addr_; 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_TRUE; 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PP_Bool TCPSocketResourceBase::GetRemoteAddressImpl( 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_NetAddress_Private* remote_addr) { 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected() || !remote_addr) 1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_FALSE; 1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *remote_addr = remote_addr_; 1507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_TRUE; 1517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 153424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t TCPSocketResourceBase::SSLHandshakeImpl( 1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const char* server_name, 1557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) uint16_t server_port, 1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!server_name) 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.IsPending(TCPSocketState::SSL_CONNECT) || 1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TrackedCallback::IsPending(read_callback_) || 162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) TrackedCallback::IsPending(write_callback_)) { 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_INPROGRESS; 164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::SSL_CONNECT)) 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 1677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ssl_handshake_callback_ = callback; 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.SetPendingTransition(TCPSocketState::SSL_CONNECT); 1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_SSLHandshakeReply>( 172424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BROWSER, 173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiHostMsg_TCPSocket_SSLHandshake(server_name, 174424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) server_port, 175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) trusted_certificates_, 176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) untrusted_certificates_), 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgSSLHandshakeReply, 178d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::Unretained(this)), 179d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) callback); 1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PP_Resource TCPSocketResourceBase::GetServerCertificateImpl() { 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!server_certificate_.get()) 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return 0; 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return server_certificate_->GetReference(); 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PP_Bool TCPSocketResourceBase::AddChainBuildingCertificateImpl( 1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_Resource certificate, 1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_Bool trusted) { 1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // TODO(raymes): The plumbing for this functionality is implemented but the 1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // certificates aren't yet used for the connection, so just return false for 1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // now. 1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_FALSE; 1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) thunk::EnterResourceNoLock<thunk::PPB_X509Certificate_Private_API> 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) enter_cert(certificate, true); 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (enter_cert.failed()) 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_FALSE; 2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_Var der_var = enter_cert.object()->GetField( 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_X509CERTIFICATE_PRIVATE_RAW); 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ArrayBufferVar* der_array_buffer = ArrayBufferVar::FromPPVar(der_var); 2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_Bool success = PP_FALSE; 2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (der_array_buffer) { 2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const char* der_bytes = static_cast<const char*>(der_array_buffer->Map()); 2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) uint32_t der_length = der_array_buffer->ByteLength(); 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::vector<char> der(der_bytes, der_bytes + der_length); 2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (PP_ToBool(trusted)) 2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) trusted_certificates_.push_back(der); 2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) else 2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) untrusted_certificates_.push_back(der); 2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) success = PP_TRUE; 2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(der_var); 2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return success; 2187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t TCPSocketResourceBase::ReadImpl( 221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) char* buffer, 222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t bytes_to_read, 223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!buffer || bytes_to_read <= 0) 2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 2267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected()) 2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_FAILED; 2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (TrackedCallback::IsPending(read_callback_) || 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.IsPending(TCPSocketState::SSL_CONNECT)) 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_INPROGRESS; 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) read_buffer_ = buffer; 2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_to_read_ = std::min(bytes_to_read, kMaxReadSize); 2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) read_callback_ = callback; 2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 236424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_ReadReply>( 237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BROWSER, 238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiHostMsg_TCPSocket_Read(bytes_to_read_), 239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgReadReply, 240d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::Unretained(this)), 241d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) callback); 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t TCPSocketResourceBase::WriteImpl( 246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char* buffer, 247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t bytes_to_write, 248424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!buffer || bytes_to_write <= 0) 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 25268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected()) 2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_FAILED; 2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (TrackedCallback::IsPending(write_callback_) || 25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.IsPending(TCPSocketState::SSL_CONNECT)) 2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_INPROGRESS; 2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (bytes_to_write > kMaxWriteSize) 2597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_to_write = kMaxWriteSize; 2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) write_callback_ = callback; 2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_WriteReply>( 264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BROWSER, 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiHostMsg_TCPSocket_Write(std::string(buffer, bytes_to_write)), 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgWriteReply, 267d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::Unretained(this)), 268d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) callback); 2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int32_t TCPSocketResourceBase::ListenImpl( 27368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int32_t backlog, 27468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 27568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (backlog <= 0) 27668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 27768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.IsPending(TCPSocketState::LISTEN)) 27868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_INPROGRESS; 27968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::LISTEN)) 28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) listen_callback_ = callback; 28368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.SetPendingTransition(TCPSocketState::LISTEN); 28468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_ListenReply>( 28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) BROWSER, 28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PpapiHostMsg_TCPSocket_Listen(backlog), 28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgListenReply, 289d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::Unretained(this)), 290d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) callback); 29168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 29268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 29368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 29468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int32_t TCPSocketResourceBase::AcceptImpl( 29568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PP_Resource* accepted_tcp_socket, 29668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 29768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!accepted_tcp_socket) 29868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 29968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (TrackedCallback::IsPending(accept_callback_)) 30068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_INPROGRESS; 30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.state() != TCPSocketState::LISTENING) 30268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 30368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 30468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accept_callback_ = callback; 30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accepted_tcp_socket_ = accepted_tcp_socket; 30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_AcceptReply>( 30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) BROWSER, 30968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PpapiHostMsg_TCPSocket_Accept(), 31068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgAcceptReply, 311d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::Unretained(this)), 312d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) callback); 31368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 31468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 31568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 31668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TCPSocketResourceBase::CloseImpl() { 31768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.state() == TCPSocketState::CLOSED) 3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 32068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.DoTransition(TCPSocketState::CLOSE, true); 3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 32268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Post(BROWSER, PpapiHostMsg_TCPSocket_Close()); 3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 32468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PostAbortIfNecessary(&bind_callback_); 3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PostAbortIfNecessary(&connect_callback_); 3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PostAbortIfNecessary(&ssl_handshake_callback_); 3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PostAbortIfNecessary(&read_callback_); 3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PostAbortIfNecessary(&write_callback_); 32968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PostAbortIfNecessary(&listen_callback_); 33068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PostAbortIfNecessary(&accept_callback_); 3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) read_buffer_ = NULL; 3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_to_read_ = -1; 3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) server_certificate_ = NULL; 33468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accepted_tcp_socket_ = NULL; 3357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t TCPSocketResourceBase::SetOptionImpl( 338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_TCPSocket_Option name, 3397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const PP_Var& value, 3407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SocketOptionData option_data; 3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) switch (name) { 343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case PP_TCPSOCKET_OPTION_NO_DELAY: { 34468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected()) 34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (value.type != PP_VARTYPE_BOOL) 3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch option_data.SetBool(PP_ToBool(value.value.as_bool)); 350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: 353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { 35468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected()) 35568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 35668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (value.type != PP_VARTYPE_INT32) 358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return PP_ERROR_BADARGUMENT; 359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch option_data.SetInt32(value.value.as_int); 360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default: { 363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NOTREACHED(); 3647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch set_option_callbacks_.push(callback); 369424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 370424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_SetOptionReply>( 371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BROWSER, 372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiHostMsg_TCPSocket_SetOption(name, option_data), 373424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgSetOptionReply, 374d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) base::Unretained(this)), 375d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) callback); 376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return PP_OK_COMPLETIONPENDING; 3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::PostAbortIfNecessary( 380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<TrackedCallback>* callback) { 381424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (TrackedCallback::IsPending(*callback)) 382424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) (*callback)->PostAbort(); 383424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 38568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgBindReply( 38668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ResourceMessageReplyParams& params, 38768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const PP_NetAddress_Private& local_addr) { 38868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // It is possible that CloseImpl() has been called. We don't want to update 38968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // class members in this case. 39068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsPending(TCPSocketState::BIND)) 39168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 39268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 39368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(TrackedCallback::IsPending(bind_callback_)); 39468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (params.result() == PP_OK) { 39568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) local_addr_ = local_addr; 39668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(true); 39768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 39868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(false); 39968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 40068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RunCallback(bind_callback_, params.result()); 40168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 40268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 403424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgConnectReply( 404424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ResourceMessageReplyParams& params, 405424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PP_NetAddress_Private& local_addr, 406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PP_NetAddress_Private& remote_addr) { 40768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // It is possible that CloseImpl() has been called. We don't want to update 40868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // class members in this case. 40968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsPending(TCPSocketState::CONNECT)) 410424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 411424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 41268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(TrackedCallback::IsPending(connect_callback_)); 413424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (params.result() == PP_OK) { 414424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) local_addr_ = local_addr; 415424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) remote_addr_ = remote_addr; 41668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(true); 41768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 41868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (version_ == TCP_SOCKET_VERSION_1_1_OR_ABOVE) { 41968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(false); 42068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 42168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // In order to maintain backward compatibility, allow to connect the 42268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // socket again. 42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_ = TCPSocketState(TCPSocketState::INITIAL); 42468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 425424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 426424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RunCallback(connect_callback_, params.result()); 427424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 428424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 429424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgSSLHandshakeReply( 430424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ResourceMessageReplyParams& params, 431424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PPB_X509Certificate_Fields& certificate_fields) { 43268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // It is possible that CloseImpl() has been called. We don't want to 43368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // update class members in this case. 43468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsPending(TCPSocketState::SSL_CONNECT)) 435424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 436424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 43768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(TrackedCallback::IsPending(ssl_handshake_callback_)); 438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (params.result() == PP_OK) { 43968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(true); 440424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) server_certificate_ = new PPB_X509Certificate_Private_Shared( 441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OBJECT_IS_PROXY, 442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pp_instance(), 443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) certificate_fields); 444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 44568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(false); 446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 44768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RunCallback(ssl_handshake_callback_, params.result()); 448424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 449424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgReadReply( 451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ResourceMessageReplyParams& params, 452424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& data) { 45368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // It is possible that CloseImpl() has been called. We shouldn't access the 45468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // buffer in that case. The user may have released it. 45568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected() || !TrackedCallback::IsPending(read_callback_) || 45668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !read_buffer_) { 457424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 45868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 459424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 460424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const bool succeeded = params.result() == PP_OK; 461424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (succeeded) { 462424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_); 463424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!data.empty()) 464424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memmove(read_buffer_, data.c_str(), data.size()); 465424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 4667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) read_buffer_ = NULL; 4677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_to_read_ = -1; 4687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 46968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RunCallback(read_callback_, 47068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) succeeded ? static_cast<int32_t>(data.size()) : params.result()); 4717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgWriteReply( 474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ResourceMessageReplyParams& params) { 47568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected() || !TrackedCallback::IsPending(write_callback_)) 476424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 477424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RunCallback(write_callback_, params.result()); 4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 48068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgListenReply( 48168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ResourceMessageReplyParams& params) { 48268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsPending(TCPSocketState::LISTEN)) 48368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 48468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 48568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(TrackedCallback::IsPending(listen_callback_)); 48668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(params.result() == PP_OK); 48768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 48868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RunCallback(listen_callback_, params.result()); 48968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 49068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 49168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgAcceptReply( 49268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ResourceMessageReplyParams& params, 49368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int pending_host_id, 49468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const PP_NetAddress_Private& local_addr, 49568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const PP_NetAddress_Private& remote_addr) { 49668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // It is possible that CloseImpl() has been called. We shouldn't access the 49768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // output parameter in that case. The user may have released it. 49868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.state() != TCPSocketState::LISTENING || 49968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !TrackedCallback::IsPending(accept_callback_) || !accepted_tcp_socket_) { 50068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 50168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 50368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (params.result() == PP_OK) { 50468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) *accepted_tcp_socket_ = CreateAcceptedSocket(pending_host_id, local_addr, 50568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) remote_addr); 50668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accepted_tcp_socket_ = NULL; 50868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RunCallback(accept_callback_, params.result()); 50968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 51068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 511424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgSetOptionReply( 512424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ResourceMessageReplyParams& params) { 513424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (set_option_callbacks_.empty()) { 514424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED(); 515424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 516424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 517424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<TrackedCallback> callback = set_option_callbacks_.front(); 518424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) set_option_callbacks_.pop(); 519424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (TrackedCallback::IsPending(callback)) 520424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RunCallback(callback, params.result()); 521424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 522424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 523424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::RunCallback(scoped_refptr<TrackedCallback> callback, 524424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t pp_result) { 52568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) callback->Run(ConvertNetworkAPIErrorForCompatibility( 52668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pp_result, version_ == TCP_SOCKET_VERSION_PRIVATE)); 5277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace ppapi 530424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace proxy 531