| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.
h" | 5 #include "content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.
h" |
| 6 | 6 |
| 7 #include <cstring> | 7 #include <cstring> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 : version_(version), | 57 : version_(version), |
| 58 external_plugin_(host->external_plugin()), | 58 external_plugin_(host->external_plugin()), |
| 59 render_process_id_(0), | 59 render_process_id_(0), |
| 60 render_frame_id_(0), | 60 render_frame_id_(0), |
| 61 ppapi_host_(host->GetPpapiHost()), | 61 ppapi_host_(host->GetPpapiHost()), |
| 62 factory_(factory), | 62 factory_(factory), |
| 63 instance_(instance), | 63 instance_(instance), |
| 64 state_(TCPSocketState::INITIAL), | 64 state_(TCPSocketState::INITIAL), |
| 65 end_of_file_reached_(false), | 65 end_of_file_reached_(false), |
| 66 bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), | 66 bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), |
| 67 socket_options_(SOCKET_OPTION_NODELAY), |
| 68 rcvbuf_size_(0), |
| 69 sndbuf_size_(0), |
| 67 address_index_(0), | 70 address_index_(0), |
| 68 socket_(new net::TCPSocket(NULL, net::NetLog::Source())), | 71 socket_(new net::TCPSocket(NULL, net::NetLog::Source())), |
| 69 ssl_context_helper_(host->ssl_context_helper()), | 72 ssl_context_helper_(host->ssl_context_helper()), |
| 70 pending_accept_(false) { | 73 pending_accept_(false) { |
| 71 DCHECK(host); | 74 DCHECK(host); |
| 72 ++g_num_instances; | 75 ++g_num_instances; |
| 73 if (!host->GetRenderFrameIDsForInstance( | 76 if (!host->GetRenderFrameIDsForInstance( |
| 74 instance, &render_process_id_, &render_frame_id_)) { | 77 instance, &render_process_id_, &render_frame_id_)) { |
| 75 NOTREACHED(); | 78 NOTREACHED(); |
| 76 } | 79 } |
| 77 } | 80 } |
| 78 | 81 |
| 79 PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter( | 82 PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter( |
| 80 BrowserPpapiHostImpl* host, | 83 BrowserPpapiHostImpl* host, |
| 81 PP_Instance instance, | 84 PP_Instance instance, |
| 82 TCPSocketVersion version, | 85 TCPSocketVersion version, |
| 83 scoped_ptr<net::TCPSocket> socket) | 86 scoped_ptr<net::TCPSocket> socket) |
| 84 : version_(version), | 87 : version_(version), |
| 85 external_plugin_(host->external_plugin()), | 88 external_plugin_(host->external_plugin()), |
| 86 render_process_id_(0), | 89 render_process_id_(0), |
| 87 render_frame_id_(0), | 90 render_frame_id_(0), |
| 88 ppapi_host_(host->GetPpapiHost()), | 91 ppapi_host_(host->GetPpapiHost()), |
| 89 factory_(NULL), | 92 factory_(NULL), |
| 90 instance_(instance), | 93 instance_(instance), |
| 91 state_(TCPSocketState::CONNECTED), | 94 state_(TCPSocketState::CONNECTED), |
| 92 end_of_file_reached_(false), | 95 end_of_file_reached_(false), |
| 93 bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), | 96 bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), |
| 97 socket_options_(SOCKET_OPTION_NODELAY), |
| 98 rcvbuf_size_(0), |
| 99 sndbuf_size_(0), |
| 94 address_index_(0), | 100 address_index_(0), |
| 95 socket_(socket.Pass()), | 101 socket_(socket.Pass()), |
| 96 ssl_context_helper_(host->ssl_context_helper()), | 102 ssl_context_helper_(host->ssl_context_helper()), |
| 97 pending_accept_(false) { | 103 pending_accept_(false) { |
| 98 DCHECK(host); | 104 DCHECK(host); |
| 99 DCHECK_NE(version, ppapi::TCP_SOCKET_VERSION_1_0); | 105 DCHECK_NE(version, ppapi::TCP_SOCKET_VERSION_1_0); |
| 100 | 106 |
| 101 ++g_num_instances; | 107 ++g_num_instances; |
| 102 if (!host->GetRenderFrameIDsForInstance( | 108 if (!host->GetRenderFrameIDsForInstance( |
| 103 instance, &render_process_id_, &render_frame_id_)) { | 109 instance, &render_process_id_, &render_frame_id_)) { |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 } | 456 } |
| 451 | 457 |
| 452 int32_t PepperTCPSocketMessageFilter::OnMsgSetOption( | 458 int32_t PepperTCPSocketMessageFilter::OnMsgSetOption( |
| 453 const ppapi::host::HostMessageContext* context, | 459 const ppapi::host::HostMessageContext* context, |
| 454 PP_TCPSocket_Option name, | 460 PP_TCPSocket_Option name, |
| 455 const ppapi::SocketOptionData& value) { | 461 const ppapi::SocketOptionData& value) { |
| 456 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 462 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 457 | 463 |
| 458 switch (name) { | 464 switch (name) { |
| 459 case PP_TCPSOCKET_OPTION_NO_DELAY: { | 465 case PP_TCPSOCKET_OPTION_NO_DELAY: { |
| 460 if (state_.state() != TCPSocketState::CONNECTED) | |
| 461 return PP_ERROR_FAILED; | |
| 462 | |
| 463 bool boolean_value = false; | 466 bool boolean_value = false; |
| 464 if (!value.GetBool(&boolean_value)) | 467 if (!value.GetBool(&boolean_value)) |
| 465 return PP_ERROR_BADARGUMENT; | 468 return PP_ERROR_BADARGUMENT; |
| 466 return socket_->SetNoDelay(boolean_value) ? PP_OK : PP_ERROR_FAILED; | 469 |
| 470 // If the socket is already connected, proxy the value to TCPSocket. |
| 471 if (state_.state() == TCPSocketState::CONNECTED) |
| 472 return socket_->SetNoDelay(boolean_value) ? PP_OK : PP_ERROR_FAILED; |
| 473 |
| 474 // TCPSocket instance is not yet created. So remember the value here. |
| 475 if (boolean_value) { |
| 476 socket_options_ |= SOCKET_OPTION_NODELAY; |
| 477 } else { |
| 478 socket_options_ &= ~SOCKET_OPTION_NODELAY; |
| 479 } |
| 480 return PP_OK; |
| 467 } | 481 } |
| 468 case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: | 482 case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: { |
| 469 case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { | |
| 470 if (state_.state() != TCPSocketState::CONNECTED) | |
| 471 return PP_ERROR_FAILED; | |
| 472 | |
| 473 int32_t integer_value = 0; | 483 int32_t integer_value = 0; |
| 474 if (!value.GetInt32(&integer_value) || integer_value <= 0) | 484 if (!value.GetInt32(&integer_value) || |
| 485 integer_value <= 0 || |
| 486 integer_value > TCPSocketResourceBase::kMaxSendBufferSize) |
| 475 return PP_ERROR_BADARGUMENT; | 487 return PP_ERROR_BADARGUMENT; |
| 476 | 488 |
| 477 int net_result = net::ERR_UNEXPECTED; | 489 // If the socket is already connected, proxy the value to TCPSocket. |
| 478 if (name == PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE) { | 490 if (state_.state() == TCPSocketState::CONNECTED) { |
| 479 if (integer_value > TCPSocketResourceBase::kMaxSendBufferSize) | 491 return NetErrorToPepperError( |
| 480 return PP_ERROR_BADARGUMENT; | 492 socket_->SetSendBufferSize(integer_value)); |
| 481 net_result = socket_->SetSendBufferSize(integer_value); | |
| 482 } else { | |
| 483 if (integer_value > TCPSocketResourceBase::kMaxReceiveBufferSize) | |
| 484 return PP_ERROR_BADARGUMENT; | |
| 485 net_result = socket_->SetReceiveBufferSize(integer_value); | |
| 486 } | 493 } |
| 487 // TODO(wtc): Add error mapping code. | 494 |
| 488 return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED; | 495 // TCPSocket instance is not yet created. So remember the value here. |
| 496 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE; |
| 497 sndbuf_size_ = integer_value; |
| 498 return PP_OK; |
| 499 } |
| 500 case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { |
| 501 int32_t integer_value = 0; |
| 502 if (!value.GetInt32(&integer_value) || |
| 503 integer_value <= 0 || |
| 504 integer_value > TCPSocketResourceBase::kMaxReceiveBufferSize) |
| 505 return PP_ERROR_BADARGUMENT; |
| 506 |
| 507 // If the socket is already connected, proxy the value to TCPSocket. |
| 508 if (state_.state() == TCPSocketState::CONNECTED) { |
| 509 return NetErrorToPepperError( |
| 510 socket_->SetReceiveBufferSize(integer_value)); |
| 511 } |
| 512 |
| 513 // TCPSocket instance is not yet created. So remember the value here. |
| 514 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE; |
| 515 rcvbuf_size_ = integer_value; |
| 516 return PP_OK; |
| 489 } | 517 } |
| 490 default: { | 518 default: { |
| 491 NOTREACHED(); | 519 NOTREACHED(); |
| 492 return PP_ERROR_BADARGUMENT; | 520 return PP_ERROR_BADARGUMENT; |
| 493 } | 521 } |
| 494 } | 522 } |
| 495 } | 523 } |
| 496 | 524 |
| 497 void PepperTCPSocketMessageFilter::DoBind( | 525 void PepperTCPSocketMessageFilter::DoBind( |
| 498 const ppapi::host::ReplyMessageContext& context, | 526 const ppapi::host::ReplyMessageContext& context, |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 | 717 |
| 690 StartConnect(context); | 718 StartConnect(context); |
| 691 } | 719 } |
| 692 | 720 |
| 693 void PepperTCPSocketMessageFilter::StartConnect( | 721 void PepperTCPSocketMessageFilter::StartConnect( |
| 694 const ppapi::host::ReplyMessageContext& context) { | 722 const ppapi::host::ReplyMessageContext& context) { |
| 695 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 723 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 696 DCHECK(state_.IsPending(TCPSocketState::CONNECT)); | 724 DCHECK(state_.IsPending(TCPSocketState::CONNECT)); |
| 697 DCHECK_LT(address_index_, address_list_.size()); | 725 DCHECK_LT(address_index_, address_list_.size()); |
| 698 | 726 |
| 699 int net_result = net::OK; | 727 if (!socket_->IsValid()) { |
| 700 if (!socket_->IsValid()) | 728 int net_result = socket_->Open(address_list_[address_index_].GetFamily()); |
| 701 net_result = socket_->Open(address_list_[address_index_].GetFamily()); | 729 if (net_result != net::OK) { |
| 730 OnConnectCompleted(context, net_result); |
| 731 return; |
| 732 } |
| 733 } |
| 702 | 734 |
| 703 if (net_result == net::OK) { | 735 socket_->SetDefaultOptionsForClient(); |
| 704 net_result = socket_->Connect( | 736 |
| 705 address_list_[address_index_], | 737 if (!(socket_options_ & SOCKET_OPTION_NODELAY)) { |
| 706 base::Bind(&PepperTCPSocketMessageFilter::OnConnectCompleted, | 738 if (!socket_->SetNoDelay(false)) { |
| 707 base::Unretained(this), | 739 OnConnectCompleted(context, net::ERR_FAILED); |
| 708 context)); | 740 return; |
| 741 } |
| 709 } | 742 } |
| 743 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) { |
| 744 int net_result = socket_->SetReceiveBufferSize(rcvbuf_size_); |
| 745 if (net_result != net::OK) { |
| 746 OnConnectCompleted(context, net_result); |
| 747 return; |
| 748 } |
| 749 } |
| 750 if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) { |
| 751 int net_result = socket_->SetSendBufferSize(sndbuf_size_); |
| 752 if (net_result != net::OK) { |
| 753 OnConnectCompleted(context, net_result); |
| 754 return; |
| 755 } |
| 756 } |
| 757 |
| 758 int net_result = socket_->Connect( |
| 759 address_list_[address_index_], |
| 760 base::Bind(&PepperTCPSocketMessageFilter::OnConnectCompleted, |
| 761 base::Unretained(this), |
| 762 context)); |
| 710 if (net_result != net::ERR_IO_PENDING) | 763 if (net_result != net::ERR_IO_PENDING) |
| 711 OnConnectCompleted(context, net_result); | 764 OnConnectCompleted(context, net_result); |
| 712 } | 765 } |
| 713 | 766 |
| 714 void PepperTCPSocketMessageFilter::OnConnectCompleted( | 767 void PepperTCPSocketMessageFilter::OnConnectCompleted( |
| 715 const ppapi::host::ReplyMessageContext& context, | 768 const ppapi::host::ReplyMessageContext& context, |
| 716 int net_result) { | 769 int net_result) { |
| 717 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 770 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 718 | 771 |
| 719 if (!state_.IsPending(TCPSocketState::CONNECT)) { | 772 if (!state_.IsPending(TCPSocketState::CONNECT)) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 747 ip_end_point_local.port(), | 800 ip_end_point_local.port(), |
| 748 &local_addr) || | 801 &local_addr) || |
| 749 !NetAddressPrivateImpl::IPEndPointToNetAddress( | 802 !NetAddressPrivateImpl::IPEndPointToNetAddress( |
| 750 ip_end_point_remote.address(), | 803 ip_end_point_remote.address(), |
| 751 ip_end_point_remote.port(), | 804 ip_end_point_remote.port(), |
| 752 &remote_addr)) { | 805 &remote_addr)) { |
| 753 pp_result = PP_ERROR_ADDRESS_INVALID; | 806 pp_result = PP_ERROR_ADDRESS_INVALID; |
| 754 break; | 807 break; |
| 755 } | 808 } |
| 756 | 809 |
| 757 socket_->SetDefaultOptionsForClient(); | |
| 758 SendConnectReply(context, PP_OK, local_addr, remote_addr); | 810 SendConnectReply(context, PP_OK, local_addr, remote_addr); |
| 759 state_.CompletePendingTransition(true); | 811 state_.CompletePendingTransition(true); |
| 760 return; | 812 return; |
| 761 } while (false); | 813 } while (false); |
| 762 | 814 |
| 763 if (version_ == ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) { | 815 if (version_ == ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) { |
| 764 DCHECK_EQ(1u, address_list_.size()); | 816 DCHECK_EQ(1u, address_list_.size()); |
| 765 | 817 |
| 766 SendConnectError(context, pp_result); | 818 SendConnectError(context, pp_result); |
| 767 state_.CompletePendingTransition(false); | 819 state_.CompletePendingTransition(false); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 const ppapi::host::ReplyMessageContext& context, | 1051 const ppapi::host::ReplyMessageContext& context, |
| 1000 int32_t pp_error) { | 1052 int32_t pp_error) { |
| 1001 SendAcceptReply(context, | 1053 SendAcceptReply(context, |
| 1002 pp_error, | 1054 pp_error, |
| 1003 0, | 1055 0, |
| 1004 NetAddressPrivateImpl::kInvalidNetAddress, | 1056 NetAddressPrivateImpl::kInvalidNetAddress, |
| 1005 NetAddressPrivateImpl::kInvalidNetAddress); | 1057 NetAddressPrivateImpl::kInvalidNetAddress); |
| 1006 } | 1058 } |
| 1007 | 1059 |
| 1008 } // namespace content | 1060 } // namespace content |
| OLD | NEW |