Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Side by Side Diff: content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc

Issue 690903002: Remove timing limitation of SetOption invocation for PPAPI sockets. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase and fixed implementation. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698