1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// found in the LICENSE file. 4424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h" 6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <cstring> 868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/bind.h" 10424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/logging.h" 1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "build/build_config.h" 12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" 1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" 14424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_socket_utils.h" 15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/public/browser/browser_context.h" 16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/public/browser/resource_context.h" 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "content/public/common/socket_permission_request.h" 2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/base/address_family.h" 21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/base/host_port_pair.h" 22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/base/io_buffer.h" 23424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/base/net_errors.h" 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/dns/single_request_host_resolver.h" 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/socket/client_socket_factory.h" 26424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/socket/client_socket_handle.h" 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/socket/ssl_client_socket.h" 28424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "net/socket/tcp_client_socket.h" 29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/host/dispatch_host_message.h" 30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/host/error_conversion.h" 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ppapi/host/ppapi_host.h" 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ppapi/host/resource_host.h" 33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/proxy/tcp_socket_resource_base.h" 35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ppapi/shared_impl/private/net_address_private_impl.h" 36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using ppapi::NetAddressPrivateImpl; 38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using ppapi::host::NetErrorToPepperError; 39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)using ppapi::proxy::TCPSocketResourceBase; 4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using ppapi::TCPSocketState; 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)using ppapi::TCPSocketVersion; 42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace { 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)size_t g_num_instances = 0; 46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} // namespace 48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace content { 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter( 5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ContentBrowserPepperHostFactory* factory, 53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BrowserPpapiHostImpl* host, 54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PP_Instance instance, 5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TCPSocketVersion version) 5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : version_(version), 5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) external_plugin_(host->external_plugin()), 58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) render_process_id_(0), 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_frame_id_(0), 6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ppapi_host_(host->GetPpapiHost()), 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) factory_(factory), 6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) instance_(instance), 6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_(TCPSocketState::INITIAL), 64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) end_of_file_reached_(false), 6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) address_index_(0), 6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) socket_(new net::TCPSocket(NULL, net::NetLog::Source())), 6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ssl_context_helper_(host->ssl_context_helper()), 6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending_accept_(false) { 70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(host); 71424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ++g_num_instances; 72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!host->GetRenderFrameIDsForInstance( 73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch instance, &render_process_id_, &render_frame_id_)) { 74424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED(); 75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter( 79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BrowserPpapiHostImpl* host, 80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PP_Instance instance, 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TCPSocketVersion version, 8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_ptr<net::TCPSocket> socket) 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : version_(version), 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) external_plugin_(host->external_plugin()), 85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) render_process_id_(0), 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_frame_id_(0), 8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ppapi_host_(host->GetPpapiHost()), 8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) factory_(NULL), 8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) instance_(instance), 9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_(TCPSocketState::CONNECTED), 91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) end_of_file_reached_(false), 9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), 931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) address_index_(0), 9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) socket_(socket.Pass()), 9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ssl_context_helper_(host->ssl_context_helper()), 9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending_accept_(false) { 97424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(host); 9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_NE(version, ppapi::TCP_SOCKET_VERSION_1_0); 9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ++g_num_instances; 101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!host->GetRenderFrameIDsForInstance( 102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch instance, &render_process_id_, &render_frame_id_)) { 103424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED(); 104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 107424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PepperTCPSocketMessageFilter::~PepperTCPSocketMessageFilter() { 108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (socket_) 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) socket_->Close(); 11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (ssl_socket_) 11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ssl_socket_->Disconnect(); 112424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) --g_num_instances; 113424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 114424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// static 116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)size_t PepperTCPSocketMessageFilter::GetNumInstances() { 117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return g_num_instances; 118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)scoped_refptr<base::TaskRunner> 121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)PepperTCPSocketMessageFilter::OverrideTaskRunnerForMessage( 122424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const IPC::Message& message) { 123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) switch (message.type()) { 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case PpapiHostMsg_TCPSocket_Bind::ID: 125424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case PpapiHostMsg_TCPSocket_Connect::ID: 126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case PpapiHostMsg_TCPSocket_ConnectWithNetAddress::ID: 12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case PpapiHostMsg_TCPSocket_Listen::ID: 128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); 129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case PpapiHostMsg_TCPSocket_SSLHandshake::ID: 130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case PpapiHostMsg_TCPSocket_Read::ID: 131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case PpapiHostMsg_TCPSocket_Write::ID: 13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case PpapiHostMsg_TCPSocket_Accept::ID: 13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) case PpapiHostMsg_TCPSocket_Close::ID: 134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case PpapiHostMsg_TCPSocket_SetOption::ID: 135424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 136424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return NULL; 138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 139424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 140424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnResourceMessageReceived( 141424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const IPC::Message& msg, 142424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ppapi::host::HostMessageContext* context) { 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_BEGIN_MESSAGE_MAP(PepperTCPSocketMessageFilter, msg) 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Bind, OnMsgBind) 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Connect, 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnMsgConnect) 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL( 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PpapiHostMsg_TCPSocket_ConnectWithNetAddress, 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnMsgConnectWithNetAddress) 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_SSLHandshake, 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnMsgSSLHandshake) 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Read, OnMsgRead) 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Write, OnMsgWrite) 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Listen, 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnMsgListen) 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TCPSocket_Accept, 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnMsgAccept) 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TCPSocket_Close, 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnMsgClose) 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_SetOption, 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnMsgSetOption) 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_END_MESSAGE_MAP() 163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_FAILED; 164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnMsgBind( 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ppapi::host::HostMessageContext* context, 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const PP_NetAddress_Private& net_addr) { 169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // This is only supported by PPB_TCPSocket v1.1 or above. 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (version_ != ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) { 17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) NOTREACHED(); 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_NOACCESS; 17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 177a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, 178a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch false /* private_api */, 179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch NULL, 180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch render_process_id_, 181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch render_frame_id_)) { 18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_NOACCESS; 18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bind_input_addr_ = net_addr; 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch BrowserThread::PostTask(BrowserThread::IO, 188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FROM_HERE, 189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&PepperTCPSocketMessageFilter::DoBind, 190a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch this, 191a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context->MakeReplyMessageContext(), 192a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch net_addr)); 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnMsgConnect( 197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::HostMessageContext* context, 198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& host, 199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) uint16_t port) { 200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // This is only supported by PPB_TCPSocket_Private. 20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!IsPrivateAPI()) { 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED(); 205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_NOACCESS; 206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 208a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SocketPermissionRequest request( 209a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SocketPermissionRequest::TCP_CONNECT, host, port); 210a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, 211a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch true /* private_api */, 212a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &request, 213a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch render_process_id_, 214a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch render_frame_id_)) { 215424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_NOACCESS; 216424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 217424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RenderProcessHost* render_process_host = 219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) RenderProcessHost::FromID(render_process_id_); 220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!render_process_host) 221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_FAILED; 222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BrowserContext* browser_context = render_process_host->GetBrowserContext(); 223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!browser_context || !browser_context->GetResourceContext()) 224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_FAILED; 225424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 226a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch BrowserThread::PostTask(BrowserThread::IO, 227a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FROM_HERE, 228a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&PepperTCPSocketMessageFilter::DoConnect, 229a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch this, 230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context->MakeReplyMessageContext(), 231a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch host, 232a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch port, 233a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch browser_context->GetResourceContext())); 234424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 236424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnMsgConnectWithNetAddress( 238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::HostMessageContext* context, 239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PP_NetAddress_Private& net_addr) { 240effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) content::SocketPermissionRequest request = 243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pepper_socket_utils::CreateSocketPermissionRequest( 244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) content::SocketPermissionRequest::TCP_CONNECT, net_addr); 245a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, 246a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch IsPrivateAPI(), 247a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &request, 248a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch render_process_id_, 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_frame_id_)) { 250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_NOACCESS; 251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 252424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 253424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BrowserThread::PostTask( 254a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch BrowserThread::IO, 255a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FROM_HERE, 256a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&PepperTCPSocketMessageFilter::DoConnectWithNetAddress, 257a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch this, 258a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context->MakeReplyMessageContext(), 259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch net_addr)); 260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnMsgSSLHandshake( 264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::HostMessageContext* context, 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& server_name, 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) uint16_t server_port, 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::vector<std::vector<char> >& trusted_certs, 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::vector<std::vector<char> >& untrusted_certs) { 269effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Allow to do SSL handshake only if currently the socket has been connected 272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // and there isn't pending read or write. 27368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::SSL_CONNECT) || 27468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) read_buffer_.get() || write_buffer_base_.get() || write_buffer_.get()) { 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_FAILED; 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(raymes,rsleevi): Use trusted/untrusted certificates when connecting. 27968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::IPEndPoint peer_address; 28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (socket_->GetPeerAddress(&peer_address) != net::OK) 28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<net::ClientSocketHandle> handle(new net::ClientSocketHandle()); 28468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) handle->SetSocket(make_scoped_ptr<net::StreamSocket>( 28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new net::TCPClientSocket(socket_.Pass(), peer_address))); 286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::ClientSocketFactory* factory = 287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::ClientSocketFactory::GetDefaultFactory(); 288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::HostPortPair host_port_pair(server_name, server_port); 289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::SSLClientSocketContext ssl_context; 290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ssl_context.cert_verifier = ssl_context_helper_->GetCertVerifier(); 291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ssl_context.transport_security_state = 292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ssl_context_helper_->GetTransportSecurityState(); 293a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ssl_socket_ = 294a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch factory->CreateSSLClientSocket(handle.Pass(), 295a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch host_port_pair, 296a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ssl_context_helper_->ssl_config(), 297a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ssl_context); 29868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!ssl_socket_) { 299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) LOG(WARNING) << "Failed to create an SSL client socket."; 30068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(false); 301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_FAILED; 302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 30468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.SetPendingTransition(TCPSocketState::SSL_CONNECT); 30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext reply_context( 307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) context->MakeReplyMessageContext()); 30868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int net_result = ssl_socket_->Connect( 309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted, 310a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Unretained(this), 311a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch reply_context)); 312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (net_result != net::ERR_IO_PENDING) 313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OnSSLHandshakeCompleted(reply_context, net_result); 314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 315424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 316424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 317424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnMsgRead( 318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::HostMessageContext* context, 319424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t bytes_to_read) { 320effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 32168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected() || end_of_file_reached_) 322424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_FAILED; 323424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (read_buffer_.get()) 324424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_INPROGRESS; 325424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (bytes_to_read <= 0 || 326424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bytes_to_read > TCPSocketResourceBase::kMaxReadSize) { 327424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 328424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 329424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 330424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context( 331424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) context->MakeReplyMessageContext()); 332424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) read_buffer_ = new net::IOBuffer(bytes_to_read); 33368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 33468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int net_result = net::ERR_FAILED; 33568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (socket_) { 33668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_EQ(state_.state(), TCPSocketState::CONNECTED); 337a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch net_result = 338a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch socket_->Read(read_buffer_.get(), 339a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bytes_to_read, 340a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&PepperTCPSocketMessageFilter::OnReadCompleted, 341a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Unretained(this), 342a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch reply_context)); 34368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else if (ssl_socket_) { 34468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_EQ(state_.state(), TCPSocketState::SSL_CONNECTED); 34568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net_result = ssl_socket_->Read( 34668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) read_buffer_.get(), 34768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bytes_to_read, 34868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&PepperTCPSocketMessageFilter::OnReadCompleted, 349a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Unretained(this), 350a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch reply_context)); 35168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (net_result != net::ERR_IO_PENDING) 353424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OnReadCompleted(reply_context, net_result); 354424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 355424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 356424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 357424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnMsgWrite( 358424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::HostMessageContext* context, 359424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& data) { 360effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 361424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 36268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsConnected()) 363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_FAILED; 364424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (write_buffer_base_.get() || write_buffer_.get()) 365424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_INPROGRESS; 366424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 367424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) size_t data_size = data.size(); 368424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (data_size == 0 || 369424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data_size > static_cast<size_t>(TCPSocketResourceBase::kMaxWriteSize)) { 370424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 371424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 372424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 373424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) write_buffer_base_ = new net::IOBuffer(data_size); 374424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memcpy(write_buffer_base_->data(), data.data(), data_size); 375424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) write_buffer_ = 376424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) new net::DrainableIOBuffer(write_buffer_base_.get(), data_size); 377424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DoWrite(context->MakeReplyMessageContext()); 378424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 379424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 380424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 38168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnMsgListen( 38268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ppapi::host::HostMessageContext* context, 38368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int32_t backlog) { 384effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 38568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 38668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // This is only supported by PPB_TCPSocket v1.1 or above. 38768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (version_ != ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) { 38868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) NOTREACHED(); 38968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_NOACCESS; 39068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 39168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 39268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::SocketPermissionRequest request = 39368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pepper_socket_utils::CreateSocketPermissionRequest( 39468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::SocketPermissionRequest::TCP_LISTEN, bind_input_addr_); 395a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, 396a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch false /* private_api */, 397a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &request, 398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch render_process_id_, 399a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch render_frame_id_)) { 40068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_NOACCESS; 40168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 40268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 403a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch BrowserThread::PostTask(BrowserThread::IO, 404a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FROM_HERE, 405a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&PepperTCPSocketMessageFilter::DoListen, 406a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch this, 407a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context->MakeReplyMessageContext(), 408a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch backlog)); 40968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 41068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 41168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 41268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnMsgAccept( 41368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ppapi::host::HostMessageContext* context) { 414effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 41568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 41668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (pending_accept_) 41768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_INPROGRESS; 41868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.state() != TCPSocketState::LISTENING) 41968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 42068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 42168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending_accept_ = true; 42268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context( 42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) context->MakeReplyMessageContext()); 42468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int net_result = socket_->Accept( 42568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &accepted_socket_, 42668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &accepted_address_, 42768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&PepperTCPSocketMessageFilter::OnAcceptCompleted, 428a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Unretained(this), 429a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch reply_context)); 43068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (net_result != net::ERR_IO_PENDING) 43168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) OnAcceptCompleted(reply_context, net_result); 43268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_OK_COMPLETIONPENDING; 43368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 43468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 43568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnMsgClose( 436424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::HostMessageContext* context) { 437effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 43868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.state() == TCPSocketState::CLOSED) 43968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_OK; 44068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 44168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.DoTransition(TCPSocketState::CLOSE, true); 44268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Make sure we get no further callbacks from |socket_| or |ssl_socket_|. 44368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (socket_) { 44468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) socket_->Close(); 44568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else if (ssl_socket_) { 44668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ssl_socket_->Disconnect(); 44768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 448424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_OK; 449424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)int32_t PepperTCPSocketMessageFilter::OnMsgSetOption( 452424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::HostMessageContext* context, 453424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PP_TCPSocket_Option name, 454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::SocketOptionData& value) { 455effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 456424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 457424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) switch (name) { 458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case PP_TCPSOCKET_OPTION_NO_DELAY: { 45968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.state() != TCPSocketState::CONNECTED) 46068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 46168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 462424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool boolean_value = false; 463424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!value.GetBool(&boolean_value)) 464424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 46568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return socket_->SetNoDelay(boolean_value) ? PP_OK : PP_ERROR_FAILED; 466424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 467424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: 468424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { 46968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.state() != TCPSocketState::CONNECTED) 47068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return PP_ERROR_FAILED; 47168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 472424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t integer_value = 0; 473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!value.GetInt32(&integer_value) || integer_value <= 0) 474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 475424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 476c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int net_result = net::ERR_UNEXPECTED; 477424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (name == PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE) { 478424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (integer_value > TCPSocketResourceBase::kMaxSendBufferSize) 479424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 480c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch net_result = socket_->SetSendBufferSize(integer_value); 481424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 482424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (integer_value > TCPSocketResourceBase::kMaxReceiveBufferSize) 483424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 484c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch net_result = socket_->SetReceiveBufferSize(integer_value); 485424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 486c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(wtc): Add error mapping code. 487c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED; 488424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 489424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) default: { 490424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NOTREACHED(); 491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return PP_ERROR_BADARGUMENT; 492424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 49468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 49568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 49668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void PepperTCPSocketMessageFilter::DoBind( 49768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 49868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const PP_NetAddress_Private& net_addr) { 499effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 50068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 50168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.IsPending(TCPSocketState::BIND)) { 50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendBindError(context, PP_ERROR_INPROGRESS); 50368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 50468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 50568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::BIND)) { 50668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendBindError(context, PP_ERROR_FAILED); 50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 50868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 50968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 51068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int pp_result = PP_OK; 51168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) do { 51268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::IPAddressNumber address; 51368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int port; 514a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!NetAddressPrivateImpl::NetAddressToIPEndPoint( 515a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch net_addr, &address, &port)) { 51668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pp_result = PP_ERROR_ADDRESS_INVALID; 51768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 51868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 51968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::IPEndPoint bind_addr(address, port); 52068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 52168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(!socket_->IsValid()); 52268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pp_result = NetErrorToPepperError(socket_->Open(bind_addr.GetFamily())); 52368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (pp_result != PP_OK) 52468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 52568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 52668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pp_result = NetErrorToPepperError(socket_->SetDefaultOptionsForServer()); 52768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (pp_result != PP_OK) 52868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 52968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 53068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pp_result = NetErrorToPepperError(socket_->Bind(bind_addr)); 53168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (pp_result != PP_OK) 53268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 53368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 53468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::IPEndPoint ip_end_point_local; 535a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp_result = 536a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch NetErrorToPepperError(socket_->GetLocalAddress(&ip_end_point_local)); 53768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (pp_result != PP_OK) 53868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 53968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 54068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PP_NetAddress_Private local_addr = 54168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) NetAddressPrivateImpl::kInvalidNetAddress; 54268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 54368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ip_end_point_local.address(), 54468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ip_end_point_local.port(), 54568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &local_addr)) { 54668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pp_result = PP_ERROR_ADDRESS_INVALID; 54768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) break; 54868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 54968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 55068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendBindReply(context, PP_OK, local_addr); 55168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.DoTransition(TCPSocketState::BIND, true); 55268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 55368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } while (false); 55468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (socket_->IsValid()) 55568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) socket_->Close(); 55668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendBindError(context, pp_result); 55768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.DoTransition(TCPSocketState::BIND, false); 558424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 559424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 560424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::DoConnect( 561424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 562424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& host, 563424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) uint16_t port, 564424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ResourceContext* resource_context) { 565effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 566424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 56768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::CONNECT)) { 568424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendConnectError(context, PP_ERROR_FAILED); 569424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 570424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 571424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 57268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.SetPendingTransition(TCPSocketState::CONNECT); 5731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) address_index_ = 0; 5741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) address_list_.clear(); 575424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port)); 576a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch resolver_.reset( 577a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch new net::SingleRequestHostResolver(resource_context->GetHostResolver())); 578424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int net_result = resolver_->Resolve( 579424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) request_info, 580424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::DEFAULT_PRIORITY, 581424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) &address_list_, 582424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::Bind(&PepperTCPSocketMessageFilter::OnResolveCompleted, 583a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Unretained(this), 584a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context), 585424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::BoundNetLog()); 586424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (net_result != net::ERR_IO_PENDING) 587424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OnResolveCompleted(context, net_result); 588424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 589424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 590424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::DoConnectWithNetAddress( 591424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 592424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PP_NetAddress_Private& net_addr) { 593effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 594424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 59568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::CONNECT)) { 596424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendConnectError(context, PP_ERROR_FAILED); 597424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 598424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 599424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 60068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.SetPendingTransition(TCPSocketState::CONNECT); 60168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 602424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::IPAddressNumber address; 603424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int port; 604a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!NetAddressPrivateImpl::NetAddressToIPEndPoint( 605a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch net_addr, &address, &port)) { 60668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(false); 607424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendConnectError(context, PP_ERROR_ADDRESS_INVALID); 608424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 609424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 610424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 611424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Copy the single IPEndPoint to address_list_. 6121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) address_index_ = 0; 613424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) address_list_.clear(); 614424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) address_list_.push_back(net::IPEndPoint(address, port)); 615424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) StartConnect(context); 616424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 617424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 618424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::DoWrite( 619424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context) { 620effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 621424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(write_buffer_base_.get()); 622424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(write_buffer_.get()); 623424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK_GT(write_buffer_->BytesRemaining(), 0); 62468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(state_.IsConnected()); 62568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 62668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int net_result = net::ERR_FAILED; 62768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (socket_) { 62868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_EQ(state_.state(), TCPSocketState::CONNECTED); 62968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net_result = socket_->Write( 63068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) write_buffer_.get(), 63168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) write_buffer_->BytesRemaining(), 63268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&PepperTCPSocketMessageFilter::OnWriteCompleted, 633a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Unretained(this), 634a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context)); 63568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else if (ssl_socket_) { 63668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK_EQ(state_.state(), TCPSocketState::SSL_CONNECTED); 63768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net_result = ssl_socket_->Write( 63868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) write_buffer_.get(), 63968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) write_buffer_->BytesRemaining(), 64068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&PepperTCPSocketMessageFilter::OnWriteCompleted, 641a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Unretained(this), 642a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context)); 64368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 644424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (net_result != net::ERR_IO_PENDING) 645424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OnWriteCompleted(context, net_result); 646424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 647424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 64868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void PepperTCPSocketMessageFilter::DoListen( 64968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 65068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int32_t backlog) { 651effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 65268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 65368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (state_.IsPending(TCPSocketState::LISTEN)) { 65468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendListenReply(context, PP_ERROR_INPROGRESS); 65568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 65668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 65768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsValidTransition(TCPSocketState::LISTEN)) { 65868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendListenReply(context, PP_ERROR_FAILED); 65968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 66068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 66168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 66268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int32_t pp_result = NetErrorToPepperError(socket_->Listen(backlog)); 66368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendListenReply(context, pp_result); 66468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.DoTransition(TCPSocketState::LISTEN, pp_result == PP_OK); 66568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 66668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 667424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::OnResolveCompleted( 668424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 669424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int net_result) { 670effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 671424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 67268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsPending(TCPSocketState::CONNECT)) { 67368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(state_.state() == TCPSocketState::CLOSED); 674424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendConnectError(context, PP_ERROR_FAILED); 675424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 676424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 677424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 678424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (net_result != net::OK) { 679424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendConnectError(context, NetErrorToPepperError(net_result)); 68068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(false); 681424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 682424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 683424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 684424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) StartConnect(context); 685424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 686424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 687424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::StartConnect( 688424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context) { 689effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 69068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(state_.IsPending(TCPSocketState::CONNECT)); 6911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_LT(address_index_, address_list_.size()); 692424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 69368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int net_result = net::OK; 69468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!socket_->IsValid()) 6951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) net_result = socket_->Open(address_list_[address_index_].GetFamily()); 696424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 69768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (net_result == net::OK) { 69868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net_result = socket_->Connect( 6991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) address_list_[address_index_], 70068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&PepperTCPSocketMessageFilter::OnConnectCompleted, 701a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Unretained(this), 702a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context)); 70368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 704424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (net_result != net::ERR_IO_PENDING) 705424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) OnConnectCompleted(context, net_result); 706424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 707424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 708424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::OnConnectCompleted( 709424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 710424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int net_result) { 711effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 712424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 71368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsPending(TCPSocketState::CONNECT)) { 71468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(state_.state() == TCPSocketState::CLOSED); 715424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendConnectError(context, PP_ERROR_FAILED); 716424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 717424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 718424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 719424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t pp_result = NetErrorToPepperError(net_result); 720424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) do { 721424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (pp_result != PP_OK) 722424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 723424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 724424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::IPEndPoint ip_end_point_local; 725424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::IPEndPoint ip_end_point_remote; 726a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp_result = 727a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch NetErrorToPepperError(socket_->GetLocalAddress(&ip_end_point_local)); 728424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (pp_result != PP_OK) 729424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 730a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp_result = 731a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch NetErrorToPepperError(socket_->GetPeerAddress(&ip_end_point_remote)); 732424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (pp_result != PP_OK) 733424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 734424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 735424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PP_NetAddress_Private local_addr = 736424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NetAddressPrivateImpl::kInvalidNetAddress; 737424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PP_NetAddress_Private remote_addr = 738424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NetAddressPrivateImpl::kInvalidNetAddress; 739424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 740424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ip_end_point_local.address(), 741424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ip_end_point_local.port(), 742424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) &local_addr) || 743424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) !NetAddressPrivateImpl::IPEndPointToNetAddress( 744424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ip_end_point_remote.address(), 745424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ip_end_point_remote.port(), 746424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) &remote_addr)) { 747424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pp_result = PP_ERROR_ADDRESS_INVALID; 748424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 749424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 750424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 75168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) socket_->SetDefaultOptionsForClient(); 752424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendConnectReply(context, PP_OK, local_addr, remote_addr); 75368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(true); 754424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 755424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } while (false); 756424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 75768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (version_ == ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) { 7581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_EQ(1u, address_list_.size()); 7591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 7601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SendConnectError(context, pp_result); 76168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(false); 76268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 76368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // We have to recreate |socket_| because it doesn't allow a second connect 76468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // attempt. We won't lose any state such as bound address or set options, 76568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // because in the private or v1.0 API, connect must be the first operation. 76668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) socket_.reset(new net::TCPSocket(NULL, net::NetLog::Source())); 7671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 7681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (address_index_ + 1 < address_list_.size()) { 7691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK_EQ(version_, ppapi::TCP_SOCKET_VERSION_PRIVATE); 7701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) address_index_++; 7711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) StartConnect(context); 7721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } else { 7731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) SendConnectError(context, pp_result); 7741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // In order to maintain backward compatibility, allow further attempts to 7751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // connect the socket. 7761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) state_ = TCPSocketState(TCPSocketState::INITIAL); 7771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 77868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 779424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 780424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 781424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted( 782424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 783424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int net_result) { 784effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 785424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 78668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!state_.IsPending(TCPSocketState::SSL_CONNECT)) { 78768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(state_.state() == TCPSocketState::CLOSED); 788424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendSSLHandshakeReply(context, PP_ERROR_FAILED); 789424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 790424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 79168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 792424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendSSLHandshakeReply(context, NetErrorToPepperError(net_result)); 79368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) state_.CompletePendingTransition(net_result == net::OK); 794424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 795424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 796424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::OnReadCompleted( 797424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 798424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int net_result) { 799effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 800424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(read_buffer_.get()); 801424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 802424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (net_result > 0) { 803a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch SendReadReply( 804a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch context, PP_OK, std::string(read_buffer_->data(), net_result)); 805424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else if (net_result == 0) { 806424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) end_of_file_reached_ = true; 807424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendReadReply(context, PP_OK, std::string()); 808424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 809424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendReadError(context, NetErrorToPepperError(net_result)); 810424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 811424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) read_buffer_ = NULL; 812424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 813424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 814424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::OnWriteCompleted( 815424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 816424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int net_result) { 817effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 818424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(write_buffer_base_.get()); 819424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(write_buffer_.get()); 820424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 821424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Note: For partial writes of 0 bytes, don't continue writing to avoid a 822424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // likely infinite loop. 823424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (net_result > 0) { 824424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) write_buffer_->DidConsume(net_result); 82568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (write_buffer_->BytesRemaining() > 0 && state_.IsConnected()) { 826424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DoWrite(context); 827424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 828424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 829424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 830424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 831424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (net_result >= 0) 832424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendWriteReply(context, write_buffer_->BytesConsumed()); 833424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else 834424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendWriteReply(context, NetErrorToPepperError(net_result)); 835424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 836424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) write_buffer_ = NULL; 837424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) write_buffer_base_ = NULL; 838424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 839424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 84068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void PepperTCPSocketMessageFilter::OnAcceptCompleted( 84168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 84268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int net_result) { 843effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::IO); 84468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(pending_accept_); 84568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 84668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending_accept_ = false; 84768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 84868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (net_result != net::OK) { 84968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendAcceptError(context, NetErrorToPepperError(net_result)); 85068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 85168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 85268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 85368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(accepted_socket_.get()); 85468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 85568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::IPEndPoint ip_end_point_local; 85668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PP_NetAddress_Private local_addr = NetAddressPrivateImpl::kInvalidNetAddress; 85768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) PP_NetAddress_Private remote_addr = NetAddressPrivateImpl::kInvalidNetAddress; 85868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 859a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch int32_t pp_result = NetErrorToPepperError( 860a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch accepted_socket_->GetLocalAddress(&ip_end_point_local)); 86168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (pp_result != PP_OK) { 86268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendAcceptError(context, pp_result); 86368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 86468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 86568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 86668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ip_end_point_local.address(), 86768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ip_end_point_local.port(), 86868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &local_addr) || 86968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !NetAddressPrivateImpl::IPEndPointToNetAddress( 87068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accepted_address_.address(), 87168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) accepted_address_.port(), 87268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &remote_addr)) { 87368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendAcceptError(context, PP_ERROR_ADDRESS_INVALID); 87468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 87568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 87668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 87768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // |factory_| is guaranteed to be non-NULL here. Only those instances created 87868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // in CONNECTED state have a NULL |factory_|, while getting here requires 87968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // LISTENING state. 88068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_ptr<ppapi::host::ResourceHost> host = 88168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) factory_->CreateAcceptedTCPSocket( 88268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) instance_, version_, accepted_socket_.Pass()); 88368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!host) { 88468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendAcceptError(context, PP_ERROR_NOSPACE); 88568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 88668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 88768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int pending_host_id = ppapi_host_->AddPendingResourceHost(host.Pass()); 88868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (pending_host_id) 88968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendAcceptReply(context, PP_OK, pending_host_id, local_addr, remote_addr); 89068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else 89168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendAcceptError(context, PP_ERROR_NOSPACE); 89268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 89368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 89468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void PepperTCPSocketMessageFilter::SendBindReply( 89568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 89668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int32_t pp_result, 89768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const PP_NetAddress_Private& local_addr) { 89868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context(context); 89968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) reply_context.params.set_result(pp_result); 90068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendReply(reply_context, PpapiPluginMsg_TCPSocket_BindReply(local_addr)); 90168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 90268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 90368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void PepperTCPSocketMessageFilter::SendBindError( 90468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 90568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int32_t pp_error) { 90668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) SendBindReply(context, pp_error, NetAddressPrivateImpl::kInvalidNetAddress); 90768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 90868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 909424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::SendConnectReply( 910424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 911424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t pp_result, 912424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PP_NetAddress_Private& local_addr, 913424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const PP_NetAddress_Private& remote_addr) { 914424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context(context); 915424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) reply_context.params.set_result(pp_result); 916424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendReply(reply_context, 917424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiPluginMsg_TCPSocket_ConnectReply(local_addr, remote_addr)); 918424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 919424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 920424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::SendConnectError( 921424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 922424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t pp_error) { 923424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendConnectReply(context, 924424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pp_error, 925424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NetAddressPrivateImpl::kInvalidNetAddress, 926424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) NetAddressPrivateImpl::kInvalidNetAddress); 927424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 928424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 929424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::SendSSLHandshakeReply( 930424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 931424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t pp_result) { 932424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context(context); 933424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) reply_context.params.set_result(pp_result); 934424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ppapi::PPB_X509Certificate_Fields certificate_fields; 935424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (pp_result == PP_OK) { 936424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Our socket is guaranteed to be an SSL socket if we get here. 937424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) net::SSLInfo ssl_info; 93868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ssl_socket_->GetSSLInfo(&ssl_info); 939424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ssl_info.cert.get()) { 940424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pepper_socket_utils::GetCertificateFields(*ssl_info.cert.get(), 941424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) &certificate_fields); 942424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 943424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 944424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SendReply(reply_context, 945424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) PpapiPluginMsg_TCPSocket_SSLHandshakeReply(certificate_fields)); 946424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 947424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 948424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)void PepperTCPSocketMessageFilter::SendReadReply( 949424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const ppapi::host::ReplyMessageContext& context, 950424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int32_t pp_result, 951424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::string& data) { 952424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ppapi::host::ReplyMessageContext reply_context(context); 953