OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h" | 5 #include "chrome/browser/extensions/api/cast_channel/cast_socket.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
22 #include "net/cert/x509_certificate.h" | 22 #include "net/cert/x509_certificate.h" |
23 #include "net/http/transport_security_state.h" | 23 #include "net/http/transport_security_state.h" |
24 #include "net/socket/client_socket_factory.h" | 24 #include "net/socket/client_socket_factory.h" |
25 #include "net/socket/client_socket_handle.h" | 25 #include "net/socket/client_socket_handle.h" |
26 #include "net/socket/ssl_client_socket.h" | 26 #include "net/socket/ssl_client_socket.h" |
27 #include "net/socket/stream_socket.h" | 27 #include "net/socket/stream_socket.h" |
28 #include "net/socket/tcp_client_socket.h" | 28 #include "net/socket/tcp_client_socket.h" |
29 #include "net/ssl/ssl_config_service.h" | 29 #include "net/ssl/ssl_config_service.h" |
30 #include "net/ssl/ssl_info.h" | 30 #include "net/ssl/ssl_info.h" |
31 | 31 |
32 // Assumes member name url_. Anyway compile error will occur if that changes. | |
Wez
2014/02/13 21:46:08
nit: "Anyway ... changes." is not a sentence.
Sug
Munjal (Google)
2014/02/13 22:23:39
Done.
| |
33 #define VLOG_WITH_URL(level) VLOG(level) << "[" + url_.spec() + "] " | |
34 | |
32 namespace { | 35 namespace { |
33 | 36 |
34 // Allowed schemes for Cast device URLs. | 37 // Allowed schemes for Cast device URLs. |
35 const char kCastInsecureScheme[] = "cast"; | 38 const char kCastInsecureScheme[] = "cast"; |
36 const char kCastSecureScheme[] = "casts"; | 39 const char kCastSecureScheme[] = "casts"; |
37 | 40 |
38 // The default keepalive delay. On Linux, keepalives probes will be sent after | 41 // The default keepalive delay. On Linux, keepalives probes will be sent after |
39 // the socket is idle for this length of time, and the socket will be closed | 42 // the socket is idle for this length of time, and the socket will be closed |
40 // after 9 failed probes. So the total idle time before close is 10 * | 43 // after 9 failed probes. So the total idle time before close is 10 * |
41 // kTcpKeepAliveDelaySecs. | 44 // kTcpKeepAliveDelaySecs. |
(...skipping 25 matching lines...) Expand all Loading... | |
67 CastSocket::CastSocket(const std::string& owner_extension_id, | 70 CastSocket::CastSocket(const std::string& owner_extension_id, |
68 const GURL& url, | 71 const GURL& url, |
69 CastSocket::Delegate* delegate, | 72 CastSocket::Delegate* delegate, |
70 net::NetLog* net_log) : | 73 net::NetLog* net_log) : |
71 ApiResource(owner_extension_id), | 74 ApiResource(owner_extension_id), |
72 channel_id_(0), | 75 channel_id_(0), |
73 url_(url), | 76 url_(url), |
74 delegate_(delegate), | 77 delegate_(delegate), |
75 auth_required_(false), | 78 auth_required_(false), |
76 current_message_size_(0), | 79 current_message_size_(0), |
80 current_message_(new CastMessage()), | |
77 net_log_(net_log), | 81 net_log_(net_log), |
78 connect_state_(CONN_STATE_NONE), | 82 connect_state_(CONN_STATE_NONE), |
79 write_state_(WRITE_STATE_NONE), | 83 write_state_(WRITE_STATE_NONE), |
80 read_state_(READ_STATE_NONE), | 84 read_state_(READ_STATE_NONE), |
81 error_state_(CHANNEL_ERROR_NONE), | 85 error_state_(CHANNEL_ERROR_NONE), |
82 ready_state_(READY_STATE_NONE) { | 86 ready_state_(READY_STATE_NONE) { |
83 DCHECK(net_log_); | 87 DCHECK(net_log_); |
84 net_log_source_.type = net::NetLog::SOURCE_SOCKET; | 88 net_log_source_.type = net::NetLog::SOURCE_SOCKET; |
85 net_log_source_.id = net_log_->NextID(); | 89 net_log_source_.id = net_log_->NextID(); |
86 | 90 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
138 | 142 |
139 bool CastSocket::ExtractPeerCert(std::string* cert) { | 143 bool CastSocket::ExtractPeerCert(std::string* cert) { |
140 DCHECK(cert); | 144 DCHECK(cert); |
141 DCHECK(peer_cert_.empty()); | 145 DCHECK(peer_cert_.empty()); |
142 net::SSLInfo ssl_info; | 146 net::SSLInfo ssl_info; |
143 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) | 147 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get()) |
144 return false; | 148 return false; |
145 bool result = net::X509Certificate::GetDEREncoded( | 149 bool result = net::X509Certificate::GetDEREncoded( |
146 ssl_info.cert->os_cert_handle(), cert); | 150 ssl_info.cert->os_cert_handle(), cert); |
147 if (result) | 151 if (result) |
148 VLOG(1) << "[URL: " << url_.spec() | 152 VLOG_WITH_URL(1) << "Successfully extracted peer certificate: " << *cert; |
149 << "] Successfully extracted peer certificate: " << *cert; | |
150 return result; | 153 return result; |
151 } | 154 } |
152 | 155 |
153 bool CastSocket::VerifyChallengeReply() { | 156 bool CastSocket::VerifyChallengeReply() { |
154 return AuthenticateChallengeReply(*challenge_reply_.get(), peer_cert_); | 157 return AuthenticateChallengeReply(*challenge_reply_.get(), peer_cert_); |
155 } | 158 } |
156 | 159 |
157 void CastSocket::Connect(const net::CompletionCallback& callback) { | 160 void CastSocket::Connect(const net::CompletionCallback& callback) { |
158 DCHECK(CalledOnValidThread()); | 161 DCHECK(CalledOnValidThread()); |
159 VLOG(1) << "Connect readyState = " << ready_state_; | 162 VLOG_WITH_URL(1) << "Connect readyState = " << ready_state_; |
160 if (ready_state_ != READY_STATE_NONE) { | 163 if (ready_state_ != READY_STATE_NONE) { |
161 callback.Run(net::ERR_CONNECTION_FAILED); | 164 callback.Run(net::ERR_CONNECTION_FAILED); |
162 return; | 165 return; |
163 } | 166 } |
164 if (!ParseChannelUrl(url_)) { | 167 if (!ParseChannelUrl(url_)) { |
165 callback.Run(net::ERR_CONNECTION_FAILED); | 168 callback.Run(net::ERR_CONNECTION_FAILED); |
166 return; | 169 return; |
167 } | 170 } |
168 | 171 |
169 ready_state_ = READY_STATE_CONNECTING; | 172 ready_state_ = READY_STATE_CONNECTING; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
225 // Get out of the loop either when: | 228 // Get out of the loop either when: |
226 // a. A network operation is pending, OR | 229 // a. A network operation is pending, OR |
227 // b. The Do* method called did not change state | 230 // b. The Do* method called did not change state |
228 | 231 |
229 // Connect loop is finished: if there is no pending IO invoke the callback. | 232 // Connect loop is finished: if there is no pending IO invoke the callback. |
230 if (rv != net::ERR_IO_PENDING) | 233 if (rv != net::ERR_IO_PENDING) |
231 DoConnectCallback(rv); | 234 DoConnectCallback(rv); |
232 } | 235 } |
233 | 236 |
234 int CastSocket::DoTcpConnect() { | 237 int CastSocket::DoTcpConnect() { |
235 VLOG(1) << "DoTcpConnect"; | 238 VLOG_WITH_URL(1) << "DoTcpConnect"; |
236 connect_state_ = CONN_STATE_TCP_CONNECT_COMPLETE; | 239 connect_state_ = CONN_STATE_TCP_CONNECT_COMPLETE; |
237 tcp_socket_ = CreateTcpSocket(); | 240 tcp_socket_ = CreateTcpSocket(); |
238 return tcp_socket_->Connect( | 241 return tcp_socket_->Connect( |
239 base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr())); | 242 base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr())); |
240 } | 243 } |
241 | 244 |
242 int CastSocket::DoTcpConnectComplete(int result) { | 245 int CastSocket::DoTcpConnectComplete(int result) { |
243 VLOG(1) << "DoTcpConnectComplete: " << result; | 246 VLOG_WITH_URL(1) << "DoTcpConnectComplete: " << result; |
244 if (result == net::OK) { | 247 if (result == net::OK) { |
245 // Enable TCP protocol-level keep-alive. | 248 // Enable TCP protocol-level keep-alive. |
246 bool result = tcp_socket_->SetKeepAlive(true, kTcpKeepAliveDelaySecs); | 249 bool result = tcp_socket_->SetKeepAlive(true, kTcpKeepAliveDelaySecs); |
247 LOG_IF(WARNING, !result) << "Failed to SetKeepAlive."; | 250 LOG_IF(WARNING, !result) << "Failed to SetKeepAlive."; |
248 connect_state_ = CONN_STATE_SSL_CONNECT; | 251 connect_state_ = CONN_STATE_SSL_CONNECT; |
249 } | 252 } |
250 return result; | 253 return result; |
251 } | 254 } |
252 | 255 |
253 int CastSocket::DoSslConnect() { | 256 int CastSocket::DoSslConnect() { |
254 VLOG(1) << "DoSslConnect"; | 257 VLOG_WITH_URL(1) << "DoSslConnect"; |
255 connect_state_ = CONN_STATE_SSL_CONNECT_COMPLETE; | 258 connect_state_ = CONN_STATE_SSL_CONNECT_COMPLETE; |
256 socket_ = CreateSslSocket(tcp_socket_.PassAs<net::StreamSocket>()); | 259 socket_ = CreateSslSocket(tcp_socket_.PassAs<net::StreamSocket>()); |
257 return socket_->Connect( | 260 return socket_->Connect( |
258 base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr())); | 261 base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr())); |
259 } | 262 } |
260 | 263 |
261 int CastSocket::DoSslConnectComplete(int result) { | 264 int CastSocket::DoSslConnectComplete(int result) { |
262 VLOG(1) << "DoSslConnectComplete: " << result; | 265 VLOG_WITH_URL(1) << "DoSslConnectComplete: " << result; |
263 if (result == net::ERR_CERT_AUTHORITY_INVALID && | 266 if (result == net::ERR_CERT_AUTHORITY_INVALID && |
264 peer_cert_.empty() && | 267 peer_cert_.empty() && |
265 ExtractPeerCert(&peer_cert_)) { | 268 ExtractPeerCert(&peer_cert_)) { |
266 connect_state_ = CONN_STATE_TCP_CONNECT; | 269 connect_state_ = CONN_STATE_TCP_CONNECT; |
267 } else if (result == net::OK && auth_required_) { | 270 } else if (result == net::OK && auth_required_) { |
268 connect_state_ = CONN_STATE_AUTH_CHALLENGE_SEND; | 271 connect_state_ = CONN_STATE_AUTH_CHALLENGE_SEND; |
269 } | 272 } |
270 return result; | 273 return result; |
271 } | 274 } |
272 | 275 |
273 int CastSocket::DoAuthChallengeSend() { | 276 int CastSocket::DoAuthChallengeSend() { |
274 VLOG(1) << "DoAuthChallengeSend"; | 277 VLOG_WITH_URL(1) << "DoAuthChallengeSend"; |
275 connect_state_ = CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE; | 278 connect_state_ = CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE; |
276 CastMessage challenge_message; | 279 CastMessage challenge_message; |
277 CreateAuthChallengeMessage(&challenge_message); | 280 CreateAuthChallengeMessage(&challenge_message); |
278 VLOG(1) << "Sending challenge: " << CastMessageToString(challenge_message); | 281 VLOG_WITH_URL(1) << "Sending challenge: " |
282 << CastMessageToString(challenge_message); | |
279 // Post a task to send auth challenge so that DoWriteLoop is not nested inside | 283 // Post a task to send auth challenge so that DoWriteLoop is not nested inside |
280 // DoConnectLoop. This is not strictly necessary but keeps the write loop | 284 // DoConnectLoop. This is not strictly necessary but keeps the write loop |
281 // code decoupled from connect loop code. | 285 // code decoupled from connect loop code. |
282 base::MessageLoop::current()->PostTask( | 286 base::MessageLoop::current()->PostTask( |
283 FROM_HERE, | 287 FROM_HERE, |
284 base::Bind(&CastSocket::SendCastMessageInternal, AsWeakPtr(), | 288 base::Bind(&CastSocket::SendCastMessageInternal, AsWeakPtr(), |
285 challenge_message, | 289 challenge_message, |
286 base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr()))); | 290 base::Bind(&CastSocket::DoConnectLoop, AsWeakPtr()))); |
287 // Always return IO_PENDING since the result is always asynchronous. | 291 // Always return IO_PENDING since the result is always asynchronous. |
288 return net::ERR_IO_PENDING; | 292 return net::ERR_IO_PENDING; |
289 } | 293 } |
290 | 294 |
291 int CastSocket::DoAuthChallengeSendComplete(int result) { | 295 int CastSocket::DoAuthChallengeSendComplete(int result) { |
292 VLOG(1) << "DoAuthChallengeSendComplete: " << result; | 296 VLOG_WITH_URL(1) << "DoAuthChallengeSendComplete: " << result; |
293 if (result < 0) | 297 if (result < 0) |
294 return result; | 298 return result; |
295 connect_state_ = CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE; | 299 connect_state_ = CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE; |
296 // Post a task to start read loop so that DoReadLoop is not nested inside | 300 // Post a task to start read loop so that DoReadLoop is not nested inside |
297 // DoConnectLoop. This is not strictly necessary but keeps the read loop | 301 // DoConnectLoop. This is not strictly necessary but keeps the read loop |
298 // code decoupled from connect loop code. | 302 // code decoupled from connect loop code. |
299 PostTaskToStartReadLoop(); | 303 PostTaskToStartReadLoop(); |
300 // Always return IO_PENDING since the result is always asynchronous. | 304 // Always return IO_PENDING since the result is always asynchronous. |
301 return net::ERR_IO_PENDING; | 305 return net::ERR_IO_PENDING; |
302 } | 306 } |
303 | 307 |
304 int CastSocket::DoAuthChallengeReplyComplete(int result) { | 308 int CastSocket::DoAuthChallengeReplyComplete(int result) { |
305 VLOG(1) << "DoAuthChallengeReplyComplete: " << result; | 309 VLOG_WITH_URL(1) << "DoAuthChallengeReplyComplete: " << result; |
306 if (result < 0) | 310 if (result < 0) |
307 return result; | 311 return result; |
308 if (!VerifyChallengeReply()) | 312 if (!VerifyChallengeReply()) |
309 return net::ERR_FAILED; | 313 return net::ERR_FAILED; |
310 VLOG(1) << "Auth challenge verification succeeded"; | 314 VLOG_WITH_URL(1) << "Auth challenge verification succeeded"; |
311 return net::OK; | 315 return net::OK; |
312 } | 316 } |
313 | 317 |
314 void CastSocket::DoConnectCallback(int result) { | 318 void CastSocket::DoConnectCallback(int result) { |
315 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED; | 319 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED; |
316 error_state_ = (result == net::OK) ? | 320 error_state_ = (result == net::OK) ? |
317 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR; | 321 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR; |
318 if (result == net::OK) // Start the read loop | 322 if (result == net::OK) // Start the read loop |
319 PostTaskToStartReadLoop(); | 323 PostTaskToStartReadLoop(); |
320 base::ResetAndReturn(&connect_callback_).Run(result); | 324 base::ResetAndReturn(&connect_callback_).Run(result); |
321 } | 325 } |
322 | 326 |
323 void CastSocket::Close(const net::CompletionCallback& callback) { | 327 void CastSocket::Close(const net::CompletionCallback& callback) { |
324 DCHECK(CalledOnValidThread()); | 328 DCHECK(CalledOnValidThread()); |
325 VLOG(1) << "Close ReadyState = " << ready_state_; | 329 VLOG_WITH_URL(1) << "Close ReadyState = " << ready_state_; |
326 tcp_socket_.reset(); | 330 tcp_socket_.reset(); |
327 socket_.reset(); | 331 socket_.reset(); |
328 cert_verifier_.reset(); | 332 cert_verifier_.reset(); |
329 transport_security_state_.reset(); | 333 transport_security_state_.reset(); |
330 ready_state_ = READY_STATE_CLOSED; | 334 ready_state_ = READY_STATE_CLOSED; |
331 callback.Run(net::OK); | 335 callback.Run(net::OK); |
332 // |callback| can delete |this| | 336 // |callback| can delete |this| |
333 } | 337 } |
334 | 338 |
335 void CastSocket::SendMessage(const MessageInfo& message, | 339 void CastSocket::SendMessage(const MessageInfo& message, |
(...skipping 23 matching lines...) Expand all Loading... | |
359 | 363 |
360 write_queue_.push(write_request); | 364 write_queue_.push(write_request); |
361 if (write_state_ == WRITE_STATE_NONE) { | 365 if (write_state_ == WRITE_STATE_NONE) { |
362 write_state_ = WRITE_STATE_WRITE; | 366 write_state_ = WRITE_STATE_WRITE; |
363 DoWriteLoop(net::OK); | 367 DoWriteLoop(net::OK); |
364 } | 368 } |
365 } | 369 } |
366 | 370 |
367 void CastSocket::DoWriteLoop(int result) { | 371 void CastSocket::DoWriteLoop(int result) { |
368 DCHECK(CalledOnValidThread()); | 372 DCHECK(CalledOnValidThread()); |
369 VLOG(1) << "WriteData q = " << write_queue_.size(); | 373 VLOG_WITH_URL(1) << "DoWriteLoop queue size: " << write_queue_.size(); |
370 | 374 |
371 if (write_queue_.empty()) { | 375 if (write_queue_.empty()) { |
372 write_state_ = WRITE_STATE_NONE; | 376 write_state_ = WRITE_STATE_NONE; |
373 return; | 377 return; |
374 } | 378 } |
375 | 379 |
376 // Network operations can either finish synchronously or asynchronously. | 380 // Network operations can either finish synchronously or asynchronously. |
377 // This method executes the state machine transitions in a loop so that | 381 // This method executes the state machine transitions in a loop so that |
378 // write state transitions happen even when network operations finish | 382 // write state transitions happen even when network operations finish |
379 // synchronously. | 383 // synchronously. |
(...skipping 29 matching lines...) Expand all Loading... | |
409 | 413 |
410 // Write loop is done - if the result is ERR_FAILED then close with error. | 414 // Write loop is done - if the result is ERR_FAILED then close with error. |
411 if (rv == net::ERR_FAILED) | 415 if (rv == net::ERR_FAILED) |
412 CloseWithError(error_state_); | 416 CloseWithError(error_state_); |
413 } | 417 } |
414 | 418 |
415 int CastSocket::DoWrite() { | 419 int CastSocket::DoWrite() { |
416 DCHECK(!write_queue_.empty()); | 420 DCHECK(!write_queue_.empty()); |
417 WriteRequest& request = write_queue_.front(); | 421 WriteRequest& request = write_queue_.front(); |
418 | 422 |
419 VLOG(1) << "WriteData byte_count = " << request.io_buffer->size() | 423 VLOG_WITH_URL(2) << "WriteData byte_count = " << request.io_buffer->size() |
420 << " bytes_written " << request.io_buffer->BytesConsumed(); | 424 << " bytes_written " << request.io_buffer->BytesConsumed(); |
421 | 425 |
422 write_state_ = WRITE_STATE_WRITE_COMPLETE; | 426 write_state_ = WRITE_STATE_WRITE_COMPLETE; |
423 | 427 |
424 return socket_->Write( | 428 return socket_->Write( |
425 request.io_buffer.get(), | 429 request.io_buffer.get(), |
426 request.io_buffer->BytesRemaining(), | 430 request.io_buffer->BytesRemaining(), |
427 base::Bind(&CastSocket::DoWriteLoop, AsWeakPtr())); | 431 base::Bind(&CastSocket::DoWriteLoop, AsWeakPtr())); |
428 } | 432 } |
429 | 433 |
430 int CastSocket::DoWriteComplete(int result) { | 434 int CastSocket::DoWriteComplete(int result) { |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
557 DCHECK_GT(num_bytes_to_read, 0U); | 561 DCHECK_GT(num_bytes_to_read, 0U); |
558 | 562 |
559 // Read up to num_bytes_to_read into |current_read_buffer_|. | 563 // Read up to num_bytes_to_read into |current_read_buffer_|. |
560 return socket_->Read( | 564 return socket_->Read( |
561 current_read_buffer_.get(), | 565 current_read_buffer_.get(), |
562 num_bytes_to_read, | 566 num_bytes_to_read, |
563 base::Bind(&CastSocket::DoReadLoop, AsWeakPtr())); | 567 base::Bind(&CastSocket::DoReadLoop, AsWeakPtr())); |
564 } | 568 } |
565 | 569 |
566 int CastSocket::DoReadComplete(int result) { | 570 int CastSocket::DoReadComplete(int result) { |
567 VLOG(1) << "DoReadDataComplete result = " << result | 571 VLOG_WITH_URL(2) << "DoReadComplete result = " << result |
568 << " header offset = " << header_read_buffer_->offset() | 572 << " header offset = " << header_read_buffer_->offset() |
569 << " body offset = " << body_read_buffer_->offset(); | 573 << " body offset = " << body_read_buffer_->offset(); |
570 if (result <= 0) { // 0 means EOF: the peer closed the socket | 574 if (result <= 0) { // 0 means EOF: the peer closed the socket |
575 VLOG_WITH_URL(1) << "Read error, peer closed the socket"; | |
571 error_state_ = CHANNEL_ERROR_SOCKET_ERROR; | 576 error_state_ = CHANNEL_ERROR_SOCKET_ERROR; |
572 read_state_ = READ_STATE_ERROR; | 577 read_state_ = READ_STATE_ERROR; |
573 return result == 0 ? net::ERR_FAILED : result; | 578 return result == 0 ? net::ERR_FAILED : result; |
574 } | 579 } |
575 | 580 |
576 // Some data was read. Move the offset in the current buffer forward. | 581 // Some data was read. Move the offset in the current buffer forward. |
577 DCHECK_LE(current_read_buffer_->offset() + result, | 582 DCHECK_LE(current_read_buffer_->offset() + result, |
578 current_read_buffer_->capacity()); | 583 current_read_buffer_->capacity()); |
579 current_read_buffer_->set_offset(current_read_buffer_->offset() + result); | 584 current_read_buffer_->set_offset(current_read_buffer_->offset() + result); |
580 read_state_ = READ_STATE_READ; | 585 read_state_ = READ_STATE_READ; |
(...skipping 15 matching lines...) Expand all Loading... | |
596 error_state_ = cast_channel::CHANNEL_ERROR_INVALID_MESSAGE; | 601 error_state_ = cast_channel::CHANNEL_ERROR_INVALID_MESSAGE; |
597 read_state_ = READ_STATE_ERROR; | 602 read_state_ = READ_STATE_ERROR; |
598 } | 603 } |
599 } | 604 } |
600 | 605 |
601 return net::OK; | 606 return net::OK; |
602 } | 607 } |
603 | 608 |
604 int CastSocket::DoReadCallback() { | 609 int CastSocket::DoReadCallback() { |
605 read_state_ = READ_STATE_READ; | 610 read_state_ = READ_STATE_READ; |
606 if (IsAuthMessage(current_message_)) { | 611 const CastMessage& message = *(current_message_.get()); |
612 if (IsAuthMessage(message)) { | |
607 // An auth message is received, check that connect flow is running. | 613 // An auth message is received, check that connect flow is running. |
608 if (ready_state_ == READY_STATE_CONNECTING) { | 614 if (ready_state_ == READY_STATE_CONNECTING) { |
609 challenge_reply_.reset(new CastMessage(current_message_)); | 615 challenge_reply_.reset(new CastMessage(message)); |
610 PostTaskToStartConnectLoop(net::OK); | 616 PostTaskToStartConnectLoop(net::OK); |
611 } else { | 617 } else { |
612 read_state_ = READ_STATE_ERROR; | 618 read_state_ = READ_STATE_ERROR; |
613 } | 619 } |
614 } else if (delegate_) { | 620 } else if (delegate_) { |
615 MessageInfo message; | 621 MessageInfo message_info; |
616 if (CastMessageToMessageInfo(current_message_, &message)) | 622 if (CastMessageToMessageInfo(message, &message_info)) |
617 delegate_->OnMessage(this, message); | 623 delegate_->OnMessage(this, message_info); |
618 else | 624 else |
619 read_state_ = READ_STATE_ERROR; | 625 read_state_ = READ_STATE_ERROR; |
620 } | 626 } |
621 current_message_.Clear(); | 627 current_message_->Clear(); |
622 return net::OK; | 628 return net::OK; |
623 } | 629 } |
624 | 630 |
625 int CastSocket::DoReadError(int result) { | 631 int CastSocket::DoReadError(int result) { |
626 DCHECK_LE(result, 0); | 632 DCHECK_LE(result, 0); |
627 // If inside connection flow, then get back to connect loop. | 633 // If inside connection flow, then get back to connect loop. |
628 if (ready_state_ == READY_STATE_CONNECTING) { | 634 if (ready_state_ == READY_STATE_CONNECTING) { |
629 PostTaskToStartConnectLoop(result); | 635 PostTaskToStartConnectLoop(result); |
630 // does not try to report error also. | 636 // does not try to report error also. |
631 return net::OK; | 637 return net::OK; |
632 } | 638 } |
633 return net::ERR_FAILED; | 639 return net::ERR_FAILED; |
634 } | 640 } |
635 | 641 |
636 bool CastSocket::ProcessHeader() { | 642 bool CastSocket::ProcessHeader() { |
637 DCHECK_EQ(static_cast<uint32>(header_read_buffer_->offset()), | 643 DCHECK_EQ(static_cast<uint32>(header_read_buffer_->offset()), |
638 kMessageHeaderSize); | 644 kMessageHeaderSize); |
639 MessageHeader header; | 645 MessageHeader header; |
640 MessageHeader::ReadFromIOBuffer(header_read_buffer_.get(), &header); | 646 MessageHeader::ReadFromIOBuffer(header_read_buffer_.get(), &header); |
641 if (header.message_size > kMaxMessageSize) | 647 if (header.message_size > kMaxMessageSize) |
642 return false; | 648 return false; |
643 | 649 |
644 VLOG(1) << "Parsed header { message_size: " << header.message_size << " }"; | 650 VLOG_WITH_URL(2) << "Parsed header { message_size: " |
651 << header.message_size << " }"; | |
645 current_message_size_ = header.message_size; | 652 current_message_size_ = header.message_size; |
646 return true; | 653 return true; |
647 } | 654 } |
648 | 655 |
649 bool CastSocket::ProcessBody() { | 656 bool CastSocket::ProcessBody() { |
650 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()), | 657 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()), |
651 current_message_size_); | 658 current_message_size_); |
652 if (!current_message_.ParseFromArray( | 659 if (!current_message_->ParseFromArray( |
653 body_read_buffer_->StartOfBuffer(), current_message_size_)) { | 660 body_read_buffer_->StartOfBuffer(), current_message_size_)) { |
654 return false; | 661 return false; |
655 } | 662 } |
656 current_message_size_ = 0; | 663 current_message_size_ = 0; |
657 header_read_buffer_->set_offset(0); | 664 header_read_buffer_->set_offset(0); |
658 body_read_buffer_->set_offset(0); | 665 body_read_buffer_->set_offset(0); |
659 current_read_buffer_ = header_read_buffer_; | 666 current_read_buffer_ = header_read_buffer_; |
660 return true; | 667 return true; |
661 } | 668 } |
662 | 669 |
(...skipping 16 matching lines...) Expand all Loading... | |
679 void CastSocket::CloseWithError(ChannelError error) { | 686 void CastSocket::CloseWithError(ChannelError error) { |
680 DCHECK(CalledOnValidThread()); | 687 DCHECK(CalledOnValidThread()); |
681 socket_.reset(NULL); | 688 socket_.reset(NULL); |
682 ready_state_ = READY_STATE_CLOSED; | 689 ready_state_ = READY_STATE_CLOSED; |
683 error_state_ = error; | 690 error_state_ = error; |
684 if (delegate_) | 691 if (delegate_) |
685 delegate_->OnError(this, error); | 692 delegate_->OnError(this, error); |
686 } | 693 } |
687 | 694 |
688 bool CastSocket::ParseChannelUrl(const GURL& url) { | 695 bool CastSocket::ParseChannelUrl(const GURL& url) { |
689 VLOG(1) << "url = " + url.spec(); | 696 VLOG_WITH_URL(2) << "ParseChannelUrl"; |
690 if (url.SchemeIs(kCastInsecureScheme)) { | 697 if (url.SchemeIs(kCastInsecureScheme)) { |
691 auth_required_ = false; | 698 auth_required_ = false; |
692 } else if (url.SchemeIs(kCastSecureScheme)) { | 699 } else if (url.SchemeIs(kCastSecureScheme)) { |
693 auth_required_ = true; | 700 auth_required_ = true; |
694 } else { | 701 } else { |
695 return false; | 702 return false; |
696 } | 703 } |
697 // TODO(mfoltz): Manual parsing, yech. Register cast[s] as standard schemes? | 704 // TODO(mfoltz): Manual parsing, yech. Register cast[s] as standard schemes? |
698 // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets? | 705 // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets? |
699 // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 link-local | 706 // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 |
700 // networks | 707 // link-local networks |
701 const std::string& path = url.path(); | 708 const std::string& path = url.path(); |
702 // Shortest possible: //A:B | 709 // Shortest possible: //A:B |
703 if (path.size() < 5) { | 710 if (path.size() < 5) { |
704 return false; | 711 return false; |
705 } | 712 } |
706 if (path.find("//") != 0) { | 713 if (path.find("//") != 0) { |
707 return false; | 714 return false; |
708 } | 715 } |
709 size_t colon = path.find_last_of(':'); | 716 size_t colon = path.find_last_of(':'); |
710 if (colon == std::string::npos || colon < 3 || colon > path.size() - 2) { | 717 if (colon == std::string::npos || colon < 3 || colon > path.size() - 2) { |
711 return false; | 718 return false; |
712 } | 719 } |
713 const std::string& ip_address_str = path.substr(2, colon - 2); | 720 const std::string& ip_address_str = path.substr(2, colon - 2); |
714 const std::string& port_str = path.substr(colon + 1); | 721 const std::string& port_str = path.substr(colon + 1); |
715 VLOG(1) << "addr " << ip_address_str << " port " << port_str; | 722 VLOG_WITH_URL(2) << "IP: " << ip_address_str << " Port: " << port_str; |
716 int port; | 723 int port; |
717 if (!base::StringToInt(port_str, &port)) | 724 if (!base::StringToInt(port_str, &port)) |
718 return false; | 725 return false; |
719 net::IPAddressNumber ip_address; | 726 net::IPAddressNumber ip_address; |
720 if (!net::ParseIPLiteralToNumber(ip_address_str, &ip_address)) | 727 if (!net::ParseIPLiteralToNumber(ip_address_str, &ip_address)) |
721 return false; | 728 return false; |
722 ip_endpoint_ = net::IPEndPoint(ip_address, port); | 729 ip_endpoint_ = net::IPEndPoint(ip_address, port); |
723 return true; | 730 return true; |
724 }; | 731 }; |
725 | 732 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
772 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data), | 779 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data), |
773 message_data.size()); | 780 message_data.size()); |
774 return true; | 781 return true; |
775 } | 782 } |
776 | 783 |
777 CastSocket::WriteRequest::~WriteRequest() { } | 784 CastSocket::WriteRequest::~WriteRequest() { } |
778 | 785 |
779 } // namespace cast_channel | 786 } // namespace cast_channel |
780 } // namespace api | 787 } // namespace api |
781 } // namespace extensions | 788 } // namespace extensions |
789 | |
790 #undef VLOG_WITH_URL | |
OLD | NEW |