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

Side by Side Diff: extensions/browser/api/cast_channel/cast_socket.cc

Issue 555283002: Create new class "CastTransport", which encapsulates the message read and write event loops. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed wez's feedback. Created 6 years, 3 months 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "extensions/browser/api/cast_channel/cast_socket.h" 5 #include "extensions/browser/api/cast_channel/cast_socket.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <string.h> 8 #include <string.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 // The default keepalive delay. On Linux, keepalives probes will be sent after 46 // The default keepalive delay. On Linux, keepalives probes will be sent after
47 // the socket is idle for this length of time, and the socket will be closed 47 // the socket is idle for this length of time, and the socket will be closed
48 // after 9 failed probes. So the total idle time before close is 10 * 48 // after 9 failed probes. So the total idle time before close is 10 *
49 // kTcpKeepAliveDelaySecs. 49 // kTcpKeepAliveDelaySecs.
50 const int kTcpKeepAliveDelaySecs = 10; 50 const int kTcpKeepAliveDelaySecs = 10;
51 } // namespace 51 } // namespace
52 52
53 namespace extensions { 53 namespace extensions {
54 54
55 static base::LazyInstance<BrowserContextKeyedAPIFactory< 55 static base::LazyInstance<BrowserContextKeyedAPIFactory<
56 ApiResourceManager<core_api::cast_channel::CastSocket> > > g_factory = 56 ApiResourceManager<core_api::cast_channel::CastSocketImpl> > > g_factory =
57 LAZY_INSTANCE_INITIALIZER; 57 LAZY_INSTANCE_INITIALIZER;
58 58
59 // static 59 // static
60 template <> 60 template <>
61 BrowserContextKeyedAPIFactory< 61 BrowserContextKeyedAPIFactory<
62 ApiResourceManager<core_api::cast_channel::CastSocket> >* 62 ApiResourceManager<core_api::cast_channel::CastSocketImpl> >*
63 ApiResourceManager<core_api::cast_channel::CastSocket>::GetFactoryInstance() { 63 ApiResourceManager<
64 core_api::cast_channel::CastSocketImpl>::GetFactoryInstance() {
64 return g_factory.Pointer(); 65 return g_factory.Pointer();
65 } 66 }
66 67
67 namespace core_api { 68 namespace core_api {
68 namespace cast_channel { 69 namespace cast_channel {
69 70
70 namespace { 71 namespace {
71 72
72 proto::ReadyState ReadyStateToProto(ReadyState state) { 73 proto::ReadyState ReadyStateToProto(ReadyState state) {
73 switch (state) { 74 switch (state) {
74 case READY_STATE_NONE: 75 case READY_STATE_NONE:
75 return proto::READY_STATE_NONE; 76 return proto::READY_STATE_NONE;
76 case READY_STATE_CONNECTING: 77 case READY_STATE_CONNECTING:
77 return proto::READY_STATE_CONNECTING; 78 return proto::READY_STATE_CONNECTING;
78 case READY_STATE_OPEN: 79 case READY_STATE_OPEN:
79 return proto::READY_STATE_OPEN; 80 return proto::READY_STATE_OPEN;
80 case READY_STATE_CLOSING: 81 case READY_STATE_CLOSING:
81 return proto::READY_STATE_CLOSING; 82 return proto::READY_STATE_CLOSING;
82 case READY_STATE_CLOSED: 83 case READY_STATE_CLOSED:
83 return proto::READY_STATE_CLOSED; 84 return proto::READY_STATE_CLOSED;
84 default: 85 default:
85 NOTREACHED(); 86 NOTREACHED();
86 return proto::READY_STATE_NONE; 87 return proto::READY_STATE_NONE;
87 } 88 }
88 } 89 }
89 90
90 proto::ConnectionState ConnectStateToProto(CastSocket::ConnectionState state) { 91 proto::ConnectionState ConnectStateToProto(
92 CastSocketImpl::ConnectionState state) {
91 switch (state) { 93 switch (state) {
92 case CastSocket::CONN_STATE_NONE: 94 case CastSocketImpl::CONN_STATE_NONE:
93 return proto::CONN_STATE_NONE; 95 return proto::CONN_STATE_NONE;
94 case CastSocket::CONN_STATE_TCP_CONNECT: 96 case CastSocketImpl::CONN_STATE_TCP_CONNECT:
95 return proto::CONN_STATE_TCP_CONNECT; 97 return proto::CONN_STATE_TCP_CONNECT;
96 case CastSocket::CONN_STATE_TCP_CONNECT_COMPLETE: 98 case CastSocketImpl::CONN_STATE_TCP_CONNECT_COMPLETE:
97 return proto::CONN_STATE_TCP_CONNECT_COMPLETE; 99 return proto::CONN_STATE_TCP_CONNECT_COMPLETE;
98 case CastSocket::CONN_STATE_SSL_CONNECT: 100 case CastSocketImpl::CONN_STATE_SSL_CONNECT:
99 return proto::CONN_STATE_SSL_CONNECT; 101 return proto::CONN_STATE_SSL_CONNECT;
100 case CastSocket::CONN_STATE_SSL_CONNECT_COMPLETE: 102 case CastSocketImpl::CONN_STATE_SSL_CONNECT_COMPLETE:
101 return proto::CONN_STATE_SSL_CONNECT_COMPLETE; 103 return proto::CONN_STATE_SSL_CONNECT_COMPLETE;
102 case CastSocket::CONN_STATE_AUTH_CHALLENGE_SEND: 104 case CastSocketImpl::CONN_STATE_AUTH_CHALLENGE_SEND:
103 return proto::CONN_STATE_AUTH_CHALLENGE_SEND; 105 return proto::CONN_STATE_AUTH_CHALLENGE_SEND;
104 case CastSocket::CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE: 106 case CastSocketImpl::CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE:
105 return proto::CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE; 107 return proto::CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE;
106 case CastSocket::CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE: 108 case CastSocketImpl::CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE:
107 return proto::CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE; 109 return proto::CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE;
108 default: 110 default:
109 NOTREACHED(); 111 NOTREACHED();
110 return proto::CONN_STATE_NONE; 112 return proto::CONN_STATE_NONE;
111 } 113 }
112 } 114 }
113 115
114 proto::ReadState ReadStateToProto(CastSocket::ReadState state) { 116 proto::ReadState ReadStateToProto(CastSocketImpl::ReadState state) {
115 switch (state) { 117 switch (state) {
116 case CastSocket::READ_STATE_NONE: 118 case CastSocketImpl::READ_STATE_NONE:
117 return proto::READ_STATE_NONE; 119 return proto::READ_STATE_NONE;
118 case CastSocket::READ_STATE_READ: 120 case CastSocketImpl::READ_STATE_READ:
119 return proto::READ_STATE_READ; 121 return proto::READ_STATE_READ;
120 case CastSocket::READ_STATE_READ_COMPLETE: 122 case CastSocketImpl::READ_STATE_READ_COMPLETE:
121 return proto::READ_STATE_READ_COMPLETE; 123 return proto::READ_STATE_READ_COMPLETE;
122 case CastSocket::READ_STATE_DO_CALLBACK: 124 case CastSocketImpl::READ_STATE_DO_CALLBACK:
123 return proto::READ_STATE_DO_CALLBACK; 125 return proto::READ_STATE_DO_CALLBACK;
124 case CastSocket::READ_STATE_ERROR: 126 case CastSocketImpl::READ_STATE_ERROR:
125 return proto::READ_STATE_ERROR; 127 return proto::READ_STATE_ERROR;
126 default: 128 default:
127 NOTREACHED(); 129 NOTREACHED();
128 return proto::READ_STATE_NONE; 130 return proto::READ_STATE_NONE;
129 } 131 }
130 } 132 }
131 133
132 proto::WriteState WriteStateToProto(CastSocket::WriteState state) { 134 proto::WriteState WriteStateToProto(CastSocketImpl::WriteState state) {
133 switch (state) { 135 switch (state) {
134 case CastSocket::WRITE_STATE_NONE: 136 case CastSocketImpl::WRITE_STATE_NONE:
135 return proto::WRITE_STATE_NONE; 137 return proto::WRITE_STATE_NONE;
136 case CastSocket::WRITE_STATE_WRITE: 138 case CastSocketImpl::WRITE_STATE_WRITE:
137 return proto::WRITE_STATE_WRITE; 139 return proto::WRITE_STATE_WRITE;
138 case CastSocket::WRITE_STATE_WRITE_COMPLETE: 140 case CastSocketImpl::WRITE_STATE_WRITE_COMPLETE:
139 return proto::WRITE_STATE_WRITE_COMPLETE; 141 return proto::WRITE_STATE_WRITE_COMPLETE;
140 case CastSocket::WRITE_STATE_DO_CALLBACK: 142 case CastSocketImpl::WRITE_STATE_DO_CALLBACK:
141 return proto::WRITE_STATE_DO_CALLBACK; 143 return proto::WRITE_STATE_DO_CALLBACK;
142 case CastSocket::WRITE_STATE_ERROR: 144 case CastSocketImpl::WRITE_STATE_ERROR:
143 return proto::WRITE_STATE_ERROR; 145 return proto::WRITE_STATE_ERROR;
144 default: 146 default:
145 NOTREACHED(); 147 NOTREACHED();
146 return proto::WRITE_STATE_NONE; 148 return proto::WRITE_STATE_NONE;
147 } 149 }
148 } 150 }
149 151
150 proto::ErrorState ErrorStateToProto(ChannelError state) { 152 proto::ErrorState ErrorStateToProto(ChannelError state) {
151 switch (state) { 153 switch (state) {
152 case CHANNEL_ERROR_NONE: 154 case CHANNEL_ERROR_NONE:
(...skipping 17 matching lines...) Expand all
170 case CHANNEL_ERROR_UNKNOWN: 172 case CHANNEL_ERROR_UNKNOWN:
171 return proto::CHANNEL_ERROR_UNKNOWN; 173 return proto::CHANNEL_ERROR_UNKNOWN;
172 default: 174 default:
173 NOTREACHED(); 175 NOTREACHED();
174 return proto::CHANNEL_ERROR_NONE; 176 return proto::CHANNEL_ERROR_NONE;
175 } 177 }
176 } 178 }
177 179
178 } // namespace 180 } // namespace
179 181
180 CastSocket::CastSocket(const std::string& owner_extension_id, 182 CastSocketImpl::CastSocketImpl(const std::string& owner_extension_id,
181 const net::IPEndPoint& ip_endpoint, 183 const net::IPEndPoint& ip_endpoint,
182 ChannelAuthType channel_auth, 184 ChannelAuthType channel_auth,
183 CastSocket::Delegate* delegate, 185 CastSocketImpl::Delegate* delegate,
184 net::NetLog* net_log, 186 net::NetLog* net_log,
185 const base::TimeDelta& timeout, 187 const base::TimeDelta& timeout,
186 const scoped_refptr<Logger>& logger) 188 const scoped_refptr<Logger>& logger)
187 : ApiResource(owner_extension_id), 189 : ApiResource(owner_extension_id),
188 channel_id_(0), 190 channel_id_(0),
189 ip_endpoint_(ip_endpoint), 191 ip_endpoint_(ip_endpoint),
190 channel_auth_(channel_auth), 192 channel_auth_(channel_auth),
191 delegate_(delegate), 193 delegate_(delegate),
192 net_log_(net_log), 194 net_log_(net_log),
193 logger_(logger), 195 logger_(logger),
194 connect_timeout_(timeout), 196 connect_timeout_(timeout),
195 connect_timeout_timer_(new base::OneShotTimer<CastSocket>), 197 connect_timeout_timer_(new base::OneShotTimer<CastSocketImpl>),
196 is_canceled_(false), 198 is_canceled_(false),
197 connect_state_(CONN_STATE_NONE), 199 connect_state_(CONN_STATE_NONE),
198 write_state_(WRITE_STATE_NONE), 200 write_state_(WRITE_STATE_NONE),
199 read_state_(READ_STATE_NONE), 201 read_state_(READ_STATE_NONE),
200 error_state_(CHANNEL_ERROR_NONE), 202 error_state_(CHANNEL_ERROR_NONE),
201 ready_state_(READY_STATE_NONE) { 203 ready_state_(READY_STATE_NONE) {
202 DCHECK(net_log_); 204 DCHECK(net_log_);
203 DCHECK(channel_auth_ == CHANNEL_AUTH_TYPE_SSL || 205 DCHECK(channel_auth_ == CHANNEL_AUTH_TYPE_SSL ||
204 channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED); 206 channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED);
205 net_log_source_.type = net::NetLog::SOURCE_SOCKET; 207 net_log_source_.type = net::NetLog::SOURCE_SOCKET;
206 net_log_source_.id = net_log_->NextID(); 208 net_log_source_.id = net_log_->NextID();
207 209
208 // Buffer is reused across messages. 210 // Buffer is reused across messages.
209 read_buffer_ = new net::GrowableIOBuffer(); 211 read_buffer_ = new net::GrowableIOBuffer();
210 read_buffer_->SetCapacity(MessageFramer::MessageHeader::max_message_size()); 212 read_buffer_->SetCapacity(MessageFramer::MessageHeader::max_message_size());
211 framer_.reset(new MessageFramer(read_buffer_)); 213 framer_.reset(new MessageFramer(read_buffer_));
212 } 214 }
213 215
214 CastSocket::~CastSocket() { 216 CastSocketImpl::~CastSocketImpl() {
215 // Ensure that resources are freed but do not run pending callbacks to avoid 217 // Ensure that resources are freed but do not run pending callbacks to avoid
216 // any re-entrancy. 218 // any re-entrancy.
217 CloseInternal(); 219 CloseInternal();
218 } 220 }
219 221
220 ReadyState CastSocket::ready_state() const { 222 ReadyState CastSocketImpl::ready_state() const {
221 return ready_state_; 223 return ready_state_;
222 } 224 }
223 225
224 ChannelError CastSocket::error_state() const { 226 ChannelError CastSocketImpl::error_state() const {
225 return error_state_; 227 return error_state_;
226 } 228 }
227 229
228 scoped_ptr<net::TCPClientSocket> CastSocket::CreateTcpSocket() { 230 scoped_ptr<net::TCPClientSocket> CastSocketImpl::CreateTcpSocket() {
229 net::AddressList addresses(ip_endpoint_); 231 net::AddressList addresses(ip_endpoint_);
230 return scoped_ptr<net::TCPClientSocket>( 232 return scoped_ptr<net::TCPClientSocket>(
231 new net::TCPClientSocket(addresses, net_log_, net_log_source_)); 233 new net::TCPClientSocket(addresses, net_log_, net_log_source_));
232 // Options cannot be set on the TCPClientSocket yet, because the 234 // Options cannot be set on the TCPClientSocket yet, because the
233 // underlying platform socket will not be created until Bind() 235 // underlying platform socket will not be created until Bind()
234 // or Connect() is called. 236 // or Connect() is called.
235 } 237 }
236 238
237 scoped_ptr<net::SSLClientSocket> CastSocket::CreateSslSocket( 239 scoped_ptr<net::SSLClientSocket> CastSocketImpl::CreateSslSocket(
238 scoped_ptr<net::StreamSocket> socket) { 240 scoped_ptr<net::StreamSocket> socket) {
239 net::SSLConfig ssl_config; 241 net::SSLConfig ssl_config;
240 // If a peer cert was extracted in a previous attempt to connect, then 242 // If a peer cert was extracted in a previous attempt to connect, then
241 // whitelist that cert. 243 // whitelist that cert.
242 if (!peer_cert_.empty()) { 244 if (!peer_cert_.empty()) {
243 net::SSLConfig::CertAndStatus cert_and_status; 245 net::SSLConfig::CertAndStatus cert_and_status;
244 cert_and_status.cert_status = net::CERT_STATUS_AUTHORITY_INVALID; 246 cert_and_status.cert_status = net::CERT_STATUS_AUTHORITY_INVALID;
245 cert_and_status.der_cert = peer_cert_; 247 cert_and_status.der_cert = peer_cert_;
246 ssl_config.allowed_bad_certs.push_back(cert_and_status); 248 ssl_config.allowed_bad_certs.push_back(cert_and_status);
247 logger_->LogSocketEvent(channel_id_, proto::SSL_CERT_WHITELISTED); 249 logger_->LogSocketEvent(channel_id_, proto::SSL_CERT_WHITELISTED);
248 } 250 }
249 251
250 cert_verifier_.reset(net::CertVerifier::CreateDefault()); 252 cert_verifier_.reset(net::CertVerifier::CreateDefault());
251 transport_security_state_.reset(new net::TransportSecurityState); 253 transport_security_state_.reset(new net::TransportSecurityState);
252 net::SSLClientSocketContext context; 254 net::SSLClientSocketContext context;
253 // CertVerifier and TransportSecurityState are owned by us, not the 255 // CertVerifier and TransportSecurityState are owned by us, not the
254 // context object. 256 // context object.
255 context.cert_verifier = cert_verifier_.get(); 257 context.cert_verifier = cert_verifier_.get();
256 context.transport_security_state = transport_security_state_.get(); 258 context.transport_security_state = transport_security_state_.get();
257 259
258 scoped_ptr<net::ClientSocketHandle> connection(new net::ClientSocketHandle); 260 scoped_ptr<net::ClientSocketHandle> connection(new net::ClientSocketHandle);
259 connection->SetSocket(socket.Pass()); 261 connection->SetSocket(socket.Pass());
260 net::HostPortPair host_and_port = net::HostPortPair::FromIPEndPoint( 262 net::HostPortPair host_and_port = net::HostPortPair::FromIPEndPoint(
261 ip_endpoint_); 263 ip_endpoint_);
262 264
263 return net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket( 265 return net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket(
264 connection.Pass(), host_and_port, ssl_config, context); 266 connection.Pass(), host_and_port, ssl_config, context);
265 } 267 }
266 268
267 bool CastSocket::ExtractPeerCert(std::string* cert) { 269 bool CastSocketImpl::ExtractPeerCert(std::string* cert) {
268 DCHECK(cert); 270 DCHECK(cert);
269 DCHECK(peer_cert_.empty()); 271 DCHECK(peer_cert_.empty());
270 net::SSLInfo ssl_info; 272 net::SSLInfo ssl_info;
271 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) { 273 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) {
272 return false; 274 return false;
273 } 275 }
274 276
275 logger_->LogSocketEvent(channel_id_, proto::SSL_INFO_OBTAINED); 277 logger_->LogSocketEvent(channel_id_, proto::SSL_INFO_OBTAINED);
276 278
277 bool result = net::X509Certificate::GetDEREncoded( 279 bool result = net::X509Certificate::GetDEREncoded(
278 ssl_info.cert->os_cert_handle(), cert); 280 ssl_info.cert->os_cert_handle(), cert);
279 if (result) { 281 if (result) {
280 VLOG_WITH_CONNECTION(1) << "Successfully extracted peer certificate: " 282 VLOG_WITH_CONNECTION(1) << "Successfully extracted peer certificate: "
281 << *cert; 283 << *cert;
282 } 284 }
283 285
284 logger_->LogSocketEventWithRv( 286 logger_->LogSocketEventWithRv(
285 channel_id_, proto::DER_ENCODED_CERT_OBTAIN, result ? 1 : 0); 287 channel_id_, proto::DER_ENCODED_CERT_OBTAIN, result ? 1 : 0);
286 return result; 288 return result;
287 } 289 }
288 290
289 bool CastSocket::VerifyChallengeReply() { 291 bool CastSocketImpl::VerifyChallengeReply() {
290 AuthResult result = AuthenticateChallengeReply(*challenge_reply_, peer_cert_); 292 AuthResult result = AuthenticateChallengeReply(*challenge_reply_, peer_cert_);
291 logger_->LogSocketChallengeReplyEvent(channel_id_, result); 293 logger_->LogSocketChallengeReplyEvent(channel_id_, result);
292 return result.success(); 294 return result.success();
293 } 295 }
294 296
295 void CastSocket::Connect(const net::CompletionCallback& callback) { 297 void CastSocketImpl::Connect(const net::CompletionCallback& callback) {
296 DCHECK(CalledOnValidThread()); 298 DCHECK(CalledOnValidThread());
297 VLOG_WITH_CONNECTION(1) << "Connect readyState = " << ready_state_; 299 VLOG_WITH_CONNECTION(1) << "Connect readyState = " << ready_state_;
298 if (ready_state_ != READY_STATE_NONE) { 300 if (ready_state_ != READY_STATE_NONE) {
299 logger_->LogSocketEventWithDetails( 301 logger_->LogSocketEventWithDetails(
300 channel_id_, proto::CONNECT_FAILED, "ReadyState not NONE"); 302 channel_id_, proto::CONNECT_FAILED, "ReadyState not NONE");
301 callback.Run(net::ERR_CONNECTION_FAILED); 303 callback.Run(net::ERR_CONNECTION_FAILED);
302 return; 304 return;
303 } 305 }
304 306
305 connect_callback_ = callback; 307 connect_callback_ = callback;
306 SetReadyState(READY_STATE_CONNECTING); 308 SetReadyState(READY_STATE_CONNECTING);
307 SetConnectState(CONN_STATE_TCP_CONNECT); 309 SetConnectState(CONN_STATE_TCP_CONNECT);
308 310
309 if (connect_timeout_.InMicroseconds() > 0) { 311 if (connect_timeout_.InMicroseconds() > 0) {
310 DCHECK(connect_timeout_callback_.IsCancelled()); 312 DCHECK(connect_timeout_callback_.IsCancelled());
311 connect_timeout_callback_.Reset( 313 connect_timeout_callback_.Reset(
312 base::Bind(&CastSocket::OnConnectTimeout, base::Unretained(this))); 314 base::Bind(&CastSocketImpl::OnConnectTimeout, base::Unretained(this)));
313 GetTimer()->Start(FROM_HERE, 315 GetTimer()->Start(FROM_HERE,
314 connect_timeout_, 316 connect_timeout_,
315 connect_timeout_callback_.callback()); 317 connect_timeout_callback_.callback());
316 } 318 }
317 DoConnectLoop(net::OK); 319 DoConnectLoop(net::OK);
318 } 320 }
319 321
320 void CastSocket::PostTaskToStartConnectLoop(int result) { 322 void CastSocketImpl::PostTaskToStartConnectLoop(int result) {
321 DCHECK(CalledOnValidThread()); 323 DCHECK(CalledOnValidThread());
322 DCHECK(connect_loop_callback_.IsCancelled()); 324 DCHECK(connect_loop_callback_.IsCancelled());
323 connect_loop_callback_.Reset(base::Bind(&CastSocket::DoConnectLoop, 325 connect_loop_callback_.Reset(base::Bind(
324 base::Unretained(this), 326 &CastSocketImpl::DoConnectLoop, base::Unretained(this), result));
325 result));
326 base::MessageLoop::current()->PostTask(FROM_HERE, 327 base::MessageLoop::current()->PostTask(FROM_HERE,
327 connect_loop_callback_.callback()); 328 connect_loop_callback_.callback());
328 } 329 }
329 330
330 void CastSocket::OnConnectTimeout() { 331 void CastSocketImpl::OnConnectTimeout() {
331 DCHECK(CalledOnValidThread()); 332 DCHECK(CalledOnValidThread());
332 // Stop all pending connection setup tasks and report back to the client. 333 // Stop all pending connection setup tasks and report back to the client.
333 is_canceled_ = true; 334 is_canceled_ = true;
334 logger_->LogSocketEvent(channel_id_, proto::CONNECT_TIMED_OUT); 335 logger_->LogSocketEvent(channel_id_, proto::CONNECT_TIMED_OUT);
335 VLOG_WITH_CONNECTION(1) << "Timeout while establishing a connection."; 336 VLOG_WITH_CONNECTION(1) << "Timeout while establishing a connection.";
336 DoConnectCallback(net::ERR_TIMED_OUT); 337 DoConnectCallback(net::ERR_TIMED_OUT);
337 } 338 }
338 339
339 // This method performs the state machine transitions for connection flow. 340 // This method performs the state machine transitions for connection flow.
340 // There are two entry points to this method: 341 // There are two entry points to this method:
341 // 1. Connect method: this starts the flow 342 // 1. Connect method: this starts the flow
342 // 2. Callback from network operations that finish asynchronously 343 // 2. Callback from network operations that finish asynchronously
343 void CastSocket::DoConnectLoop(int result) { 344 void CastSocketImpl::DoConnectLoop(int result) {
344 connect_loop_callback_.Cancel(); 345 connect_loop_callback_.Cancel();
345 if (is_canceled_) { 346 if (is_canceled_) {
346 LOG(ERROR) << "CANCELLED - Aborting DoConnectLoop."; 347 LOG(ERROR) << "CANCELLED - Aborting DoConnectLoop.";
347 return; 348 return;
348 } 349 }
349 // Network operations can either finish synchronously or asynchronously. 350 // Network operations can either finish synchronously or asynchronously.
350 // This method executes the state machine transitions in a loop so that 351 // This method executes the state machine transitions in a loop so that
351 // correct state transitions happen even when network operations finish 352 // correct state transitions happen even when network operations finish
352 // synchronously. 353 // synchronously.
353 int rv = result; 354 int rv = result;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 ConnectStateToProto(connect_state_)); 396 ConnectStateToProto(connect_state_));
396 } 397 }
397 398
398 // Connect loop is finished: if there is no pending IO invoke the callback. 399 // Connect loop is finished: if there is no pending IO invoke the callback.
399 if (rv != net::ERR_IO_PENDING) { 400 if (rv != net::ERR_IO_PENDING) {
400 GetTimer()->Stop(); 401 GetTimer()->Stop();
401 DoConnectCallback(rv); 402 DoConnectCallback(rv);
402 } 403 }
403 } 404 }
404 405
405 int CastSocket::DoTcpConnect() { 406 int CastSocketImpl::DoTcpConnect() {
406 DCHECK(connect_loop_callback_.IsCancelled()); 407 DCHECK(connect_loop_callback_.IsCancelled());
407 VLOG_WITH_CONNECTION(1) << "DoTcpConnect"; 408 VLOG_WITH_CONNECTION(1) << "DoTcpConnect";
408 SetConnectState(CONN_STATE_TCP_CONNECT_COMPLETE); 409 SetConnectState(CONN_STATE_TCP_CONNECT_COMPLETE);
409 tcp_socket_ = CreateTcpSocket(); 410 tcp_socket_ = CreateTcpSocket();
410 411
411 int rv = tcp_socket_->Connect( 412 int rv = tcp_socket_->Connect(
412 base::Bind(&CastSocket::DoConnectLoop, base::Unretained(this))); 413 base::Bind(&CastSocketImpl::DoConnectLoop, base::Unretained(this)));
413 logger_->LogSocketEventWithRv(channel_id_, proto::TCP_SOCKET_CONNECT, rv); 414 logger_->LogSocketEventWithRv(channel_id_, proto::TCP_SOCKET_CONNECT, rv);
414 return rv; 415 return rv;
415 } 416 }
416 417
417 int CastSocket::DoTcpConnectComplete(int result) { 418 int CastSocketImpl::DoTcpConnectComplete(int result) {
418 VLOG_WITH_CONNECTION(1) << "DoTcpConnectComplete: " << result; 419 VLOG_WITH_CONNECTION(1) << "DoTcpConnectComplete: " << result;
419 if (result == net::OK) { 420 if (result == net::OK) {
420 // Enable TCP protocol-level keep-alive. 421 // Enable TCP protocol-level keep-alive.
421 bool result = tcp_socket_->SetKeepAlive(true, kTcpKeepAliveDelaySecs); 422 bool result = tcp_socket_->SetKeepAlive(true, kTcpKeepAliveDelaySecs);
422 LOG_IF(WARNING, !result) << "Failed to SetKeepAlive."; 423 LOG_IF(WARNING, !result) << "Failed to SetKeepAlive.";
423 logger_->LogSocketEventWithRv( 424 logger_->LogSocketEventWithRv(
424 channel_id_, proto::TCP_SOCKET_SET_KEEP_ALIVE, result ? 1 : 0); 425 channel_id_, proto::TCP_SOCKET_SET_KEEP_ALIVE, result ? 1 : 0);
425 SetConnectState(CONN_STATE_SSL_CONNECT); 426 SetConnectState(CONN_STATE_SSL_CONNECT);
426 } 427 }
427 return result; 428 return result;
428 } 429 }
429 430
430 int CastSocket::DoSslConnect() { 431 int CastSocketImpl::DoSslConnect() {
431 DCHECK(connect_loop_callback_.IsCancelled()); 432 DCHECK(connect_loop_callback_.IsCancelled());
432 VLOG_WITH_CONNECTION(1) << "DoSslConnect"; 433 VLOG_WITH_CONNECTION(1) << "DoSslConnect";
433 SetConnectState(CONN_STATE_SSL_CONNECT_COMPLETE); 434 SetConnectState(CONN_STATE_SSL_CONNECT_COMPLETE);
434 socket_ = CreateSslSocket(tcp_socket_.PassAs<net::StreamSocket>()); 435 socket_ = CreateSslSocket(tcp_socket_.PassAs<net::StreamSocket>());
435 436
436 int rv = socket_->Connect( 437 int rv = socket_->Connect(
437 base::Bind(&CastSocket::DoConnectLoop, base::Unretained(this))); 438 base::Bind(&CastSocketImpl::DoConnectLoop, base::Unretained(this)));
438 logger_->LogSocketEventWithRv(channel_id_, proto::SSL_SOCKET_CONNECT, rv); 439 logger_->LogSocketEventWithRv(channel_id_, proto::SSL_SOCKET_CONNECT, rv);
439 return rv; 440 return rv;
440 } 441 }
441 442
442 int CastSocket::DoSslConnectComplete(int result) { 443 int CastSocketImpl::DoSslConnectComplete(int result) {
443 VLOG_WITH_CONNECTION(1) << "DoSslConnectComplete: " << result; 444 VLOG_WITH_CONNECTION(1) << "DoSslConnectComplete: " << result;
444 if (result == net::ERR_CERT_AUTHORITY_INVALID && 445 if (result == net::ERR_CERT_AUTHORITY_INVALID &&
445 peer_cert_.empty() && ExtractPeerCert(&peer_cert_)) { 446 peer_cert_.empty() && ExtractPeerCert(&peer_cert_)) {
446 SetConnectState(CONN_STATE_TCP_CONNECT); 447 SetConnectState(CONN_STATE_TCP_CONNECT);
447 } else if (result == net::OK && 448 } else if (result == net::OK &&
448 channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED) { 449 channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED) {
449 SetConnectState(CONN_STATE_AUTH_CHALLENGE_SEND); 450 SetConnectState(CONN_STATE_AUTH_CHALLENGE_SEND);
450 } 451 }
451 return result; 452 return result;
452 } 453 }
453 454
454 int CastSocket::DoAuthChallengeSend() { 455 int CastSocketImpl::DoAuthChallengeSend() {
455 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeSend"; 456 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeSend";
456 SetConnectState(CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE); 457 SetConnectState(CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE);
457 458
458 CastMessage challenge_message; 459 CastMessage challenge_message;
459 CreateAuthChallengeMessage(&challenge_message); 460 CreateAuthChallengeMessage(&challenge_message);
460 VLOG_WITH_CONNECTION(1) << "Sending challenge: " 461 VLOG_WITH_CONNECTION(1) << "Sending challenge: "
461 << CastMessageToString(challenge_message); 462 << CastMessageToString(challenge_message);
462 // Post a task to send auth challenge so that DoWriteLoop is not nested inside 463 // Post a task to send auth challenge so that DoWriteLoop is not nested inside
463 // DoConnectLoop. This is not strictly necessary but keeps the write loop 464 // DoConnectLoop. This is not strictly necessary but keeps the write loop
464 // code decoupled from connect loop code. 465 // code decoupled from connect loop code.
465 DCHECK(send_auth_challenge_callback_.IsCancelled()); 466 DCHECK(send_auth_challenge_callback_.IsCancelled());
466 send_auth_challenge_callback_.Reset( 467 send_auth_challenge_callback_.Reset(
467 base::Bind(&CastSocket::SendCastMessageInternal, 468 base::Bind(&CastSocketImpl::SendCastMessageInternal,
468 base::Unretained(this), 469 base::Unretained(this),
469 challenge_message, 470 challenge_message,
470 base::Bind(&CastSocket::DoAuthChallengeSendWriteComplete, 471 base::Bind(&CastSocketImpl::DoAuthChallengeSendWriteComplete,
471 base::Unretained(this)))); 472 base::Unretained(this))));
472 base::MessageLoop::current()->PostTask( 473 base::MessageLoop::current()->PostTask(
473 FROM_HERE, 474 FROM_HERE,
474 send_auth_challenge_callback_.callback()); 475 send_auth_challenge_callback_.callback());
475 // Always return IO_PENDING since the result is always asynchronous. 476 // Always return IO_PENDING since the result is always asynchronous.
476 return net::ERR_IO_PENDING; 477 return net::ERR_IO_PENDING;
477 } 478 }
478 479
479 void CastSocket::DoAuthChallengeSendWriteComplete(int result) { 480 void CastSocketImpl::DoAuthChallengeSendWriteComplete(int result) {
480 send_auth_challenge_callback_.Cancel(); 481 send_auth_challenge_callback_.Cancel();
481 VLOG_WITH_CONNECTION(2) << "DoAuthChallengeSendWriteComplete: " << result; 482 VLOG_WITH_CONNECTION(2) << "DoAuthChallengeSendWriteComplete: " << result;
482 DCHECK_GT(result, 0); 483 DCHECK_GT(result, 0);
483 DCHECK_EQ(write_queue_.size(), 1UL); 484 DCHECK_EQ(write_queue_.size(), 1UL);
484 PostTaskToStartConnectLoop(result); 485 PostTaskToStartConnectLoop(result);
485 } 486 }
486 487
487 int CastSocket::DoAuthChallengeSendComplete(int result) { 488 int CastSocketImpl::DoAuthChallengeSendComplete(int result) {
488 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeSendComplete: " << result; 489 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeSendComplete: " << result;
489 if (result < 0) { 490 if (result < 0) {
490 return result; 491 return result;
491 } 492 }
492 SetConnectState(CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE); 493 SetConnectState(CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE);
493 494
494 // Post a task to start read loop so that DoReadLoop is not nested inside 495 // Post a task to start read loop so that DoReadLoop is not nested inside
495 // DoConnectLoop. This is not strictly necessary but keeps the read loop 496 // DoConnectLoop. This is not strictly necessary but keeps the read loop
496 // code decoupled from connect loop code. 497 // code decoupled from connect loop code.
497 PostTaskToStartReadLoop(); 498 PostTaskToStartReadLoop();
498 // Always return IO_PENDING since the result is always asynchronous. 499 // Always return IO_PENDING since the result is always asynchronous.
499 return net::ERR_IO_PENDING; 500 return net::ERR_IO_PENDING;
500 } 501 }
501 502
502 int CastSocket::DoAuthChallengeReplyComplete(int result) { 503 int CastSocketImpl::DoAuthChallengeReplyComplete(int result) {
503 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeReplyComplete: " << result; 504 VLOG_WITH_CONNECTION(1) << "DoAuthChallengeReplyComplete: " << result;
504 if (result < 0) { 505 if (result < 0) {
505 return result; 506 return result;
506 } 507 }
507 if (!VerifyChallengeReply()) { 508 if (!VerifyChallengeReply()) {
508 return net::ERR_FAILED; 509 return net::ERR_FAILED;
509 } 510 }
510 VLOG_WITH_CONNECTION(1) << "Auth challenge verification succeeded"; 511 VLOG_WITH_CONNECTION(1) << "Auth challenge verification succeeded";
511 return net::OK; 512 return net::OK;
512 } 513 }
513 514
514 void CastSocket::DoConnectCallback(int result) { 515 void CastSocketImpl::DoConnectCallback(int result) {
515 SetReadyState((result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED); 516 SetReadyState((result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED);
516 if (result == net::OK) { 517 if (result == net::OK) {
517 SetErrorState(CHANNEL_ERROR_NONE); 518 SetErrorState(CHANNEL_ERROR_NONE);
518 PostTaskToStartReadLoop(); 519 PostTaskToStartReadLoop();
519 VLOG_WITH_CONNECTION(1) << "Calling Connect_Callback"; 520 VLOG_WITH_CONNECTION(1) << "Calling Connect_Callback";
520 base::ResetAndReturn(&connect_callback_).Run(result); 521 base::ResetAndReturn(&connect_callback_).Run(result);
521 return; 522 return;
522 } else if (result == net::ERR_TIMED_OUT) { 523 } else if (result == net::ERR_TIMED_OUT) {
523 SetErrorState(CHANNEL_ERROR_CONNECT_TIMEOUT); 524 SetErrorState(CHANNEL_ERROR_CONNECT_TIMEOUT);
524 } else { 525 } else {
525 SetErrorState(CHANNEL_ERROR_CONNECT_ERROR); 526 SetErrorState(CHANNEL_ERROR_CONNECT_ERROR);
526 } 527 }
527 // Calls the connect callback. 528 // Calls the connect callback.
528 CloseWithError(); 529 CloseWithError();
529 } 530 }
530 531
531 void CastSocket::Close(const net::CompletionCallback& callback) { 532 void CastSocketImpl::Close(const net::CompletionCallback& callback) {
532 CloseInternal(); 533 CloseInternal();
533 RunPendingCallbacksOnClose(); 534 RunPendingCallbacksOnClose();
534 // Run this callback last. It may delete the socket. 535 // Run this callback last. It may delete the socket.
535 callback.Run(net::OK); 536 callback.Run(net::OK);
536 } 537 }
537 538
538 void CastSocket::CloseInternal() { 539 void CastSocketImpl::CloseInternal() {
539 // TODO(mfoltz): Enforce this when CastChannelAPITest is rewritten to create 540 // TODO(mfoltz): Enforce this when CastChannelAPITest is rewritten to create
540 // and free sockets on the same thread. crbug.com/398242 541 // and free sockets on the same thread. crbug.com/398242
541 // DCHECK(CalledOnValidThread()); 542 // DCHECK(CalledOnValidThread());
542 if (ready_state_ == READY_STATE_CLOSED) { 543 if (ready_state_ == READY_STATE_CLOSED) {
543 return; 544 return;
544 } 545 }
545 546
546 VLOG_WITH_CONNECTION(1) << "Close ReadyState = " << ready_state_; 547 VLOG_WITH_CONNECTION(1) << "Close ReadyState = " << ready_state_;
547 tcp_socket_.reset(); 548 tcp_socket_.reset();
548 socket_.reset(); 549 socket_.reset();
549 cert_verifier_.reset(); 550 cert_verifier_.reset();
550 transport_security_state_.reset(); 551 transport_security_state_.reset();
551 GetTimer()->Stop(); 552 GetTimer()->Stop();
552 553
553 // Cancel callbacks that we queued ourselves to re-enter the connect or read 554 // Cancel callbacks that we queued ourselves to re-enter the connect or read
554 // loops. 555 // loops.
555 connect_loop_callback_.Cancel(); 556 connect_loop_callback_.Cancel();
556 send_auth_challenge_callback_.Cancel(); 557 send_auth_challenge_callback_.Cancel();
557 read_loop_callback_.Cancel(); 558 read_loop_callback_.Cancel();
558 connect_timeout_callback_.Cancel(); 559 connect_timeout_callback_.Cancel();
559 SetReadyState(READY_STATE_CLOSED); 560 SetReadyState(READY_STATE_CLOSED);
560 logger_->LogSocketEvent(channel_id_, proto::SOCKET_CLOSED); 561 logger_->LogSocketEvent(channel_id_, proto::SOCKET_CLOSED);
561 } 562 }
562 563
563 void CastSocket::RunPendingCallbacksOnClose() { 564 void CastSocketImpl::RunPendingCallbacksOnClose() {
564 DCHECK_EQ(ready_state_, READY_STATE_CLOSED); 565 DCHECK_EQ(ready_state_, READY_STATE_CLOSED);
565 if (!connect_callback_.is_null()) { 566 if (!connect_callback_.is_null()) {
566 connect_callback_.Run(net::ERR_CONNECTION_FAILED); 567 connect_callback_.Run(net::ERR_CONNECTION_FAILED);
567 connect_callback_.Reset(); 568 connect_callback_.Reset();
568 } 569 }
569 for (; !write_queue_.empty(); write_queue_.pop()) { 570 for (; !write_queue_.empty(); write_queue_.pop()) {
570 net::CompletionCallback& callback = write_queue_.front().callback; 571 net::CompletionCallback& callback = write_queue_.front().callback;
571 callback.Run(net::ERR_FAILED); 572 callback.Run(net::ERR_FAILED);
572 callback.Reset(); 573 callback.Reset();
573 } 574 }
574 } 575 }
575 576
576 void CastSocket::SendMessage(const MessageInfo& message, 577 void CastSocketImpl::SendMessage(const MessageInfo& message,
577 const net::CompletionCallback& callback) { 578 const net::CompletionCallback& callback) {
578 DCHECK(CalledOnValidThread()); 579 DCHECK(CalledOnValidThread());
579 if (ready_state_ != READY_STATE_OPEN) { 580 if (ready_state_ != READY_STATE_OPEN) {
580 logger_->LogSocketEventForMessage(channel_id_, 581 logger_->LogSocketEventForMessage(channel_id_,
581 proto::SEND_MESSAGE_FAILED, 582 proto::SEND_MESSAGE_FAILED,
582 message.namespace_, 583 message.namespace_,
583 "Ready state not OPEN"); 584 "Ready state not OPEN");
584 callback.Run(net::ERR_FAILED); 585 callback.Run(net::ERR_FAILED);
585 return; 586 return;
586 } 587 }
587 CastMessage message_proto; 588 CastMessage message_proto;
588 if (!MessageInfoToCastMessage(message, &message_proto)) { 589 if (!MessageInfoToCastMessage(message, &message_proto)) {
589 logger_->LogSocketEventForMessage(channel_id_, 590 logger_->LogSocketEventForMessage(channel_id_,
590 proto::SEND_MESSAGE_FAILED, 591 proto::SEND_MESSAGE_FAILED,
591 message.namespace_, 592 message.namespace_,
592 "Failed to convert to CastMessage"); 593 "Failed to convert to CastMessage");
593 callback.Run(net::ERR_FAILED); 594 callback.Run(net::ERR_FAILED);
594 return; 595 return;
595 } 596 }
596 SendCastMessageInternal(message_proto, callback); 597 SendCastMessageInternal(message_proto, callback);
597 } 598 }
598 599
599 void CastSocket::SendCastMessageInternal( 600 void CastSocketImpl::SendCastMessageInternal(
600 const CastMessage& message, 601 const CastMessage& message,
601 const net::CompletionCallback& callback) { 602 const net::CompletionCallback& callback) {
602 WriteRequest write_request(callback); 603 WriteRequest write_request(callback);
603 if (!write_request.SetContent(message)) { 604 if (!write_request.SetContent(message)) {
604 logger_->LogSocketEventForMessage(channel_id_, 605 logger_->LogSocketEventForMessage(channel_id_,
605 proto::SEND_MESSAGE_FAILED, 606 proto::SEND_MESSAGE_FAILED,
606 message.namespace_(), 607 message.namespace_(),
607 "SetContent failed"); 608 "SetContent failed");
608 callback.Run(net::ERR_FAILED); 609 callback.Run(net::ERR_FAILED);
609 return; 610 return;
610 } 611 }
611 612
612 write_queue_.push(write_request); 613 write_queue_.push(write_request);
613 logger_->LogSocketEventForMessage( 614 logger_->LogSocketEventForMessage(
614 channel_id_, 615 channel_id_,
615 proto::MESSAGE_ENQUEUED, 616 proto::MESSAGE_ENQUEUED,
616 message.namespace_(), 617 message.namespace_(),
617 base::StringPrintf("Queue size: %" PRIuS, write_queue_.size())); 618 base::StringPrintf("Queue size: %" PRIuS, write_queue_.size()));
618 if (write_state_ == WRITE_STATE_NONE) { 619 if (write_state_ == WRITE_STATE_NONE) {
619 SetWriteState(WRITE_STATE_WRITE); 620 SetWriteState(WRITE_STATE_WRITE);
620 DoWriteLoop(net::OK); 621 DoWriteLoop(net::OK);
621 } 622 }
622 } 623 }
623 624
624 void CastSocket::DoWriteLoop(int result) { 625 void CastSocketImpl::DoWriteLoop(int result) {
625 DCHECK(CalledOnValidThread()); 626 DCHECK(CalledOnValidThread());
626 VLOG_WITH_CONNECTION(1) << "DoWriteLoop queue size: " << write_queue_.size(); 627 VLOG_WITH_CONNECTION(1) << "DoWriteLoop queue size: " << write_queue_.size();
627 628
628 if (write_queue_.empty()) { 629 if (write_queue_.empty()) {
629 SetWriteState(WRITE_STATE_NONE); 630 SetWriteState(WRITE_STATE_NONE);
630 return; 631 return;
631 } 632 }
632 633
633 // Network operations can either finish synchronously or asynchronously. 634 // Network operations can either finish synchronously or asynchronously.
634 // This method executes the state machine transitions in a loop so that 635 // This method executes the state machine transitions in a loop so that
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 if (write_queue_.empty()) { 671 if (write_queue_.empty()) {
671 SetWriteState(WRITE_STATE_NONE); 672 SetWriteState(WRITE_STATE_NONE);
672 } 673 }
673 674
674 // Write loop is done - if the result is ERR_FAILED then close with error. 675 // Write loop is done - if the result is ERR_FAILED then close with error.
675 if (rv == net::ERR_FAILED) { 676 if (rv == net::ERR_FAILED) {
676 CloseWithError(); 677 CloseWithError();
677 } 678 }
678 } 679 }
679 680
680 int CastSocket::DoWrite() { 681 int CastSocketImpl::DoWrite() {
681 DCHECK(!write_queue_.empty()); 682 DCHECK(!write_queue_.empty());
682 WriteRequest& request = write_queue_.front(); 683 WriteRequest& request = write_queue_.front();
683 684
684 VLOG_WITH_CONNECTION(2) << "WriteData byte_count = " 685 VLOG_WITH_CONNECTION(2) << "WriteData byte_count = "
685 << request.io_buffer->size() << " bytes_written " 686 << request.io_buffer->size() << " bytes_written "
686 << request.io_buffer->BytesConsumed(); 687 << request.io_buffer->BytesConsumed();
687 688
688 SetWriteState(WRITE_STATE_WRITE_COMPLETE); 689 SetWriteState(WRITE_STATE_WRITE_COMPLETE);
689 690
690 int rv = socket_->Write( 691 int rv = socket_->Write(
691 request.io_buffer.get(), 692 request.io_buffer.get(),
692 request.io_buffer->BytesRemaining(), 693 request.io_buffer->BytesRemaining(),
693 base::Bind(&CastSocket::DoWriteLoop, base::Unretained(this))); 694 base::Bind(&CastSocketImpl::DoWriteLoop, base::Unretained(this)));
694 logger_->LogSocketEventWithRv(channel_id_, proto::SOCKET_WRITE, rv); 695 logger_->LogSocketEventWithRv(channel_id_, proto::SOCKET_WRITE, rv);
695 696
696 return rv; 697 return rv;
697 } 698 }
698 699
699 int CastSocket::DoWriteComplete(int result) { 700 int CastSocketImpl::DoWriteComplete(int result) {
700 DCHECK(!write_queue_.empty()); 701 DCHECK(!write_queue_.empty());
701 if (result <= 0) { // NOTE that 0 also indicates an error 702 if (result <= 0) { // NOTE that 0 also indicates an error
702 SetErrorState(CHANNEL_ERROR_SOCKET_ERROR); 703 SetErrorState(CHANNEL_ERROR_SOCKET_ERROR);
703 SetWriteState(WRITE_STATE_ERROR); 704 SetWriteState(WRITE_STATE_ERROR);
704 return result == 0 ? net::ERR_FAILED : result; 705 return result == 0 ? net::ERR_FAILED : result;
705 } 706 }
706 707
707 // Some bytes were successfully written 708 // Some bytes were successfully written
708 WriteRequest& request = write_queue_.front(); 709 WriteRequest& request = write_queue_.front();
709 scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer; 710 scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer;
710 io_buffer->DidConsume(result); 711 io_buffer->DidConsume(result);
711 if (io_buffer->BytesRemaining() == 0) { // Message fully sent 712 if (io_buffer->BytesRemaining() == 0) { // Message fully sent
712 SetWriteState(WRITE_STATE_DO_CALLBACK); 713 SetWriteState(WRITE_STATE_DO_CALLBACK);
713 } else { 714 } else {
714 SetWriteState(WRITE_STATE_WRITE); 715 SetWriteState(WRITE_STATE_WRITE);
715 } 716 }
716 717
717 return net::OK; 718 return net::OK;
718 } 719 }
719 720
720 int CastSocket::DoWriteCallback() { 721 int CastSocketImpl::DoWriteCallback() {
721 DCHECK(!write_queue_.empty()); 722 DCHECK(!write_queue_.empty());
722 723
723 SetWriteState(WRITE_STATE_WRITE); 724 SetWriteState(WRITE_STATE_WRITE);
724 725
725 WriteRequest& request = write_queue_.front(); 726 WriteRequest& request = write_queue_.front();
726 int bytes_consumed = request.io_buffer->BytesConsumed(); 727 int bytes_consumed = request.io_buffer->BytesConsumed();
727 logger_->LogSocketEventForMessage( 728 logger_->LogSocketEventForMessage(
728 channel_id_, 729 channel_id_,
729 proto::MESSAGE_WRITTEN, 730 proto::MESSAGE_WRITTEN,
730 request.message_namespace, 731 request.message_namespace,
731 base::StringPrintf("Bytes: %d", bytes_consumed)); 732 base::StringPrintf("Bytes: %d", bytes_consumed));
732 request.callback.Run(bytes_consumed); 733 request.callback.Run(bytes_consumed);
733 write_queue_.pop(); 734 write_queue_.pop();
734 return net::OK; 735 return net::OK;
735 } 736 }
736 737
737 int CastSocket::DoWriteError(int result) { 738 int CastSocketImpl::DoWriteError(int result) {
738 DCHECK(!write_queue_.empty()); 739 DCHECK(!write_queue_.empty());
739 DCHECK_LT(result, 0); 740 DCHECK_LT(result, 0);
740 741
741 // If inside connection flow, then there should be exactly one item in 742 // If inside connection flow, then there should be exactly one item in
742 // the write queue. 743 // the write queue.
743 if (ready_state_ == READY_STATE_CONNECTING) { 744 if (ready_state_ == READY_STATE_CONNECTING) {
744 write_queue_.pop(); 745 write_queue_.pop();
745 DCHECK(write_queue_.empty()); 746 DCHECK(write_queue_.empty());
746 PostTaskToStartConnectLoop(result); 747 PostTaskToStartConnectLoop(result);
747 // Connect loop will handle the error. Return net::OK so that write flow 748 // Connect loop will handle the error. Return net::OK so that write flow
748 // does not try to report error also. 749 // does not try to report error also.
749 return net::OK; 750 return net::OK;
750 } 751 }
751 752
752 while (!write_queue_.empty()) { 753 while (!write_queue_.empty()) {
753 WriteRequest& request = write_queue_.front(); 754 WriteRequest& request = write_queue_.front();
754 request.callback.Run(result); 755 request.callback.Run(result);
755 write_queue_.pop(); 756 write_queue_.pop();
756 } 757 }
757 return net::ERR_FAILED; 758 return net::ERR_FAILED;
758 } 759 }
759 760
760 void CastSocket::PostTaskToStartReadLoop() { 761 void CastSocketImpl::PostTaskToStartReadLoop() {
761 DCHECK(CalledOnValidThread()); 762 DCHECK(CalledOnValidThread());
762 DCHECK(read_loop_callback_.IsCancelled()); 763 DCHECK(read_loop_callback_.IsCancelled());
763 read_loop_callback_.Reset(base::Bind(&CastSocket::StartReadLoop, 764 read_loop_callback_.Reset(
764 base::Unretained(this))); 765 base::Bind(&CastSocketImpl::StartReadLoop, base::Unretained(this)));
765 base::MessageLoop::current()->PostTask(FROM_HERE, 766 base::MessageLoop::current()->PostTask(FROM_HERE,
766 read_loop_callback_.callback()); 767 read_loop_callback_.callback());
767 } 768 }
768 769
769 void CastSocket::StartReadLoop() { 770 void CastSocketImpl::StartReadLoop() {
770 read_loop_callback_.Cancel(); 771 read_loop_callback_.Cancel();
771 // Read loop would have already been started if read state is not NONE 772 // Read loop would have already been started if read state is not NONE
772 if (read_state_ == READ_STATE_NONE) { 773 if (read_state_ == READ_STATE_NONE) {
773 SetReadState(READ_STATE_READ); 774 SetReadState(READ_STATE_READ);
774 DoReadLoop(net::OK); 775 DoReadLoop(net::OK);
775 } 776 }
776 } 777 }
777 778
778 void CastSocket::DoReadLoop(int result) { 779 void CastSocketImpl::DoReadLoop(int result) {
779 DCHECK(CalledOnValidThread()); 780 DCHECK(CalledOnValidThread());
780 // Network operations can either finish synchronously or asynchronously. 781 // Network operations can either finish synchronously or asynchronously.
781 // This method executes the state machine transitions in a loop so that 782 // This method executes the state machine transitions in a loop so that
782 // write state transitions happen even when network operations finish 783 // write state transitions happen even when network operations finish
783 // synchronously. 784 // synchronously.
784 int rv = result; 785 int rv = result;
785 do { 786 do {
786 ReadState state = read_state_; 787 ReadState state = read_state_;
787 read_state_ = READ_STATE_NONE; 788 read_state_ = READ_STATE_NONE;
788 789
(...skipping 30 matching lines...) Expand all
819 // delegate. 820 // delegate.
820 PostTaskToStartConnectLoop(net::ERR_FAILED); 821 PostTaskToStartConnectLoop(net::ERR_FAILED);
821 } else { 822 } else {
822 // Connection is already established. Close and send error status via the 823 // Connection is already established. Close and send error status via the
823 // OnError delegate. 824 // OnError delegate.
824 CloseWithError(); 825 CloseWithError();
825 } 826 }
826 } 827 }
827 } 828 }
828 829
829 int CastSocket::DoRead() { 830 int CastSocketImpl::DoRead() {
830 SetReadState(READ_STATE_READ_COMPLETE); 831 SetReadState(READ_STATE_READ_COMPLETE);
831 832
832 // Determine how many bytes need to be read. 833 // Determine how many bytes need to be read.
833 size_t num_bytes_to_read = framer_->BytesRequested(); 834 size_t num_bytes_to_read = framer_->BytesRequested();
834 835
835 // Read up to num_bytes_to_read into |current_read_buffer_|. 836 // Read up to num_bytes_to_read into |current_read_buffer_|.
836 int rv = socket_->Read( 837 int rv = socket_->Read(
837 read_buffer_.get(), 838 read_buffer_.get(),
838 base::checked_cast<uint32>(num_bytes_to_read), 839 base::checked_cast<uint32>(num_bytes_to_read),
839 base::Bind(&CastSocket::DoReadLoop, base::Unretained(this))); 840 base::Bind(&CastSocketImpl::DoReadLoop, base::Unretained(this)));
840 logger_->LogSocketEventWithRv(channel_id_, proto::SOCKET_READ, rv); 841 logger_->LogSocketEventWithRv(channel_id_, proto::SOCKET_READ, rv);
841 842
842 return rv; 843 return rv;
843 } 844 }
844 845
845 int CastSocket::DoReadComplete(int result) { 846 int CastSocketImpl::DoReadComplete(int result) {
846 VLOG_WITH_CONNECTION(2) << "DoReadComplete result = " << result; 847 VLOG_WITH_CONNECTION(2) << "DoReadComplete result = " << result;
847 848
848 if (result <= 0) { // 0 means EOF: the peer closed the socket 849 if (result <= 0) { // 0 means EOF: the peer closed the socket
849 VLOG_WITH_CONNECTION(1) << "Read error, peer closed the socket"; 850 VLOG_WITH_CONNECTION(1) << "Read error, peer closed the socket";
850 SetErrorState(CHANNEL_ERROR_SOCKET_ERROR); 851 SetErrorState(CHANNEL_ERROR_SOCKET_ERROR);
851 SetReadState(READ_STATE_ERROR); 852 SetReadState(READ_STATE_ERROR);
852 return result == 0 ? net::ERR_FAILED : result; 853 return result == 0 ? net::ERR_FAILED : result;
853 } 854 }
854 855
855 size_t message_size; 856 size_t message_size;
(...skipping 12 matching lines...) Expand all
868 } else if (error_state_ != CHANNEL_ERROR_NONE) { 869 } else if (error_state_ != CHANNEL_ERROR_NONE) {
869 DCHECK(current_message_.get() == NULL); 870 DCHECK(current_message_.get() == NULL);
870 SetReadState(READ_STATE_ERROR); 871 SetReadState(READ_STATE_ERROR);
871 } else { 872 } else {
872 DCHECK(current_message_.get() == NULL); 873 DCHECK(current_message_.get() == NULL);
873 SetReadState(READ_STATE_READ); 874 SetReadState(READ_STATE_READ);
874 } 875 }
875 return net::OK; 876 return net::OK;
876 } 877 }
877 878
878 int CastSocket::DoReadCallback() { 879 int CastSocketImpl::DoReadCallback() {
879 SetReadState(READ_STATE_READ); 880 SetReadState(READ_STATE_READ);
880 const CastMessage& message = *current_message_; 881 const CastMessage& message = *current_message_;
881 if (ready_state_ == READY_STATE_CONNECTING) { 882 if (ready_state_ == READY_STATE_CONNECTING) {
882 if (IsAuthMessage(message)) { 883 if (IsAuthMessage(message)) {
883 challenge_reply_.reset(new CastMessage(message)); 884 challenge_reply_.reset(new CastMessage(message));
884 logger_->LogSocketEvent(channel_id_, proto::RECEIVED_CHALLENGE_REPLY); 885 logger_->LogSocketEvent(channel_id_, proto::RECEIVED_CHALLENGE_REPLY);
885 PostTaskToStartConnectLoop(net::OK); 886 PostTaskToStartConnectLoop(net::OK);
886 current_message_.reset(); 887 current_message_.reset();
887 return net::OK; 888 return net::OK;
888 } else { 889 } else {
(...skipping 15 matching lines...) Expand all
904 logger_->LogSocketEventForMessage(channel_id_, 905 logger_->LogSocketEventForMessage(channel_id_,
905 proto::NOTIFY_ON_MESSAGE, 906 proto::NOTIFY_ON_MESSAGE,
906 message.namespace_(), 907 message.namespace_(),
907 std::string()); 908 std::string());
908 delegate_->OnMessage(this, message_info); 909 delegate_->OnMessage(this, message_info);
909 current_message_.reset(); 910 current_message_.reset();
910 911
911 return net::OK; 912 return net::OK;
912 } 913 }
913 914
914 int CastSocket::DoReadError(int result) { 915 int CastSocketImpl::DoReadError(int result) {
915 DCHECK_LE(result, 0); 916 DCHECK_LE(result, 0);
916 return net::ERR_FAILED; 917 return net::ERR_FAILED;
917 } 918 }
918 919
919 void CastSocket::CloseWithError() { 920 void CastSocketImpl::CloseWithError() {
920 DCHECK(CalledOnValidThread()); 921 DCHECK(CalledOnValidThread());
921 CloseInternal(); 922 CloseInternal();
922 RunPendingCallbacksOnClose(); 923 RunPendingCallbacksOnClose();
923 if (delegate_) { 924 if (delegate_) {
924 logger_->LogSocketEvent(channel_id_, proto::NOTIFY_ON_ERROR); 925 logger_->LogSocketEvent(channel_id_, proto::NOTIFY_ON_ERROR);
925 delegate_->OnError(this, error_state_, logger_->GetLastErrors(channel_id_)); 926 delegate_->OnError(this, error_state_, logger_->GetLastErrors(channel_id_));
926 } 927 }
927 } 928 }
928 929
929 std::string CastSocket::CastUrl() const { 930 std::string CastSocketImpl::CastUrl() const {
930 return ((channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED) ? 931 return ((channel_auth_ == CHANNEL_AUTH_TYPE_SSL_VERIFIED) ?
931 "casts://" : "cast://") + ip_endpoint_.ToString(); 932 "casts://" : "cast://") + ip_endpoint_.ToString();
932 } 933 }
933 934
934 bool CastSocket::CalledOnValidThread() const { 935 bool CastSocketImpl::CalledOnValidThread() const {
935 return thread_checker_.CalledOnValidThread(); 936 return thread_checker_.CalledOnValidThread();
936 } 937 }
937 938
938 base::Timer* CastSocket::GetTimer() { 939 base::Timer* CastSocketImpl::GetTimer() {
939 return connect_timeout_timer_.get(); 940 return connect_timeout_timer_.get();
940 } 941 }
941 942
942 void CastSocket::SetConnectState(ConnectionState connect_state) { 943 void CastSocketImpl::SetConnectState(ConnectionState connect_state) {
943 if (connect_state_ != connect_state) { 944 if (connect_state_ != connect_state) {
944 connect_state_ = connect_state; 945 connect_state_ = connect_state;
945 logger_->LogSocketConnectState(channel_id_, 946 logger_->LogSocketConnectState(channel_id_,
946 ConnectStateToProto(connect_state_)); 947 ConnectStateToProto(connect_state_));
947 } 948 }
948 } 949 }
949 950
950 void CastSocket::SetReadyState(ReadyState ready_state) { 951 void CastSocketImpl::SetReadyState(ReadyState ready_state) {
951 if (ready_state_ != ready_state) { 952 if (ready_state_ != ready_state) {
952 ready_state_ = ready_state; 953 ready_state_ = ready_state;
953 logger_->LogSocketReadyState(channel_id_, ReadyStateToProto(ready_state_)); 954 logger_->LogSocketReadyState(channel_id_, ReadyStateToProto(ready_state_));
954 } 955 }
955 } 956 }
956 957
957 void CastSocket::SetErrorState(ChannelError error_state) { 958 void CastSocketImpl::SetErrorState(ChannelError error_state) {
958 if (error_state_ != error_state) { 959 if (error_state_ != error_state) {
959 error_state_ = error_state; 960 error_state_ = error_state;
960 logger_->LogSocketErrorState(channel_id_, ErrorStateToProto(error_state_)); 961 logger_->LogSocketErrorState(channel_id_, ErrorStateToProto(error_state_));
961 } 962 }
962 } 963 }
963 964
964 void CastSocket::SetReadState(ReadState read_state) { 965 void CastSocketImpl::SetReadState(ReadState read_state) {
965 if (read_state_ != read_state) { 966 if (read_state_ != read_state) {
966 read_state_ = read_state; 967 read_state_ = read_state;
967 logger_->LogSocketReadState(channel_id_, ReadStateToProto(read_state_)); 968 logger_->LogSocketReadState(channel_id_, ReadStateToProto(read_state_));
968 } 969 }
969 } 970 }
970 971
971 void CastSocket::SetWriteState(WriteState write_state) { 972 void CastSocketImpl::SetWriteState(WriteState write_state) {
972 if (write_state_ != write_state) { 973 if (write_state_ != write_state) {
973 write_state_ = write_state; 974 write_state_ = write_state;
974 logger_->LogSocketWriteState(channel_id_, WriteStateToProto(write_state_)); 975 logger_->LogSocketWriteState(channel_id_, WriteStateToProto(write_state_));
975 } 976 }
976 } 977 }
977 978
978 CastSocket::WriteRequest::WriteRequest(const net::CompletionCallback& callback) 979 CastSocketImpl::WriteRequest::WriteRequest(
979 : callback(callback) { } 980 const net::CompletionCallback& callback)
981 : callback(callback) {
982 }
980 983
981 bool CastSocket::WriteRequest::SetContent(const CastMessage& message_proto) { 984 bool CastSocketImpl::WriteRequest::SetContent(
985 const CastMessage& message_proto) {
982 DCHECK(!io_buffer.get()); 986 DCHECK(!io_buffer.get());
983 std::string message_data; 987 std::string message_data;
984 if (!MessageFramer::Serialize(message_proto, &message_data)) { 988 if (!MessageFramer::Serialize(message_proto, &message_data)) {
985 return false; 989 return false;
986 } 990 }
987 message_namespace = message_proto.namespace_(); 991 message_namespace = message_proto.namespace_();
988 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data), 992 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data),
989 message_data.size()); 993 message_data.size());
990 return true; 994 return true;
991 } 995 }
992 996
993 CastSocket::WriteRequest::~WriteRequest() { } 997 CastSocketImpl::WriteRequest::~WriteRequest() {
998 }
994 } // namespace cast_channel 999 } // namespace cast_channel
995 } // namespace core_api 1000 } // namespace core_api
996 } // namespace extensions 1001 } // namespace extensions
997 1002
998 #undef VLOG_WITH_CONNECTION 1003 #undef VLOG_WITH_CONNECTION
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698