Chromium Code Reviews| 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 56 : version_(version), | 56 : version_(version), |
| 57 external_plugin_(host->external_plugin()), | 57 external_plugin_(host->external_plugin()), |
| 58 render_process_id_(0), | 58 render_process_id_(0), |
| 59 render_frame_id_(0), | 59 render_frame_id_(0), |
| 60 ppapi_host_(host->GetPpapiHost()), | 60 ppapi_host_(host->GetPpapiHost()), |
| 61 factory_(factory), | 61 factory_(factory), |
| 62 instance_(instance), | 62 instance_(instance), |
| 63 state_(TCPSocketState::INITIAL), | 63 state_(TCPSocketState::INITIAL), |
| 64 end_of_file_reached_(false), | 64 end_of_file_reached_(false), |
| 65 bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), | 65 bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), |
| 66 socket_options_(SOCKET_OPTION_NODELAY), | |
|
bbudge
2014/12/09 18:37:37
Even though not strictly necessary in this case, w
hidehiko
2014/12/09 19:51:42
Done.
| |
| 66 address_index_(0), | 67 address_index_(0), |
| 67 socket_(new net::TCPSocket(NULL, net::NetLog::Source())), | 68 socket_(new net::TCPSocket(NULL, net::NetLog::Source())), |
| 68 ssl_context_helper_(host->ssl_context_helper()), | 69 ssl_context_helper_(host->ssl_context_helper()), |
| 69 pending_accept_(false) { | 70 pending_accept_(false) { |
| 70 DCHECK(host); | 71 DCHECK(host); |
| 71 ++g_num_instances; | 72 ++g_num_instances; |
| 72 if (!host->GetRenderFrameIDsForInstance( | 73 if (!host->GetRenderFrameIDsForInstance( |
| 73 instance, &render_process_id_, &render_frame_id_)) { | 74 instance, &render_process_id_, &render_frame_id_)) { |
| 74 NOTREACHED(); | 75 NOTREACHED(); |
| 75 } | 76 } |
| 76 } | 77 } |
| 77 | 78 |
| 78 PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter( | 79 PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter( |
| 79 BrowserPpapiHostImpl* host, | 80 BrowserPpapiHostImpl* host, |
| 80 PP_Instance instance, | 81 PP_Instance instance, |
| 81 TCPSocketVersion version, | 82 TCPSocketVersion version, |
| 82 scoped_ptr<net::TCPSocket> socket) | 83 scoped_ptr<net::TCPSocket> socket) |
| 83 : version_(version), | 84 : version_(version), |
| 84 external_plugin_(host->external_plugin()), | 85 external_plugin_(host->external_plugin()), |
| 85 render_process_id_(0), | 86 render_process_id_(0), |
| 86 render_frame_id_(0), | 87 render_frame_id_(0), |
| 87 ppapi_host_(host->GetPpapiHost()), | 88 ppapi_host_(host->GetPpapiHost()), |
| 88 factory_(NULL), | 89 factory_(NULL), |
| 89 instance_(instance), | 90 instance_(instance), |
| 90 state_(TCPSocketState::CONNECTED), | 91 state_(TCPSocketState::CONNECTED), |
| 91 end_of_file_reached_(false), | 92 end_of_file_reached_(false), |
| 92 bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), | 93 bind_input_addr_(NetAddressPrivateImpl::kInvalidNetAddress), |
| 94 socket_options_(SOCKET_OPTION_NODELAY), | |
| 93 address_index_(0), | 95 address_index_(0), |
| 94 socket_(socket.Pass()), | 96 socket_(socket.Pass()), |
| 95 ssl_context_helper_(host->ssl_context_helper()), | 97 ssl_context_helper_(host->ssl_context_helper()), |
| 96 pending_accept_(false) { | 98 pending_accept_(false) { |
| 97 DCHECK(host); | 99 DCHECK(host); |
| 98 DCHECK_NE(version, ppapi::TCP_SOCKET_VERSION_1_0); | 100 DCHECK_NE(version, ppapi::TCP_SOCKET_VERSION_1_0); |
| 99 | 101 |
| 100 ++g_num_instances; | 102 ++g_num_instances; |
| 101 if (!host->GetRenderFrameIDsForInstance( | 103 if (!host->GetRenderFrameIDsForInstance( |
| 102 instance, &render_process_id_, &render_frame_id_)) { | 104 instance, &render_process_id_, &render_frame_id_)) { |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 449 } | 451 } |
| 450 | 452 |
| 451 int32_t PepperTCPSocketMessageFilter::OnMsgSetOption( | 453 int32_t PepperTCPSocketMessageFilter::OnMsgSetOption( |
| 452 const ppapi::host::HostMessageContext* context, | 454 const ppapi::host::HostMessageContext* context, |
| 453 PP_TCPSocket_Option name, | 455 PP_TCPSocket_Option name, |
| 454 const ppapi::SocketOptionData& value) { | 456 const ppapi::SocketOptionData& value) { |
| 455 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 457 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 456 | 458 |
| 457 switch (name) { | 459 switch (name) { |
| 458 case PP_TCPSOCKET_OPTION_NO_DELAY: { | 460 case PP_TCPSOCKET_OPTION_NO_DELAY: { |
| 459 if (state_.state() != TCPSocketState::CONNECTED) | |
| 460 return PP_ERROR_FAILED; | |
| 461 | |
| 462 bool boolean_value = false; | 461 bool boolean_value = false; |
| 463 if (!value.GetBool(&boolean_value)) | 462 if (!value.GetBool(&boolean_value)) |
| 464 return PP_ERROR_BADARGUMENT; | 463 return PP_ERROR_BADARGUMENT; |
| 465 return socket_->SetNoDelay(boolean_value) ? PP_OK : PP_ERROR_FAILED; | 464 |
| 465 // If the socket is already connected, proxy the value to TCPSocket. | |
| 466 if (state_.state() == TCPSocketState::CONNECTED) | |
| 467 return socket_->SetNoDelay(boolean_value) ? PP_OK : PP_ERROR_FAILED; | |
| 468 | |
| 469 // TCPSocket instance is not yet created. So remember the value here. | |
| 470 if (boolean_value) { | |
| 471 socket_options_ |= SOCKET_OPTION_NODELAY; | |
| 472 } else { | |
| 473 socket_options_ &= ~SOCKET_OPTION_NODELAY; | |
| 474 } | |
| 475 return PP_OK; | |
| 466 } | 476 } |
| 467 case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: | 477 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; | 478 int32_t integer_value = 0; |
| 473 if (!value.GetInt32(&integer_value) || integer_value <= 0) | 479 if (!value.GetInt32(&integer_value) || |
| 480 integer_value <= 0 || | |
| 481 integer_value > TCPSocketResourceBase::kMaxSendBufferSize) | |
| 474 return PP_ERROR_BADARGUMENT; | 482 return PP_ERROR_BADARGUMENT; |
| 475 | 483 |
| 476 int net_result = net::ERR_UNEXPECTED; | 484 // If the socket is already connected, proxy the value to TCPSocket. |
| 477 if (name == PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE) { | 485 if (state_.state() == TCPSocketState::CONNECTED) { |
| 478 if (integer_value > TCPSocketResourceBase::kMaxSendBufferSize) | 486 return NetErrorToPepperError( |
| 479 return PP_ERROR_BADARGUMENT; | 487 socket_->SetSendBufferSize(integer_value)); |
| 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 } | 488 } |
| 486 // TODO(wtc): Add error mapping code. | 489 |
| 487 return (net_result == net::OK) ? PP_OK : PP_ERROR_FAILED; | 490 // TCPSocket instance is not yet created. So remember the value here. |
| 491 socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE; | |
| 492 sndbuf_size_ = integer_value; | |
| 493 return PP_OK; | |
| 494 } | |
| 495 case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { | |
| 496 int32_t integer_value = 0; | |
| 497 if (!value.GetInt32(&integer_value) || | |
| 498 integer_value <= 0 || | |
| 499 integer_value > TCPSocketResourceBase::kMaxReceiveBufferSize) | |
| 500 return PP_ERROR_BADARGUMENT; | |
| 501 | |
| 502 // If the socket is already connected, proxy the value to TCPSocket. | |
| 503 if (state_.state() == TCPSocketState::CONNECTED) { | |
| 504 return NetErrorToPepperError( | |
| 505 socket_->SetReceiveBufferSize(integer_value)); | |
| 506 } | |
| 507 | |
| 508 // TCPSocket instance is not yet created. So remember the value here. | |
| 509 socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE; | |
| 510 rcvbuf_size_ = integer_value; | |
| 511 return PP_OK; | |
| 488 } | 512 } |
| 489 default: { | 513 default: { |
| 490 NOTREACHED(); | 514 NOTREACHED(); |
| 491 return PP_ERROR_BADARGUMENT; | 515 return PP_ERROR_BADARGUMENT; |
| 492 } | 516 } |
| 493 } | 517 } |
| 494 } | 518 } |
| 495 | 519 |
| 496 void PepperTCPSocketMessageFilter::DoBind( | 520 void PepperTCPSocketMessageFilter::DoBind( |
| 497 const ppapi::host::ReplyMessageContext& context, | 521 const ppapi::host::ReplyMessageContext& context, |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 683 | 707 |
| 684 StartConnect(context); | 708 StartConnect(context); |
| 685 } | 709 } |
| 686 | 710 |
| 687 void PepperTCPSocketMessageFilter::StartConnect( | 711 void PepperTCPSocketMessageFilter::StartConnect( |
| 688 const ppapi::host::ReplyMessageContext& context) { | 712 const ppapi::host::ReplyMessageContext& context) { |
| 689 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 713 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 690 DCHECK(state_.IsPending(TCPSocketState::CONNECT)); | 714 DCHECK(state_.IsPending(TCPSocketState::CONNECT)); |
| 691 DCHECK_LT(address_index_, address_list_.size()); | 715 DCHECK_LT(address_index_, address_list_.size()); |
| 692 | 716 |
| 693 int net_result = net::OK; | 717 if (!socket_->IsValid()) { |
| 694 if (!socket_->IsValid()) | 718 int net_result = socket_->Open(address_list_[address_index_].GetFamily()); |
| 695 net_result = socket_->Open(address_list_[address_index_].GetFamily()); | 719 if (net_result != net::OK) { |
| 720 OnConnectCompleted(context, net_result); | |
| 721 return; | |
| 722 } | |
| 723 } | |
| 696 | 724 |
| 697 if (net_result == net::OK) { | 725 socket_->SetDefaultOptionsForClient(); |
| 698 net_result = socket_->Connect( | 726 |
| 699 address_list_[address_index_], | 727 if (!(socket_options_ & SOCKET_OPTION_NODELAY)) { |
| 700 base::Bind(&PepperTCPSocketMessageFilter::OnConnectCompleted, | 728 if (!socket_->SetNoDelay(false)) { |
| 701 base::Unretained(this), | 729 OnConnectCompleted(context, net::ERR_FAILED); |
| 702 context)); | 730 return; |
| 731 } | |
| 703 } | 732 } |
| 733 if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) { | |
| 734 int net_result = socket_->SetReceiveBufferSize(rcvbuf_size_); | |
| 735 if (net_result != net::OK) { | |
| 736 OnConnectCompleted(context, net_result); | |
| 737 return; | |
| 738 } | |
| 739 } | |
| 740 if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) { | |
| 741 int net_result = socket_->SetSendBufferSize(sndbuf_size_); | |
| 742 if (net_result != net::OK) { | |
| 743 OnConnectCompleted(context, net_result); | |
| 744 return; | |
| 745 } | |
| 746 } | |
| 747 | |
| 748 int net_result = socket_->Connect( | |
| 749 address_list_[address_index_], | |
| 750 base::Bind(&PepperTCPSocketMessageFilter::OnConnectCompleted, | |
| 751 base::Unretained(this), | |
| 752 context)); | |
| 704 if (net_result != net::ERR_IO_PENDING) | 753 if (net_result != net::ERR_IO_PENDING) |
| 705 OnConnectCompleted(context, net_result); | 754 OnConnectCompleted(context, net_result); |
| 706 } | 755 } |
| 707 | 756 |
| 708 void PepperTCPSocketMessageFilter::OnConnectCompleted( | 757 void PepperTCPSocketMessageFilter::OnConnectCompleted( |
| 709 const ppapi::host::ReplyMessageContext& context, | 758 const ppapi::host::ReplyMessageContext& context, |
| 710 int net_result) { | 759 int net_result) { |
| 711 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 760 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 712 | 761 |
| 713 if (!state_.IsPending(TCPSocketState::CONNECT)) { | 762 if (!state_.IsPending(TCPSocketState::CONNECT)) { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 741 ip_end_point_local.port(), | 790 ip_end_point_local.port(), |
| 742 &local_addr) || | 791 &local_addr) || |
| 743 !NetAddressPrivateImpl::IPEndPointToNetAddress( | 792 !NetAddressPrivateImpl::IPEndPointToNetAddress( |
| 744 ip_end_point_remote.address(), | 793 ip_end_point_remote.address(), |
| 745 ip_end_point_remote.port(), | 794 ip_end_point_remote.port(), |
| 746 &remote_addr)) { | 795 &remote_addr)) { |
| 747 pp_result = PP_ERROR_ADDRESS_INVALID; | 796 pp_result = PP_ERROR_ADDRESS_INVALID; |
| 748 break; | 797 break; |
| 749 } | 798 } |
| 750 | 799 |
| 751 socket_->SetDefaultOptionsForClient(); | |
| 752 SendConnectReply(context, PP_OK, local_addr, remote_addr); | 800 SendConnectReply(context, PP_OK, local_addr, remote_addr); |
| 753 state_.CompletePendingTransition(true); | 801 state_.CompletePendingTransition(true); |
| 754 return; | 802 return; |
| 755 } while (false); | 803 } while (false); |
| 756 | 804 |
| 757 if (version_ == ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) { | 805 if (version_ == ppapi::TCP_SOCKET_VERSION_1_1_OR_ABOVE) { |
| 758 DCHECK_EQ(1u, address_list_.size()); | 806 DCHECK_EQ(1u, address_list_.size()); |
| 759 | 807 |
| 760 SendConnectError(context, pp_result); | 808 SendConnectError(context, pp_result); |
| 761 state_.CompletePendingTransition(false); | 809 state_.CompletePendingTransition(false); |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 993 const ppapi::host::ReplyMessageContext& context, | 1041 const ppapi::host::ReplyMessageContext& context, |
| 994 int32_t pp_error) { | 1042 int32_t pp_error) { |
| 995 SendAcceptReply(context, | 1043 SendAcceptReply(context, |
| 996 pp_error, | 1044 pp_error, |
| 997 0, | 1045 0, |
| 998 NetAddressPrivateImpl::kInvalidNetAddress, | 1046 NetAddressPrivateImpl::kInvalidNetAddress, |
| 999 NetAddressPrivateImpl::kInvalidNetAddress); | 1047 NetAddressPrivateImpl::kInvalidNetAddress); |
| 1000 } | 1048 } |
| 1001 | 1049 |
| 1002 } // namespace content | 1050 } // namespace content |
| OLD | NEW |