1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h" 6 7#include <cstring> 8 9#include "base/bind.h" 10#include "base/logging.h" 11#include "build/build_config.h" 12#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" 13#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" 14#include "content/browser/renderer_host/pepper/pepper_socket_utils.h" 15#include "content/public/browser/browser_context.h" 16#include "content/public/browser/browser_thread.h" 17#include "content/public/browser/render_process_host.h" 18#include "content/public/browser/resource_context.h" 19#include "content/public/common/socket_permission_request.h" 20#include "net/base/address_family.h" 21#include "net/base/host_port_pair.h" 22#include "net/base/io_buffer.h" 23#include "net/base/net_errors.h" 24#include "net/dns/single_request_host_resolver.h" 25#include "net/socket/client_socket_factory.h" 26#include "net/socket/client_socket_handle.h" 27#include "net/socket/ssl_client_socket.h" 28#include "net/socket/tcp_client_socket.h" 29#include "ppapi/host/dispatch_host_message.h" 30#include "ppapi/host/error_conversion.h" 31#include "ppapi/host/ppapi_host.h" 32#include "ppapi/host/resource_host.h" 33#include "ppapi/proxy/ppapi_messages.h" 34#include "ppapi/proxy/tcp_socket_resource_base.h" 35#include "ppapi/shared_impl/private/net_address_private_impl.h" 36 37using ppapi::NetAddressPrivateImpl; 38using ppapi::host::NetErrorToPepperError; 39using ppapi::proxy::TCPSocketResourceBase; 40using ppapi::TCPSocketState; 41using ppapi::TCPSocketVersion; 42 43namespace { 44 45size_t g_num_instances = 0; 46 47} // namespace 48 49namespace content { 50 51PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter( 52 ContentBrowserPepperHostFactory* factory, 53 BrowserPpapiHostImpl* host, 54 PP_Instance instance, 55 TCPSocketVersion version) 56 : version_(version), 57 external_plugin_(host->external_plugin()), 58 render_process_id_(0), 59 render_frame_id_(0), 60 ppapi_host_(host->GetPpapiHost()), 61 factory_(factory), 62 instance_(instance), 63 state_(TCPSocketState::INITIAL), 64 end_of_file_reached_(false), 65 bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), 66 address_index_(0), 67 socket_(new net::TCPSocket(NULL, net::NetLog::Source())), 68 ssl_context_helper_(host->ssl_context_helper()), 69 pending_accept_(false) { 70 DCHECK(host); 71 ++g_num_instances; 72 if (!host->GetRenderFrameIDsForInstance( 73 instance, &render_process_id_, &render_frame_id_)) { 74 NOTREACHED(); 75 } 76} 77 78PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter( 79 BrowserPpapiHostImpl* host, 80 PP_Instance instance, 81 TCPSocketVersion version, 82 scoped_ptr<net::TCPSocket> socket) 83 : version_(version), 84 external_plugin_(host->external_plugin()), 85 render_process_id_(0), 86 render_frame_id_(0), 87 ppapi_host_(host->GetPpapiHost()), 88 factory_(NULL), 89 instance_(instance), 90 state_(TCPSocketState::CONNECTED), 91 end_of_file_reached_(false), 92 bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), 93 address_index_(0), 94 socket_(socket.Pass()), 95 ssl_context_helper_(host->ssl_context_helper()), 96 pending_accept_(false) { 97 DCHECK(host); 98 DCHECK_NE(version, ppapi::TCP_SOCKET_VERSION_1_0); 99 100 ++g_num_instances; 101 if (!host->GetRenderFrameIDsForInstance( 102 instance, &render_process_id_, &render_frame_id_)) { 103 NOTREACHED(); 104 } 105} 106 107PepperTCPSocketMessageFilter::~PepperTCPSocketMessageFilter() { 108 if (socket_) 109 socket_->Close(); 110 if (ssl_socket_) 111 ssl_socket_->Disconnect(); 112 --g_num_instances; 113} 114 115// static 116size_t PepperTCPSocketMessageFilter::GetNumInstances() { 117 return g_num_instances; 118} 119 120scoped_refptr<base::TaskRunner> 121PepperTCPSocketMessageFilter::OverrideTaskRunnerForMessage( 122 const IPC::Message& message) { 123 switch (message.type()) { 124 case PpapiHostMsg_TCPSocket_Bind::ID: 125 case PpapiHostMsg_TCPSocket_Connect::ID: 126 case PpapiHostMsg_TCPSocket_ConnectWithNetAddress::ID: 127 case PpapiHostMsg_TCPSocket_Listen::ID: 128 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); 129 case PpapiHostMsg_TCPSocket_SSLHandshake::ID: 130 case PpapiHostMsg_TCPSocket_Read::ID: 131 case PpapiHostMsg_TCPSocket_Write::ID: 132 case PpapiHostMsg_TCPSocket_Accept::ID: 133 case PpapiHostMsg_TCPSocket_Close::ID: 134 case PpapiHostMsg_TCPSocket_SetOption::ID: 135 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 136 } 137 return NULL; 138} 139 140int32_t PepperTCPSocketMessageFilter::OnResourceMessageReceived( 141 const IPC::Message& msg, 142 ppapi::host::HostMessageContext* context) { 143 PPAPI_BEGIN_MESSAGE_MAP(PepperTCPSocketMessageFilter, msg) 144 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Bind, OnMsgBind) 145 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Connect, 146 OnMsgConnect) 147 PPAPI_DISPATCH_HOST_RESOURCE_CALL( 148 PpapiHostMsg_TCPSocket_ConnectWithNetAddress, 149 OnMsgConnectWithNetAddress) 150 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_SSLHandshake, 151 OnMsgSSLHandshake) 152 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Read, OnMsgRead) 153 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Write, OnMsgWrite) 154 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_Listen, 155 OnMsgListen) 156 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TCPSocket_Accept, 157 OnMsgAccept) 158 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_TCPSocket_Close, 159 OnMsgClose) 160 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_TCPSocket_SetOption, 161 OnMsgSetOption) 162 PPAPI_END_MESSAGE_MAP() 163 return PP_ERROR_FAILED; 164} 165 166int32_t PepperTCPSocketMessageFilter::OnMsgBind( 167 const ppapi::host::HostMessageContext* context, 168 const PP_NetAddress_Private& net_addr) { 169 DCHECK_CURRENTLY_ON(BrowserThread::UI); 170 171 // This is only supported by PPB_TCPSocket v1.1 or above. 172 if (version_ != ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) { 173 NOTREACHED(); 174 return PP_ERROR_NOACCESS; 175 } 176 177 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, 178 false /* private_api */, 179 NULL, 180 render_process_id_, 181 render_frame_id_)) { 182 return PP_ERROR_NOACCESS; 183 } 184 185 bind_input_addr_ = net_addr; 186 187 BrowserThread::PostTask(BrowserThread::IO, 188 FROM_HERE, 189 base::Bind(&PepperTCPSocketMessageFilter::DoBind, 190 this, 191 context->MakeReplyMessageContext(), 192 net_addr)); 193 return PP_OK_COMPLETIONPENDING; 194} 195 196int32_t PepperTCPSocketMessageFilter::OnMsgConnect( 197 const ppapi::host::HostMessageContext* context, 198 const std::string& host, 199 uint16_t port) { 200 DCHECK_CURRENTLY_ON(BrowserThread::UI); 201 202 // This is only supported by PPB_TCPSocket_Private. 203 if (!IsPrivateAPI()) { 204 NOTREACHED(); 205 return PP_ERROR_NOACCESS; 206 } 207 208 SocketPermissionRequest request( 209 SocketPermissionRequest::TCP_CONNECT, host, port); 210 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, 211 true /* private_api */, 212 &request, 213 render_process_id_, 214 render_frame_id_)) { 215 return PP_ERROR_NOACCESS; 216 } 217 218 RenderProcessHost* render_process_host = 219 RenderProcessHost::FromID(render_process_id_); 220 if (!render_process_host) 221 return PP_ERROR_FAILED; 222 BrowserContext* browser_context = render_process_host->GetBrowserContext(); 223 if (!browser_context || !browser_context->GetResourceContext()) 224 return PP_ERROR_FAILED; 225 226 BrowserThread::PostTask(BrowserThread::IO, 227 FROM_HERE, 228 base::Bind(&PepperTCPSocketMessageFilter::DoConnect, 229 this, 230 context->MakeReplyMessageContext(), 231 host, 232 port, 233 browser_context->GetResourceContext())); 234 return PP_OK_COMPLETIONPENDING; 235} 236 237int32_t PepperTCPSocketMessageFilter::OnMsgConnectWithNetAddress( 238 const ppapi::host::HostMessageContext* context, 239 const PP_NetAddress_Private& net_addr) { 240 DCHECK_CURRENTLY_ON(BrowserThread::UI); 241 242 content::SocketPermissionRequest request = 243 pepper_socket_utils::CreateSocketPermissionRequest( 244 content::SocketPermissionRequest::TCP_CONNECT, net_addr); 245 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, 246 IsPrivateAPI(), 247 &request, 248 render_process_id_, 249 render_frame_id_)) { 250 return PP_ERROR_NOACCESS; 251 } 252 253 BrowserThread::PostTask( 254 BrowserThread::IO, 255 FROM_HERE, 256 base::Bind(&PepperTCPSocketMessageFilter::DoConnectWithNetAddress, 257 this, 258 context->MakeReplyMessageContext(), 259 net_addr)); 260 return PP_OK_COMPLETIONPENDING; 261} 262 263int32_t PepperTCPSocketMessageFilter::OnMsgSSLHandshake( 264 const ppapi::host::HostMessageContext* context, 265 const std::string& server_name, 266 uint16_t server_port, 267 const std::vector<std::vector<char> >& trusted_certs, 268 const std::vector<std::vector<char> >& untrusted_certs) { 269 DCHECK_CURRENTLY_ON(BrowserThread::IO); 270 271 // Allow to do SSL handshake only if currently the socket has been connected 272 // and there isn't pending read or write. 273 if (!state_.IsValidTransition(TCPSocketState::SSL_CONNECT) || 274 read_buffer_.get() || write_buffer_base_.get() || write_buffer_.get()) { 275 return PP_ERROR_FAILED; 276 } 277 278 // TODO(raymes,rsleevi): Use trusted/untrusted certificates when connecting. 279 net::IPEndPoint peer_address; 280 if (socket_->GetPeerAddress(&peer_address) != net::OK) 281 return PP_ERROR_FAILED; 282 283 scoped_ptr<net::ClientSocketHandle> handle(new net::ClientSocketHandle()); 284 handle->SetSocket(make_scoped_ptr<net::StreamSocket>( 285 new net::TCPClientSocket(socket_.Pass(), peer_address))); 286 net::ClientSocketFactory* factory = 287 net::ClientSocketFactory::GetDefaultFactory(); 288 net::HostPortPair host_port_pair(server_name, server_port); 289 net::SSLClientSocketContext ssl_context; 290 ssl_context.cert_verifier = ssl_context_helper_->GetCertVerifier(); 291 ssl_context.transport_security_state = 292 ssl_context_helper_->GetTransportSecurityState(); 293 ssl_socket_ = 294 factory->CreateSSLClientSocket(handle.Pass(), 295 host_port_pair, 296 ssl_context_helper_->ssl_config(), 297 ssl_context); 298 if (!ssl_socket_) { 299 LOG(WARNING) << "Failed to create an SSL client socket."; 300 state_.CompletePendingTransition(false); 301 return PP_ERROR_FAILED; 302 } 303 304 state_.SetPendingTransition(TCPSocketState::SSL_CONNECT); 305 306 const ppapi::host::ReplyMessageContext reply_context( 307 context->MakeReplyMessageContext()); 308 int net_result = ssl_socket_->Connect( 309 base::Bind(&PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted, 310 base::Unretained(this), 311 reply_context)); 312 if (net_result != net::ERR_IO_PENDING) 313 OnSSLHandshakeCompleted(reply_context, net_result); 314 return PP_OK_COMPLETIONPENDING; 315} 316 317int32_t PepperTCPSocketMessageFilter::OnMsgRead( 318 const ppapi::host::HostMessageContext* context, 319 int32_t bytes_to_read) { 320 DCHECK_CURRENTLY_ON(BrowserThread::IO); 321 if (!state_.IsConnected() || end_of_file_reached_) 322 return PP_ERROR_FAILED; 323 if (read_buffer_.get()) 324 return PP_ERROR_INPROGRESS; 325 if (bytes_to_read <= 0 || 326 bytes_to_read > TCPSocketResourceBase::kMaxReadSize) { 327 return PP_ERROR_BADARGUMENT; 328 } 329 330 ppapi::host::ReplyMessageContext reply_context( 331 context->MakeReplyMessageContext()); 332 read_buffer_ = new net::IOBuffer(bytes_to_read); 333 334 int net_result = net::ERR_FAILED; 335 if (socket_) { 336 DCHECK_EQ(state_.state(), TCPSocketState::CONNECTED); 337 net_result = 338 socket_->Read(read_buffer_.get(), 339 bytes_to_read, 340 base::Bind(&PepperTCPSocketMessageFilter::OnReadCompleted, 341 base::Unretained(this), 342 reply_context)); 343 } else if (ssl_socket_) { 344 DCHECK_EQ(state_.state(), TCPSocketState::SSL_CONNECTED); 345 net_result = ssl_socket_->Read( 346 read_buffer_.get(), 347 bytes_to_read, 348 base::Bind(&PepperTCPSocketMessageFilter::OnReadCompleted, 349 base::Unretained(this), 350 reply_context)); 351 } 352 if (net_result != net::ERR_IO_PENDING) 353 OnReadCompleted(reply_context, net_result); 354 return PP_OK_COMPLETIONPENDING; 355} 356 357int32_t PepperTCPSocketMessageFilter::OnMsgWrite( 358 const ppapi::host::HostMessageContext* context, 359 const std::string& data) { 360 DCHECK_CURRENTLY_ON(BrowserThread::IO); 361 362 if (!state_.IsConnected()) 363 return PP_ERROR_FAILED; 364 if (write_buffer_base_.get() || write_buffer_.get()) 365 return PP_ERROR_INPROGRESS; 366 367 size_t data_size = data.size(); 368 if (data_size == 0 || 369 data_size > static_cast<size_t>(TCPSocketResourceBase::kMaxWriteSize)) { 370 return PP_ERROR_BADARGUMENT; 371 } 372 373 write_buffer_base_ = new net::IOBuffer(data_size); 374 memcpy(write_buffer_base_->data(), data.data(), data_size); 375 write_buffer_ = 376 new net::DrainableIOBuffer(write_buffer_base_.get(), data_size); 377 DoWrite(context->MakeReplyMessageContext()); 378 return PP_OK_COMPLETIONPENDING; 379} 380 381int32_t PepperTCPSocketMessageFilter::OnMsgListen( 382 const ppapi::host::HostMessageContext* context, 383 int32_t backlog) { 384 DCHECK_CURRENTLY_ON(BrowserThread::UI); 385 386 // This is only supported by PPB_TCPSocket v1.1 or above. 387 if (version_ != ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) { 388 NOTREACHED(); 389 return PP_ERROR_NOACCESS; 390 } 391 392 content::SocketPermissionRequest request = 393 pepper_socket_utils::CreateSocketPermissionRequest( 394 content::SocketPermissionRequest::TCP_LISTEN, bind_input_addr_); 395 if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, 396 false /* private_api */, 397 &request, 398 render_process_id_, 399 render_frame_id_)) { 400 return PP_ERROR_NOACCESS; 401 } 402 403 BrowserThread::PostTask(BrowserThread::IO, 404 FROM_HERE, 405 base::Bind(&PepperTCPSocketMessageFilter::DoListen, 406 this, 407 context->MakeReplyMessageContext(), 408 backlog)); 409 return PP_OK_COMPLETIONPENDING; 410} 411 412int32_t PepperTCPSocketMessageFilter::OnMsgAccept( 413 const ppapi::host::HostMessageContext* context) { 414 DCHECK_CURRENTLY_ON(BrowserThread::IO); 415 416 if (pending_accept_) 417 return PP_ERROR_INPROGRESS; 418 if (state_.state() != TCPSocketState::LISTENING) 419 return PP_ERROR_FAILED; 420 421 pending_accept_ = true; 422 ppapi::host::ReplyMessageContext reply_context( 423 context->MakeReplyMessageContext()); 424 int net_result = socket_->Accept( 425 &accepted_socket_, 426 &accepted_address_, 427 base::Bind(&PepperTCPSocketMessageFilter::OnAcceptCompleted, 428 base::Unretained(this), 429 reply_context)); 430 if (net_result != net::ERR_IO_PENDING) 431 OnAcceptCompleted(reply_context, net_result); 432 return PP_OK_COMPLETIONPENDING; 433} 434 435int32_t PepperTCPSocketMessageFilter::OnMsgClose( 436 const ppapi::host::HostMessageContext* context) { 437 DCHECK_CURRENTLY_ON(BrowserThread::IO); 438 if (state_.state() == TCPSocketState::CLOSED) 439 return PP_OK; 440 441 state_.DoTransition(TCPSocketState::CLOSE, true); 442 // Make sure we get no further callbacks from |socket_| or |ssl_socket_|. 443 if (socket_) { 444 socket_->Close(); 445 } else if (ssl_socket_) { 446 ssl_socket_->Disconnect(); 447 } 448 return PP_OK; 449} 450 451int32_t PepperTCPSocketMessageFilter::OnMsgSetOption( 452 const ppapi::host::HostMessageContext* context, 453 PP_TCPSocket_Option name, 454 const ppapi::SocketOptionData& value) { 455 DCHECK_CURRENTLY_ON(BrowserThread::IO); 456 457 switch (name) { 458 case PP_TCPSOCKET_OPTION_NO_DELAY: { 459 if (state_.state() != TCPSocketState::CONNECTED) 460 return PP_ERROR_FAILED; 461 462 bool boolean_value = false; 463 if (!value.GetBool(&boolean_value)) 464 return PP_ERROR_BADARGUMENT; 465 return socket_->SetNoDelay(boolean_value) ? PP_OK : PP_ERROR_FAILED; 466 } 467 case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: 468 case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { 469 if (state_.state() != TCPSocketState::CONNECTED) 470 return PP_ERROR_FAILED; 471 472 int32_t integer_value = 0; 473 if (!value.GetInt32(&integer_value) || integer_value <= 0) 474 return PP_ERROR_BADARGUMENT; 475 476 int net_result = net::ERR_UNEXPECTED; 477 if (name == PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE) { 478 if (integer_value > TCPSocketResourceBase::kMaxSendBufferSize) 479 return PP_ERROR_BADARGUMENT; 480 net_result = socket_->SetSendBufferSize(integer_value); 481 } else { 482 if (integer_value > TCPSocketResourceBase::kMaxReceiveBufferSize) 483 return PP_ERROR_BADARGUMENT; 484 net_result = socket_->SetReceiveBufferSize(integer_value); 485 } 486 // TODO(wtc): Add error mapping code. 487 return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED; 488 } 489 default: { 490 NOTREACHED(); 491 return PP_ERROR_BADARGUMENT; 492 } 493 } 494} 495 496void PepperTCPSocketMessageFilter::DoBind( 497 const ppapi::host::ReplyMessageContext& context, 498 const PP_NetAddress_Private& net_addr) { 499 DCHECK_CURRENTLY_ON(BrowserThread::IO); 500 501 if (state_.IsPending(TCPSocketState::BIND)) { 502 SendBindError(context, PP_ERROR_INPROGRESS); 503 return; 504 } 505 if (!state_.IsValidTransition(TCPSocketState::BIND)) { 506 SendBindError(context, PP_ERROR_FAILED); 507 return; 508 } 509 510 int pp_result = PP_OK; 511 do { 512 net::IPAddressNumber address; 513 int port; 514 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint( 515 net_addr, &address, &port)) { 516 pp_result = PP_ERROR_ADDRESS_INVALID; 517 break; 518 } 519 net::IPEndPoint bind_addr(address, port); 520 521 DCHECK(!socket_->IsValid()); 522 pp_result = NetErrorToPepperError(socket_->Open(bind_addr.GetFamily())); 523 if (pp_result != PP_OK) 524 break; 525 526 pp_result = NetErrorToPepperError(socket_->SetDefaultOptionsForServer()); 527 if (pp_result != PP_OK) 528 break; 529 530 pp_result = NetErrorToPepperError(socket_->Bind(bind_addr)); 531 if (pp_result != PP_OK) 532 break; 533 534 net::IPEndPoint ip_end_point_local; 535 pp_result = 536 NetErrorToPepperError(socket_->GetLocalAddress(&ip_end_point_local)); 537 if (pp_result != PP_OK) 538 break; 539 540 PP_NetAddress_Private local_addr = 541 NetAddressPrivateImpl::kInvalidNetAddress; 542 if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 543 ip_end_point_local.address(), 544 ip_end_point_local.port(), 545 &local_addr)) { 546 pp_result = PP_ERROR_ADDRESS_INVALID; 547 break; 548 } 549 550 SendBindReply(context, PP_OK, local_addr); 551 state_.DoTransition(TCPSocketState::BIND, true); 552 return; 553 } while (false); 554 if (socket_->IsValid()) 555 socket_->Close(); 556 SendBindError(context, pp_result); 557 state_.DoTransition(TCPSocketState::BIND, false); 558} 559 560void PepperTCPSocketMessageFilter::DoConnect( 561 const ppapi::host::ReplyMessageContext& context, 562 const std::string& host, 563 uint16_t port, 564 ResourceContext* resource_context) { 565 DCHECK_CURRENTLY_ON(BrowserThread::IO); 566 567 if (!state_.IsValidTransition(TCPSocketState::CONNECT)) { 568 SendConnectError(context, PP_ERROR_FAILED); 569 return; 570 } 571 572 state_.SetPendingTransition(TCPSocketState::CONNECT); 573 address_index_ = 0; 574 address_list_.clear(); 575 net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port)); 576 resolver_.reset( 577 new net::SingleRequestHostResolver(resource_context->GetHostResolver())); 578 int net_result = resolver_->Resolve( 579 request_info, 580 net::DEFAULT_PRIORITY, 581 &address_list_, 582 base::Bind(&PepperTCPSocketMessageFilter::OnResolveCompleted, 583 base::Unretained(this), 584 context), 585 net::BoundNetLog()); 586 if (net_result != net::ERR_IO_PENDING) 587 OnResolveCompleted(context, net_result); 588} 589 590void PepperTCPSocketMessageFilter::DoConnectWithNetAddress( 591 const ppapi::host::ReplyMessageContext& context, 592 const PP_NetAddress_Private& net_addr) { 593 DCHECK_CURRENTLY_ON(BrowserThread::IO); 594 595 if (!state_.IsValidTransition(TCPSocketState::CONNECT)) { 596 SendConnectError(context, PP_ERROR_FAILED); 597 return; 598 } 599 600 state_.SetPendingTransition(TCPSocketState::CONNECT); 601 602 net::IPAddressNumber address; 603 int port; 604 if (!NetAddressPrivateImpl::NetAddressToIPEndPoint( 605 net_addr, &address, &port)) { 606 state_.CompletePendingTransition(false); 607 SendConnectError(context, PP_ERROR_ADDRESS_INVALID); 608 return; 609 } 610 611 // Copy the single IPEndPoint to address_list_. 612 address_index_ = 0; 613 address_list_.clear(); 614 address_list_.push_back(net::IPEndPoint(address, port)); 615 StartConnect(context); 616} 617 618void PepperTCPSocketMessageFilter::DoWrite( 619 const ppapi::host::ReplyMessageContext& context) { 620 DCHECK_CURRENTLY_ON(BrowserThread::IO); 621 DCHECK(write_buffer_base_.get()); 622 DCHECK(write_buffer_.get()); 623 DCHECK_GT(write_buffer_->BytesRemaining(), 0); 624 DCHECK(state_.IsConnected()); 625 626 int net_result = net::ERR_FAILED; 627 if (socket_) { 628 DCHECK_EQ(state_.state(), TCPSocketState::CONNECTED); 629 net_result = socket_->Write( 630 write_buffer_.get(), 631 write_buffer_->BytesRemaining(), 632 base::Bind(&PepperTCPSocketMessageFilter::OnWriteCompleted, 633 base::Unretained(this), 634 context)); 635 } else if (ssl_socket_) { 636 DCHECK_EQ(state_.state(), TCPSocketState::SSL_CONNECTED); 637 net_result = ssl_socket_->Write( 638 write_buffer_.get(), 639 write_buffer_->BytesRemaining(), 640 base::Bind(&PepperTCPSocketMessageFilter::OnWriteCompleted, 641 base::Unretained(this), 642 context)); 643 } 644 if (net_result != net::ERR_IO_PENDING) 645 OnWriteCompleted(context, net_result); 646} 647 648void PepperTCPSocketMessageFilter::DoListen( 649 const ppapi::host::ReplyMessageContext& context, 650 int32_t backlog) { 651 DCHECK_CURRENTLY_ON(BrowserThread::IO); 652 653 if (state_.IsPending(TCPSocketState::LISTEN)) { 654 SendListenReply(context, PP_ERROR_INPROGRESS); 655 return; 656 } 657 if (!state_.IsValidTransition(TCPSocketState::LISTEN)) { 658 SendListenReply(context, PP_ERROR_FAILED); 659 return; 660 } 661 662 int32_t pp_result = NetErrorToPepperError(socket_->Listen(backlog)); 663 SendListenReply(context, pp_result); 664 state_.DoTransition(TCPSocketState::LISTEN, pp_result == PP_OK); 665} 666 667void PepperTCPSocketMessageFilter::OnResolveCompleted( 668 const ppapi::host::ReplyMessageContext& context, 669 int net_result) { 670 DCHECK_CURRENTLY_ON(BrowserThread::IO); 671 672 if (!state_.IsPending(TCPSocketState::CONNECT)) { 673 DCHECK(state_.state() == TCPSocketState::CLOSED); 674 SendConnectError(context, PP_ERROR_FAILED); 675 return; 676 } 677 678 if (net_result != net::OK) { 679 SendConnectError(context, NetErrorToPepperError(net_result)); 680 state_.CompletePendingTransition(false); 681 return; 682 } 683 684 StartConnect(context); 685} 686 687void PepperTCPSocketMessageFilter::StartConnect( 688 const ppapi::host::ReplyMessageContext& context) { 689 DCHECK_CURRENTLY_ON(BrowserThread::IO); 690 DCHECK(state_.IsPending(TCPSocketState::CONNECT)); 691 DCHECK_LT(address_index_, address_list_.size()); 692 693 int net_result = net::OK; 694 if (!socket_->IsValid()) 695 net_result = socket_->Open(address_list_[address_index_].GetFamily()); 696 697 if (net_result == net::OK) { 698 net_result = socket_->Connect( 699 address_list_[address_index_], 700 base::Bind(&PepperTCPSocketMessageFilter::OnConnectCompleted, 701 base::Unretained(this), 702 context)); 703 } 704 if (net_result != net::ERR_IO_PENDING) 705 OnConnectCompleted(context, net_result); 706} 707 708void PepperTCPSocketMessageFilter::OnConnectCompleted( 709 const ppapi::host::ReplyMessageContext& context, 710 int net_result) { 711 DCHECK_CURRENTLY_ON(BrowserThread::IO); 712 713 if (!state_.IsPending(TCPSocketState::CONNECT)) { 714 DCHECK(state_.state() == TCPSocketState::CLOSED); 715 SendConnectError(context, PP_ERROR_FAILED); 716 return; 717 } 718 719 int32_t pp_result = NetErrorToPepperError(net_result); 720 do { 721 if (pp_result != PP_OK) 722 break; 723 724 net::IPEndPoint ip_end_point_local; 725 net::IPEndPoint ip_end_point_remote; 726 pp_result = 727 NetErrorToPepperError(socket_->GetLocalAddress(&ip_end_point_local)); 728 if (pp_result != PP_OK) 729 break; 730 pp_result = 731 NetErrorToPepperError(socket_->GetPeerAddress(&ip_end_point_remote)); 732 if (pp_result != PP_OK) 733 break; 734 735 PP_NetAddress_Private local_addr = 736 NetAddressPrivateImpl::kInvalidNetAddress; 737 PP_NetAddress_Private remote_addr = 738 NetAddressPrivateImpl::kInvalidNetAddress; 739 if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 740 ip_end_point_local.address(), 741 ip_end_point_local.port(), 742 &local_addr) || 743 !NetAddressPrivateImpl::IPEndPointToNetAddress( 744 ip_end_point_remote.address(), 745 ip_end_point_remote.port(), 746 &remote_addr)) { 747 pp_result = PP_ERROR_ADDRESS_INVALID; 748 break; 749 } 750 751 socket_->SetDefaultOptionsForClient(); 752 SendConnectReply(context, PP_OK, local_addr, remote_addr); 753 state_.CompletePendingTransition(true); 754 return; 755 } while (false); 756 757 if (version_ == ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) { 758 DCHECK_EQ(1u, address_list_.size()); 759 760 SendConnectError(context, pp_result); 761 state_.CompletePendingTransition(false); 762 } else { 763 // We have to recreate |socket_| because it doesn't allow a second connect 764 // attempt. We won't lose any state such as bound address or set options, 765 // because in the private or v1.0 API, connect must be the first operation. 766 socket_.reset(new net::TCPSocket(NULL, net::NetLog::Source())); 767 768 if (address_index_ + 1 < address_list_.size()) { 769 DCHECK_EQ(version_, ppapi::TCP_SOCKET_VERSION_PRIVATE); 770 address_index_++; 771 StartConnect(context); 772 } else { 773 SendConnectError(context, pp_result); 774 // In order to maintain backward compatibility, allow further attempts to 775 // connect the socket. 776 state_ = TCPSocketState(TCPSocketState::INITIAL); 777 } 778 } 779} 780 781void PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted( 782 const ppapi::host::ReplyMessageContext& context, 783 int net_result) { 784 DCHECK_CURRENTLY_ON(BrowserThread::IO); 785 786 if (!state_.IsPending(TCPSocketState::SSL_CONNECT)) { 787 DCHECK(state_.state() == TCPSocketState::CLOSED); 788 SendSSLHandshakeReply(context, PP_ERROR_FAILED); 789 return; 790 } 791 792 SendSSLHandshakeReply(context, NetErrorToPepperError(net_result)); 793 state_.CompletePendingTransition(net_result == net::OK); 794} 795 796void PepperTCPSocketMessageFilter::OnReadCompleted( 797 const ppapi::host::ReplyMessageContext& context, 798 int net_result) { 799 DCHECK_CURRENTLY_ON(BrowserThread::IO); 800 DCHECK(read_buffer_.get()); 801 802 if (net_result > 0) { 803 SendReadReply( 804 context, PP_OK, std::string(read_buffer_->data(), net_result)); 805 } else if (net_result == 0) { 806 end_of_file_reached_ = true; 807 SendReadReply(context, PP_OK, std::string()); 808 } else { 809 SendReadError(context, NetErrorToPepperError(net_result)); 810 } 811 read_buffer_ = NULL; 812} 813 814void PepperTCPSocketMessageFilter::OnWriteCompleted( 815 const ppapi::host::ReplyMessageContext& context, 816 int net_result) { 817 DCHECK_CURRENTLY_ON(BrowserThread::IO); 818 DCHECK(write_buffer_base_.get()); 819 DCHECK(write_buffer_.get()); 820 821 // Note: For partial writes of 0 bytes, don't continue writing to avoid a 822 // likely infinite loop. 823 if (net_result > 0) { 824 write_buffer_->DidConsume(net_result); 825 if (write_buffer_->BytesRemaining() > 0 && state_.IsConnected()) { 826 DoWrite(context); 827 return; 828 } 829 } 830 831 if (net_result >= 0) 832 SendWriteReply(context, write_buffer_->BytesConsumed()); 833 else 834 SendWriteReply(context, NetErrorToPepperError(net_result)); 835 836 write_buffer_ = NULL; 837 write_buffer_base_ = NULL; 838} 839 840void PepperTCPSocketMessageFilter::OnAcceptCompleted( 841 const ppapi::host::ReplyMessageContext& context, 842 int net_result) { 843 DCHECK_CURRENTLY_ON(BrowserThread::IO); 844 DCHECK(pending_accept_); 845 846 pending_accept_ = false; 847 848 if (net_result != net::OK) { 849 SendAcceptError(context, NetErrorToPepperError(net_result)); 850 return; 851 } 852 853 DCHECK(accepted_socket_.get()); 854 855 net::IPEndPoint ip_end_point_local; 856 PP_NetAddress_Private local_addr = NetAddressPrivateImpl::kInvalidNetAddress; 857 PP_NetAddress_Private remote_addr = NetAddressPrivateImpl::kInvalidNetAddress; 858 859 int32_t pp_result = NetErrorToPepperError( 860 accepted_socket_->GetLocalAddress(&ip_end_point_local)); 861 if (pp_result != PP_OK) { 862 SendAcceptError(context, pp_result); 863 return; 864 } 865 if (!NetAddressPrivateImpl::IPEndPointToNetAddress( 866 ip_end_point_local.address(), 867 ip_end_point_local.port(), 868 &local_addr) || 869 !NetAddressPrivateImpl::IPEndPointToNetAddress( 870 accepted_address_.address(), 871 accepted_address_.port(), 872 &remote_addr)) { 873 SendAcceptError(context, PP_ERROR_ADDRESS_INVALID); 874 return; 875 } 876 877 // |factory_| is guaranteed to be non-NULL here. Only those instances created 878 // in CONNECTED state have a NULL |factory_|, while getting here requires 879 // LISTENING state. 880 scoped_ptr<ppapi::host::ResourceHost> host = 881 factory_->CreateAcceptedTCPSocket( 882 instance_, version_, accepted_socket_.Pass()); 883 if (!host) { 884 SendAcceptError(context, PP_ERROR_NOSPACE); 885 return; 886 } 887 int pending_host_id = ppapi_host_->AddPendingResourceHost(host.Pass()); 888 if (pending_host_id) 889 SendAcceptReply(context, PP_OK, pending_host_id, local_addr, remote_addr); 890 else 891 SendAcceptError(context, PP_ERROR_NOSPACE); 892} 893 894void PepperTCPSocketMessageFilter::SendBindReply( 895 const ppapi::host::ReplyMessageContext& context, 896 int32_t pp_result, 897 const PP_NetAddress_Private& local_addr) { 898 ppapi::host::ReplyMessageContext reply_context(context); 899 reply_context.params.set_result(pp_result); 900 SendReply(reply_context, PpapiPluginMsg_TCPSocket_BindReply(local_addr)); 901} 902 903void PepperTCPSocketMessageFilter::SendBindError( 904 const ppapi::host::ReplyMessageContext& context, 905 int32_t pp_error) { 906 SendBindReply(context, pp_error, NetAddressPrivateImpl::kInvalidNetAddress); 907} 908 909void PepperTCPSocketMessageFilter::SendConnectReply( 910 const ppapi::host::ReplyMessageContext& context, 911 int32_t pp_result, 912 const PP_NetAddress_Private& local_addr, 913 const PP_NetAddress_Private& remote_addr) { 914 ppapi::host::ReplyMessageContext reply_context(context); 915 reply_context.params.set_result(pp_result); 916 SendReply(reply_context, 917 PpapiPluginMsg_TCPSocket_ConnectReply(local_addr, remote_addr)); 918} 919 920void PepperTCPSocketMessageFilter::SendConnectError( 921 const ppapi::host::ReplyMessageContext& context, 922 int32_t pp_error) { 923 SendConnectReply(context, 924 pp_error, 925 NetAddressPrivateImpl::kInvalidNetAddress, 926 NetAddressPrivateImpl::kInvalidNetAddress); 927} 928 929void PepperTCPSocketMessageFilter::SendSSLHandshakeReply( 930 const ppapi::host::ReplyMessageContext& context, 931 int32_t pp_result) { 932 ppapi::host::ReplyMessageContext reply_context(context); 933 reply_context.params.set_result(pp_result); 934 ppapi::PPB_X509Certificate_Fields certificate_fields; 935 if (pp_result == PP_OK) { 936 // Our socket is guaranteed to be an SSL socket if we get here. 937 net::SSLInfo ssl_info; 938 ssl_socket_->GetSSLInfo(&ssl_info); 939 if (ssl_info.cert.get()) { 940 pepper_socket_utils::GetCertificateFields(*ssl_info.cert.get(), 941 &certificate_fields); 942 } 943 } 944 SendReply(reply_context, 945 PpapiPluginMsg_TCPSocket_SSLHandshakeReply(certificate_fields)); 946} 947 948void PepperTCPSocketMessageFilter::SendReadReply( 949 const ppapi::host::ReplyMessageContext& context, 950 int32_t pp_result, 951 const std::string& data) { 952 ppapi::host::ReplyMessageContext reply_context(context); 953 reply_context.params.set_result(pp_result); 954 SendReply(reply_context, PpapiPluginMsg_TCPSocket_ReadReply(data)); 955} 956 957void PepperTCPSocketMessageFilter::SendReadError( 958 const ppapi::host::ReplyMessageContext& context, 959 int32_t pp_error) { 960 SendReadReply(context, pp_error, std::string()); 961} 962 963void PepperTCPSocketMessageFilter::SendWriteReply( 964 const ppapi::host::ReplyMessageContext& context, 965 int32_t pp_result) { 966 ppapi::host::ReplyMessageContext reply_context(context); 967 reply_context.params.set_result(pp_result); 968 SendReply(reply_context, PpapiPluginMsg_TCPSocket_WriteReply()); 969} 970 971void PepperTCPSocketMessageFilter::SendListenReply( 972 const ppapi::host::ReplyMessageContext& context, 973 int32_t pp_result) { 974 ppapi::host::ReplyMessageContext reply_context(context); 975 reply_context.params.set_result(pp_result); 976 SendReply(reply_context, PpapiPluginMsg_TCPSocket_ListenReply()); 977} 978 979void PepperTCPSocketMessageFilter::SendAcceptReply( 980 const ppapi::host::ReplyMessageContext& context, 981 int32_t pp_result, 982 int pending_host_id, 983 const PP_NetAddress_Private& local_addr, 984 const PP_NetAddress_Private& remote_addr) { 985 ppapi::host::ReplyMessageContext reply_context(context); 986 reply_context.params.set_result(pp_result); 987 SendReply(reply_context, 988 PpapiPluginMsg_TCPSocket_AcceptReply( 989 pending_host_id, local_addr, remote_addr)); 990} 991 992void PepperTCPSocketMessageFilter::SendAcceptError( 993 const ppapi::host::ReplyMessageContext& context, 994 int32_t pp_error) { 995 SendAcceptReply(context, 996 pp_error, 997 0, 998 NetAddressPrivateImpl::kInvalidNetAddress, 999 NetAddressPrivateImpl::kInvalidNetAddress); 1000} 1001 1002} // namespace content 1003