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, 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this)), 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (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, 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this)), 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (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, 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this)), 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (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, 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this)), 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (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) { 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(raymes): This is exposed in the private PPB_TCPSocket_Private 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // interface for Flash but isn't currently implemented due to security 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // implications. It is exposed so that it can be hooked up on the Flash side 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // and if we decide to implement it we can do so without modifying the Flash 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // codebase. 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTIMPLEMENTED(); 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_FALSE; 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t TCPSocketResourceBase::ReadImpl( 202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) char* buffer, 203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t bytes_to_read, 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!buffer || bytes_to_read <= 0) 2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected()) 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_FAILED; 2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (TrackedCallback::IsPending(read_callback_) || 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.IsPending(TCPSocketState::SSL_CONNECT)) 2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_INPROGRESS; 2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) read_buffer_ = buffer; 2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_to_read_ = std::min(bytes_to_read, kMaxReadSize); 2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) read_callback_ = callback; 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_ReadReply>( 218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BROWSER, 219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiHostMsg_TCPSocket_Read(bytes_to_read_), 220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgReadReply, 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this)), 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback); 2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 226424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t TCPSocketResourceBase::WriteImpl( 227424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const char* buffer, 228424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t bytes_to_write, 229424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!buffer || bytes_to_write <= 0) 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 2327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected()) 2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_FAILED; 2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (TrackedCallback::IsPending(write_callback_) || 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.IsPending(TCPSocketState::SSL_CONNECT)) 2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_INPROGRESS; 2387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (bytes_to_write > kMaxWriteSize) 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_to_write = kMaxWriteSize; 2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) write_callback_ = callback; 2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_WriteReply>( 245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BROWSER, 246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiHostMsg_TCPSocket_Write(std::string(buffer, bytes_to_write)), 247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgWriteReply, 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this)), 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback); 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 25368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int32_t TCPSocketResourceBase::ListenImpl( 25468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int32_t backlog, 25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 25668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (backlog <= 0) 25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.IsPending(TCPSocketState::LISTEN)) 25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_INPROGRESS; 26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::LISTEN)) 26168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) listen_callback_ = callback; 26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.SetPendingTransition(TCPSocketState::LISTEN); 26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 26668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_ListenReply>( 26768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) BROWSER, 26868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PpapiHostMsg_TCPSocket_Listen(backlog), 26968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgListenReply, 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this)), 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback); 27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 27368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 27468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 27568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int32_t TCPSocketResourceBase::AcceptImpl( 27668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PP_Resource* accepted_tcp_socket, 27768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 27868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!accepted_tcp_socket) 27968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (TrackedCallback::IsPending(accept_callback_)) 28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_INPROGRESS; 28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.state() != TCPSocketState::LISTENING) 28368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 28468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accept_callback_ = callback; 28668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accepted_tcp_socket_ = accepted_tcp_socket; 28768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 28868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_AcceptReply>( 28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) BROWSER, 29068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PpapiHostMsg_TCPSocket_Accept(), 29168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgAcceptReply, 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this)), 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback); 29468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 29568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 29668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 29768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TCPSocketResourceBase::CloseImpl() { 29868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.state() == TCPSocketState::CLOSED) 2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 3007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 30168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.DoTransition(TCPSocketState::CLOSE, true); 3027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 30368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Post(BROWSER, PpapiHostMsg_TCPSocket_Close()); 3047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PostAbortIfNecessary(&bind_callback_); 3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PostAbortIfNecessary(&connect_callback_); 3077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PostAbortIfNecessary(&ssl_handshake_callback_); 3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PostAbortIfNecessary(&read_callback_); 3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PostAbortIfNecessary(&write_callback_); 31068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PostAbortIfNecessary(&listen_callback_); 31168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PostAbortIfNecessary(&accept_callback_); 3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) read_buffer_ = NULL; 3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_to_read_ = -1; 3147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) server_certificate_ = NULL; 31568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accepted_tcp_socket_ = NULL; 3167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t TCPSocketResourceBase::SetOptionImpl( 319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_TCPSocket_Option name, 3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const PP_Var& value, 3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<TrackedCallback> callback) { 322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SocketOptionData option_data; 3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) switch (name) { 324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case PP_TCPSOCKET_OPTION_NO_DELAY: { 32568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected()) 32668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 32768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (value.type != PP_VARTYPE_BOOL) 3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch option_data.SetBool(PP_ToBool(value.value.as_bool)); 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { 33568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected()) 33668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 33768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (value.type != PP_VARTYPE_INT32) 339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return PP_ERROR_BADARGUMENT; 340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch option_data.SetInt32(value.value.as_int); 341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default: { 344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NOTREACHED(); 3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch set_option_callbacks_.push(callback); 350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) Call<PpapiPluginMsg_TCPSocket_SetOptionReply>( 352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BROWSER, 353424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiHostMsg_TCPSocket_SetOption(name, option_data), 354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&TCPSocketResourceBase::OnPluginMsgSetOptionReply, 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Unretained(this)), 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback); 357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return PP_OK_COMPLETIONPENDING; 3587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 3597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 360424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::PostAbortIfNecessary( 361424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<TrackedCallback>* callback) { 362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (TrackedCallback::IsPending(*callback)) 363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) (*callback)->PostAbort(); 364424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 365424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgBindReply( 36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ResourceMessageReplyParams& params, 36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const PP_NetAddress_Private& local_addr) { 36968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // It is possible that CloseImpl() has been called. We don't want to update 37068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // class members in this case. 37168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsPending(TCPSocketState::BIND)) 37268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 37368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 37468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(TrackedCallback::IsPending(bind_callback_)); 37568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (params.result() == PP_OK) { 37668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) local_addr_ = local_addr; 37768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(true); 37868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 37968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(false); 38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RunCallback(bind_callback_, params.result()); 38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 38368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 384424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgConnectReply( 385424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ResourceMessageReplyParams& params, 386424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PP_NetAddress_Private& local_addr, 387424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PP_NetAddress_Private& remote_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::CONNECT)) 391424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 392424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 39368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(TrackedCallback::IsPending(connect_callback_)); 394424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (params.result() == PP_OK) { 395424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) local_addr_ = local_addr; 396424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) remote_addr_ = remote_addr; 39768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(true); 39868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 39968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (version_ == TCP_SOCKET_VERSION_1_1_OR_ABOVE) { 40068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(false); 40168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 40268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // In order to maintain backward compatibility, allow to connect the 40368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // socket again. 40468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_ = TCPSocketState(TCPSocketState::INITIAL); 40568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 407424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RunCallback(connect_callback_, params.result()); 408424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 409424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 410424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgSSLHandshakeReply( 411424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ResourceMessageReplyParams& params, 412424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PPB_X509Certificate_Fields& certificate_fields) { 41368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // It is possible that CloseImpl() has been called. We don't want to 41468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // update class members in this case. 41568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsPending(TCPSocketState::SSL_CONNECT)) 416424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 417424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 41868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(TrackedCallback::IsPending(ssl_handshake_callback_)); 419424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (params.result() == PP_OK) { 42068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(true); 421424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) server_certificate_ = new PPB_X509Certificate_Private_Shared( 422424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OBJECT_IS_PROXY, 423424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pp_instance(), 424424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) certificate_fields); 425424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 42668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(false); 427424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 42868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RunCallback(ssl_handshake_callback_, params.result()); 429424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 430424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 431424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgReadReply( 432424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ResourceMessageReplyParams& params, 433424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& data) { 43468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // It is possible that CloseImpl() has been called. We shouldn't access the 43568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // buffer in that case. The user may have released it. 43668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected() || !TrackedCallback::IsPending(read_callback_) || 43768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !read_buffer_) { 438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 43968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 440424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const bool succeeded = params.result() == PP_OK; 442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (succeeded) { 443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_); 444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!data.empty()) 445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memmove(read_buffer_, data.c_str(), data.size()); 446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 4477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) read_buffer_ = NULL; 4487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bytes_to_read_ = -1; 4497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 45068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RunCallback(read_callback_, 45168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) succeeded ? static_cast<int32_t>(data.size()) : params.result()); 4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgWriteReply( 455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ResourceMessageReplyParams& params) { 45668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected() || !TrackedCallback::IsPending(write_callback_)) 457424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RunCallback(write_callback_, params.result()); 4597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 4607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 46168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgListenReply( 46268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ResourceMessageReplyParams& params) { 46368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsPending(TCPSocketState::LISTEN)) 46468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 46568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 46668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(TrackedCallback::IsPending(listen_callback_)); 46768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(params.result() == PP_OK); 46868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 46968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RunCallback(listen_callback_, params.result()); 47068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 47168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 47268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgAcceptReply( 47368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ResourceMessageReplyParams& params, 47468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int pending_host_id, 47568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const PP_NetAddress_Private& local_addr, 47668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const PP_NetAddress_Private& remote_addr) { 47768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // It is possible that CloseImpl() has been called. We shouldn't access the 47868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // output parameter in that case. The user may have released it. 47968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.state() != TCPSocketState::LISTENING || 48068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !TrackedCallback::IsPending(accept_callback_) || !accepted_tcp_socket_) { 48168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 48268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 48368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 48468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (params.result() == PP_OK) { 48568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) *accepted_tcp_socket_ = CreateAcceptedSocket(pending_host_id, local_addr, 48668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) remote_addr); 48768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 48868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accepted_tcp_socket_ = NULL; 48968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RunCallback(accept_callback_, params.result()); 49068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 49168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 492424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::OnPluginMsgSetOptionReply( 493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ResourceMessageReplyParams& params) { 494424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (set_option_callbacks_.empty()) { 495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED(); 496424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 497424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 498424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_refptr<TrackedCallback> callback = set_option_callbacks_.front(); 499424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) set_option_callbacks_.pop(); 500424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (TrackedCallback::IsPending(callback)) 501424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RunCallback(callback, params.result()); 502424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 503424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 504424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void TCPSocketResourceBase::RunCallback(scoped_refptr<TrackedCallback> callback, 505424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t pp_result) { 50668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) callback->Run(ConvertNetworkAPIErrorForCompatibility( 50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pp_result, version_ == TCP_SOCKET_VERSION_PRIVATE)); 5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace ppapi 511424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace proxy 512