OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |