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

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

Issue 35443002: Update CastSocket connection flow to check for receiver credentials. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "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"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/sys_byteorder.h" 13 #include "base/sys_byteorder.h"
14 #include "chrome/browser/extensions/api/cast_channel/cast_auth_util.h"
14 #include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h" 15 #include "chrome/browser/extensions/api/cast_channel/cast_channel.pb.h"
15 #include "chrome/browser/extensions/api/cast_channel/cast_message_util.h" 16 #include "chrome/browser/extensions/api/cast_channel/cast_message_util.h"
16 #include "net/base/address_list.h" 17 #include "net/base/address_list.h"
17 #include "net/base/host_port_pair.h" 18 #include "net/base/host_port_pair.h"
18 #include "net/base/net_errors.h" 19 #include "net/base/net_errors.h"
19 #include "net/base/net_util.h" 20 #include "net/base/net_util.h"
20 #include "net/cert/cert_verifier.h" 21 #include "net/cert/cert_verifier.h"
21 #include "net/cert/x509_certificate.h" 22 #include "net/cert/x509_certificate.h"
22 #include "net/http/transport_security_state.h" 23 #include "net/http/transport_security_state.h"
23 #include "net/socket/client_socket_factory.h" 24 #include "net/socket/client_socket_factory.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 ApiResourceManager<api::cast_channel::CastSocket>::GetFactoryInstance() { 59 ApiResourceManager<api::cast_channel::CastSocket>::GetFactoryInstance() {
59 return &g_factory.Get(); 60 return &g_factory.Get();
60 } 61 }
61 62
62 namespace api { 63 namespace api {
63 namespace cast_channel { 64 namespace cast_channel {
64 65
65 const uint32 kMaxMessageSize = 65536; 66 const uint32 kMaxMessageSize = 65536;
66 67
67 CastSocket::CastSocket(const std::string& owner_extension_id, 68 CastSocket::CastSocket(const std::string& owner_extension_id,
68 const GURL& url, CastSocket::Delegate* delegate, 69 const GURL& url,
70 CastSocket::Delegate* delegate,
69 net::NetLog* net_log) : 71 net::NetLog* net_log) :
70 ApiResource(owner_extension_id), 72 ApiResource(owner_extension_id),
71 channel_id_(0), 73 channel_id_(0),
72 url_(url), 74 url_(url),
73 delegate_(delegate), 75 delegate_(delegate),
74 is_secure_(false), 76 auth_required_(false),
75 error_state_(CHANNEL_ERROR_NONE), 77 error_state_(CHANNEL_ERROR_NONE),
76 ready_state_(READY_STATE_NONE), 78 ready_state_(READY_STATE_NONE),
77 write_callback_pending_(false), 79 write_callback_pending_(false),
78 read_callback_pending_(false), 80 read_callback_pending_(false),
79 current_message_size_(0), 81 current_message_size_(0),
80 net_log_(net_log), 82 net_log_(net_log),
81 next_state_(CONN_STATE_NONE) { 83 next_state_(CONN_STATE_NONE) {
82 DCHECK(net_log_); 84 DCHECK(net_log_);
83 net_log_source_.type = net::NetLog::SOURCE_SOCKET; 85 net_log_source_.type = net::NetLog::SOURCE_SOCKET;
84 net_log_source_.id = net_log_->NextID(); 86 net_log_source_.id = net_log_->NextID();
85 87
86 // We reuse these buffers for each message. 88 // We reuse these buffers for each message.
87 header_read_buffer_ = new net::GrowableIOBuffer(); 89 header_read_buffer_ = new net::GrowableIOBuffer();
88 header_read_buffer_->SetCapacity(kMessageHeaderSize); 90 header_read_buffer_->SetCapacity(kMessageHeaderSize);
89 body_read_buffer_ = new net::GrowableIOBuffer(); 91 body_read_buffer_ = new net::GrowableIOBuffer();
90 body_read_buffer_->SetCapacity(kMaxMessageSize); 92 body_read_buffer_->SetCapacity(kMaxMessageSize);
91 current_read_buffer_ = header_read_buffer_; 93 current_read_buffer_ = header_read_buffer_;
92 } 94 }
93 95
94 CastSocket::~CastSocket() { } 96 CastSocket::~CastSocket() { }
95 97
96 const GURL& CastSocket::url() const { 98 const GURL& CastSocket::url() const {
97 return url_; 99 return url_;
98 } 100 }
99 101
100 bool CastSocket::ExtractPeerCert(std::string* cert) {
101 CHECK(peer_cert_.empty());
102 net::SSLInfo ssl_info;
103 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get())
104 return false;
105 bool result = net::X509Certificate::GetDEREncoded(
106 ssl_info.cert->os_cert_handle(), cert);
107 if (result)
108 DVLOG(1) << "Successfully extracted peer certificate: " << *cert;
109 return result;
110 }
111
112 scoped_ptr<net::TCPClientSocket> CastSocket::CreateTcpSocket() { 102 scoped_ptr<net::TCPClientSocket> CastSocket::CreateTcpSocket() {
113 net::AddressList addresses(ip_endpoint_); 103 net::AddressList addresses(ip_endpoint_);
114 scoped_ptr<net::TCPClientSocket> tcp_socket( 104 scoped_ptr<net::TCPClientSocket> tcp_socket(
115 new net::TCPClientSocket(addresses, net_log_, net_log_source_)); 105 new net::TCPClientSocket(addresses, net_log_, net_log_source_));
116 // Enable keepalive 106 // Enable keepalive
117 tcp_socket->SetKeepAlive(true, kTcpKeepAliveDelaySecs); 107 tcp_socket->SetKeepAlive(true, kTcpKeepAliveDelaySecs);
118 return tcp_socket.Pass(); 108 return tcp_socket.Pass();
119 } 109 }
120 110
121 scoped_ptr<net::SSLClientSocket> CastSocket::CreateSslSocket() { 111 scoped_ptr<net::SSLClientSocket> CastSocket::CreateSslSocket() {
(...skipping 17 matching lines...) Expand all
139 129
140 scoped_ptr<net::ClientSocketHandle> connection(new net::ClientSocketHandle); 130 scoped_ptr<net::ClientSocketHandle> connection(new net::ClientSocketHandle);
141 connection->SetSocket(tcp_socket_.PassAs<net::StreamSocket>()); 131 connection->SetSocket(tcp_socket_.PassAs<net::StreamSocket>());
142 net::HostPortPair host_and_port = net::HostPortPair::FromIPEndPoint( 132 net::HostPortPair host_and_port = net::HostPortPair::FromIPEndPoint(
143 ip_endpoint_); 133 ip_endpoint_);
144 134
145 return net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket( 135 return net::ClientSocketFactory::GetDefaultFactory()->CreateSSLClientSocket(
146 connection.Pass(), host_and_port, ssl_config, context); 136 connection.Pass(), host_and_port, ssl_config, context);
147 } 137 }
148 138
139 bool CastSocket::ExtractPeerCert(std::string* cert) {
140 DCHECK(cert);
141 DCHECK(peer_cert_.empty());
142 net::SSLInfo ssl_info;
143 if (!socket_->GetSSLInfo(&ssl_info) || !ssl_info.cert.get())
144 return false;
145 bool result = net::X509Certificate::GetDEREncoded(
146 ssl_info.cert->os_cert_handle(), cert);
147 if (result)
148 DVLOG(1) << "Successfully extracted peer certificate: " << *cert;
149 return result;
150 }
151
152 int CastSocket::SendAuthChallenge() {
153 CastMessage challenge_message;
154 CreateAuthChallengeMessage(&challenge_message);
155 DVLOG(1) << "Sending challenge: " << CastMessageToString(challenge_message);
156 return SendMessageInternal(
157 challenge_message,
158 base::Bind(&CastSocket::OnChallengeEvent, AsWeakPtr()));
159 }
160
161 int CastSocket::ReadAuthChallengeReply() {
162 return ReadData();
163 }
164
149 void CastSocket::OnConnectComplete(int result) { 165 void CastSocket::OnConnectComplete(int result) {
150 int rv = DoConnectLoop(result); 166 int rv = DoConnectLoop(result);
151 if (rv != net::ERR_IO_PENDING) 167 if (rv != net::ERR_IO_PENDING)
152 DoConnectCallback(rv); 168 DoConnectCallback(rv);
153 } 169 }
154 170
171 void CastSocket::OnChallengeEvent(int result) {
172 // result >= 0 means read or write succeeded synchronously.
173 int rv = DoConnectLoop(result >= 0 ? net::OK : result);
174 if (rv != net::ERR_IO_PENDING)
175 DoConnectCallback(rv);
176 }
177
155 void CastSocket::Connect(const net::CompletionCallback& callback) { 178 void CastSocket::Connect(const net::CompletionCallback& callback) {
156 DCHECK(CalledOnValidThread()); 179 DCHECK(CalledOnValidThread());
157 int result = net::ERR_CONNECTION_FAILED; 180 int result = net::ERR_CONNECTION_FAILED;
158 DVLOG(1) << "Connect readyState = " << ready_state_; 181 DVLOG(1) << "Connect readyState = " << ready_state_;
159 if (ready_state_ != READY_STATE_NONE) { 182 if (ready_state_ != READY_STATE_NONE) {
160 callback.Run(result); 183 callback.Run(result);
161 return; 184 return;
162 } 185 }
163 if (!ParseChannelUrl(url_)) { 186 if (!ParseChannelUrl(url_)) {
164 CloseWithError(cast_channel::CHANNEL_ERROR_CONNECT_ERROR); 187 CloseWithError(cast_channel::CHANNEL_ERROR_CONNECT_ERROR);
165 // TODO(mfoltz): Signal channel errors via |callback|
166 callback.Run(result); 188 callback.Run(result);
167 return; 189 return;
168 } 190 }
169 connect_callback_ = callback; 191 connect_callback_ = callback;
170 next_state_ = CONN_STATE_TCP_CONNECT; 192 next_state_ = CONN_STATE_TCP_CONNECT;
171 int rv = DoConnectLoop(net::OK); 193 int rv = DoConnectLoop(net::OK);
172 if (rv != net::ERR_IO_PENDING) 194 if (rv != net::ERR_IO_PENDING)
173 DoConnectCallback(rv); 195 DoConnectCallback(rv);
174 } 196 }
175 197
(...skipping 22 matching lines...) Expand all
198 case CONN_STATE_TCP_CONNECT_COMPLETE: 220 case CONN_STATE_TCP_CONNECT_COMPLETE:
199 rv = DoTcpConnectComplete(rv); 221 rv = DoTcpConnectComplete(rv);
200 break; 222 break;
201 case CONN_STATE_SSL_CONNECT: 223 case CONN_STATE_SSL_CONNECT:
202 DCHECK_EQ(net::OK, rv); 224 DCHECK_EQ(net::OK, rv);
203 rv = DoSslConnect(); 225 rv = DoSslConnect();
204 break; 226 break;
205 case CONN_STATE_SSL_CONNECT_COMPLETE: 227 case CONN_STATE_SSL_CONNECT_COMPLETE:
206 rv = DoSslConnectComplete(rv); 228 rv = DoSslConnectComplete(rv);
207 break; 229 break;
230 case CONN_STATE_AUTH_CHALLENGE_SEND:
231 rv = DoAuthChallengeSend();
232 break;
233 case CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE:
234 rv = DoAuthChallengeSendComplete(rv);
235 break;
236 case CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE:
237 rv = DoAuthChallengeReplyComplete(rv);
238 break;
239
208 default: 240 default:
209 NOTREACHED() << "BUG in CastSocket state machine code"; 241 NOTREACHED() << "BUG in CastSocket state machine code";
210 break; 242 break;
211 } 243 }
212 } while (rv != net::ERR_IO_PENDING && next_state_ != CONN_STATE_NONE); 244 } while (rv != net::ERR_IO_PENDING && next_state_ != CONN_STATE_NONE);
213 // Get out of the loop either when: 245 // Get out of the loop either when:
214 // a. A network operation is pending, OR 246 // a. A network operation is pending, OR
215 // b. The Do* method called did not change state 247 // b. The Do* method called did not change state
216 248
217 return rv; 249 return rv;
218 } 250 }
219 251
220 int CastSocket::DoTcpConnect() { 252 int CastSocket::DoTcpConnect() {
253 DVLOG(1) << "DoTcpConnect";
221 next_state_ = CONN_STATE_TCP_CONNECT_COMPLETE; 254 next_state_ = CONN_STATE_TCP_CONNECT_COMPLETE;
222 tcp_socket_ = CreateTcpSocket(); 255 tcp_socket_ = CreateTcpSocket();
223 return tcp_socket_->Connect( 256 return tcp_socket_->Connect(
224 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr())); 257 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr()));
225 } 258 }
226 259
227 int CastSocket::DoTcpConnectComplete(int result) { 260 int CastSocket::DoTcpConnectComplete(int result) {
261 DVLOG(1) << "DoTcpConnectComplete: " << result;
228 if (result == net::OK) 262 if (result == net::OK)
229 next_state_ = CONN_STATE_SSL_CONNECT; 263 next_state_ = CONN_STATE_SSL_CONNECT;
230 return result; 264 return result;
231 } 265 }
232 266
233 int CastSocket::DoSslConnect() { 267 int CastSocket::DoSslConnect() {
268 DVLOG(1) << "DoSslConnect";
234 next_state_ = CONN_STATE_SSL_CONNECT_COMPLETE; 269 next_state_ = CONN_STATE_SSL_CONNECT_COMPLETE;
235 socket_ = CreateSslSocket(); 270 socket_ = CreateSslSocket();
236 return socket_->Connect( 271 return socket_->Connect(
237 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr())); 272 base::Bind(&CastSocket::OnConnectComplete, AsWeakPtr()));
238 } 273 }
239 274
240 int CastSocket::DoSslConnectComplete(int result) { 275 int CastSocket::DoSslConnectComplete(int result) {
241 // TODO(mfoltz,munjal): Authenticate the channel if is_secure_ == true. 276 DVLOG(1) << "DoSslConnectComplete: " << result;
242 if (result == net::ERR_CERT_AUTHORITY_INVALID && 277 if (result == net::ERR_CERT_AUTHORITY_INVALID &&
243 peer_cert_.empty() && 278 peer_cert_.empty() &&
244 ExtractPeerCert(&peer_cert_)) { 279 ExtractPeerCert(&peer_cert_)) {
245 next_state_ = CONN_STATE_TCP_CONNECT; 280 next_state_ = CONN_STATE_TCP_CONNECT;
281 } else if (result == net::OK && auth_required_) {
282 next_state_ = CONN_STATE_AUTH_CHALLENGE_SEND;
246 } 283 }
247 return result; 284 return result;
248 } 285 }
249 286
287 int CastSocket::DoAuthChallengeSend() {
288 DVLOG(1) << "DoAuthChallengeSend";
289 next_state_ = CONN_STATE_AUTH_CHALLENGE_SEND_COMPLETE;
290 return SendAuthChallenge();
291 }
292
293 int CastSocket::DoAuthChallengeSendComplete(int result) {
294 DVLOG(1) << "DoAuthChallengeSendComplete: " << result;
295 if (result != net::OK)
296 return result;
297 next_state_ = CONN_STATE_AUTH_CHALLENGE_REPLY_COMPLETE;
298 return ReadAuthChallengeReply();
299 }
300
301 int CastSocket::DoAuthChallengeReplyComplete(int result) {
302 DVLOG(1) << "DoAuthChallengeReplyComplete: " << result;
303 if (result != net::OK)
304 return result;
305 if (!VerifyChallengeReply())
306 return net::ERR_FAILED;
307 DVLOG(1) << "Auth challenge verification succeeded";
308 return net::OK;
309 }
310
311 bool CastSocket::VerifyChallengeReply() {
312 return AuthenticateChallengeReply(*challenge_reply_.get(), peer_cert_);
313 }
314
250 void CastSocket::DoConnectCallback(int result) { 315 void CastSocket::DoConnectCallback(int result) {
251 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED; 316 ready_state_ = (result == net::OK) ? READY_STATE_OPEN : READY_STATE_CLOSED;
252 error_state_ = (result == net::OK) ? 317 error_state_ = (result == net::OK) ?
253 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR; 318 CHANNEL_ERROR_NONE : CHANNEL_ERROR_CONNECT_ERROR;
254 base::ResetAndReturn(&connect_callback_).Run(result); 319 base::ResetAndReturn(&connect_callback_).Run(result);
255 if (result == net::OK) 320 if (result == net::OK)
256 ReadData(); 321 ReadData();
257 } 322 }
258 323
259 void CastSocket::Close(const net::CompletionCallback& callback) { 324 void CastSocket::Close(const net::CompletionCallback& callback) {
260 DCHECK(CalledOnValidThread()); 325 DCHECK(CalledOnValidThread());
261 DVLOG(1) << "Close ReadyState = " << ready_state_; 326 DVLOG(1) << "Close ReadyState = " << ready_state_;
262 tcp_socket_.reset(NULL); 327 tcp_socket_.reset(NULL);
263 socket_.reset(NULL); 328 socket_.reset(NULL);
264 cert_verifier_.reset(NULL); 329 cert_verifier_.reset(NULL);
265 transport_security_state_.reset(NULL); 330 transport_security_state_.reset(NULL);
266 ready_state_ = READY_STATE_CLOSED; 331 ready_state_ = READY_STATE_CLOSED;
267 callback.Run(net::OK); 332 callback.Run(net::OK);
268 } 333 }
269 334
270 void CastSocket::SendMessage(const MessageInfo& message, 335 void CastSocket::SendMessage(const MessageInfo& message,
271 const net::CompletionCallback& callback) { 336 const net::CompletionCallback& callback) {
272 DCHECK(CalledOnValidThread()); 337 DCHECK(CalledOnValidThread());
273 DVLOG(1) << "Send ReadyState " << ready_state_; 338 DVLOG(1) << "Send ReadyState " << ready_state_;
274 int result = net::ERR_FAILED; 339 int result = net::ERR_FAILED;
275 if (ready_state_ != READY_STATE_OPEN) { 340 if (ready_state_ != READY_STATE_OPEN) {
276 callback.Run(result); 341 callback.Run(result);
277 return; 342 return;
278 } 343 }
279 WriteRequest write_request(callback);
280 CastMessage message_proto; 344 CastMessage message_proto;
281 if (!MessageInfoToCastMessage(message, &message_proto) || 345 if (!MessageInfoToCastMessage(message, &message_proto)) {
282 !write_request.SetContent(message_proto)) {
283 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE); 346 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
284 // TODO(mfoltz): Do a better job of signaling cast_channel errors to the 347 // TODO(mfoltz): Do a better job of signaling cast_channel errors to the
285 // caller. 348 // caller.
286 callback.Run(net::OK); 349 callback.Run(net::OK);
287 return; 350 return;
288 } 351 }
289 write_queue_.push(write_request); 352 SendMessageInternal(message_proto, callback);
290 WriteData(); 353 /*
354 if (result >= 0) {
355 callback.Run(result);
356 } else if (result != net::ERR_IO_PENDING && result != net::OK) {
357 CloseWithError(cast_channel::CHANNEL_ERROR_INVALID_MESSAGE);
358 callback.Run(net::ERR_FAILED);
359 }*/
291 } 360 }
292 361
293 void CastSocket::WriteData() { 362 int CastSocket::SendMessageInternal(const CastMessage& message_proto,
363 const net::CompletionCallback& callback) {
364 WriteRequest write_request(callback);
365 if (!write_request.SetContent(message_proto))
366 return net::ERR_FAILED;
367 write_queue_.push(write_request);
368 return WriteData();
369 }
370
371 int CastSocket::WriteData() {
294 DCHECK(CalledOnValidThread()); 372 DCHECK(CalledOnValidThread());
295 DVLOG(1) << "WriteData q = " << write_queue_.size(); 373 DVLOG(1) << "WriteData q = " << write_queue_.size();
296 if (write_queue_.empty() || write_callback_pending_) 374 if (write_queue_.empty() || write_callback_pending_)
297 return; 375 return net::ERR_FAILED;
298 376
299 WriteRequest& request = write_queue_.front(); 377 WriteRequest& request = write_queue_.front();
300 if (ready_state_ != READY_STATE_OPEN) {
301 request.callback.Run(net::ERR_FAILED);
302 return;
303 }
304 378
305 DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() << 379 DVLOG(1) << "WriteData byte_count = " << request.io_buffer->size() <<
306 " bytes_written " << request.io_buffer->BytesConsumed(); 380 " bytes_written " << request.io_buffer->BytesConsumed();
307 381
308 write_callback_pending_ = true; 382 write_callback_pending_ = true;
309 int result = socket_->Write( 383 int result = socket_->Write(
310 request.io_buffer.get(), 384 request.io_buffer.get(),
311 request.io_buffer->BytesRemaining(), 385 request.io_buffer->BytesRemaining(),
312 base::Bind(&CastSocket::OnWriteData, AsWeakPtr())); 386 base::Bind(&CastSocket::OnWriteData, AsWeakPtr()));
313 387
314 DVLOG(1) << "WriteData result = " << result;
315
316 if (result != net::ERR_IO_PENDING) 388 if (result != net::ERR_IO_PENDING)
317 OnWriteData(result); 389 OnWriteData(result);
390
391 return result;
318 } 392 }
319 393
320 void CastSocket::OnWriteData(int result) { 394 void CastSocket::OnWriteData(int result) {
321 DCHECK(CalledOnValidThread()); 395 DCHECK(CalledOnValidThread());
322 DVLOG(1) << "OnWriteComplete result = " << result; 396 DVLOG(1) << "OnWriteComplete result = " << result;
323 DCHECK(write_callback_pending_); 397 DCHECK(write_callback_pending_);
324 DCHECK(!write_queue_.empty()); 398 DCHECK(!write_queue_.empty());
325 write_callback_pending_ = false; 399 write_callback_pending_ = false;
326 WriteRequest& request = write_queue_.front(); 400 WriteRequest& request = write_queue_.front();
327 scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer; 401 scoped_refptr<net::DrainableIOBuffer> io_buffer = request.io_buffer;
(...skipping 23 matching lines...) Expand all
351 425
352 if (result < 0) { 426 if (result < 0) {
353 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 427 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
354 return; 428 return;
355 } 429 }
356 430
357 if (!write_queue_.empty()) 431 if (!write_queue_.empty())
358 WriteData(); 432 WriteData();
359 } 433 }
360 434
361 void CastSocket::ReadData() { 435 int CastSocket::ReadData() {
362 DCHECK(CalledOnValidThread()); 436 DCHECK(CalledOnValidThread());
363 if (!socket_.get() || ready_state_ != READY_STATE_OPEN) { 437 if (!socket_.get())
364 return; 438 return net::ERR_FAILED;
365 }
366 DCHECK(!read_callback_pending_); 439 DCHECK(!read_callback_pending_);
367 read_callback_pending_ = true; 440 read_callback_pending_ = true;
368 // Figure out if we are reading the header or body, and the remaining bytes. 441 // Figure out if we are reading the header or body, and the remaining bytes.
369 uint32 num_bytes_to_read = 0; 442 uint32 num_bytes_to_read = 0;
370 if (header_read_buffer_->RemainingCapacity() > 0) { 443 if (header_read_buffer_->RemainingCapacity() > 0) {
371 current_read_buffer_ = header_read_buffer_; 444 current_read_buffer_ = header_read_buffer_;
372 num_bytes_to_read = header_read_buffer_->RemainingCapacity(); 445 num_bytes_to_read = header_read_buffer_->RemainingCapacity();
373 DCHECK_LE(num_bytes_to_read, kMessageHeaderSize); 446 DCHECK_LE(num_bytes_to_read, kMessageHeaderSize);
374 } else { 447 } else {
375 DCHECK_GT(current_message_size_, 0U); 448 DCHECK_GT(current_message_size_, 0U);
376 num_bytes_to_read = current_message_size_ - body_read_buffer_->offset(); 449 num_bytes_to_read = current_message_size_ - body_read_buffer_->offset();
377 current_read_buffer_ = body_read_buffer_; 450 current_read_buffer_ = body_read_buffer_;
378 DCHECK_LE(num_bytes_to_read, kMaxMessageSize); 451 DCHECK_LE(num_bytes_to_read, kMaxMessageSize);
379 } 452 }
380 DCHECK_GT(num_bytes_to_read, 0U); 453 DCHECK_GT(num_bytes_to_read, 0U);
381 // We read up to num_bytes_to_read into |current_read_buffer_|. 454 // We read up to num_bytes_to_read into |current_read_buffer_|.
382 int result = socket_->Read( 455 int result = socket_->Read(
383 current_read_buffer_.get(), 456 current_read_buffer_.get(),
384 num_bytes_to_read, 457 num_bytes_to_read,
385 base::Bind(&CastSocket::OnReadData, AsWeakPtr())); 458 base::Bind(&CastSocket::OnReadData, AsWeakPtr()));
386 DVLOG(1) << "ReadData result = " << result; 459 DVLOG(1) << "ReadData result = " << result;
387 if (result > 0) { 460 if (result > 0) {
388 OnReadData(result); 461 OnReadData(result);
389 } else if (result != net::ERR_IO_PENDING) { 462 } else if (result != net::ERR_IO_PENDING) {
390 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 463 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
391 } 464 }
465 return result;
392 } 466 }
393 467
394 void CastSocket::OnReadData(int result) { 468 void CastSocket::OnReadData(int result) {
395 DCHECK(CalledOnValidThread()); 469 DCHECK(CalledOnValidThread());
396 DVLOG(1) << "OnReadData result = " << result << 470 DVLOG(1) << "OnReadData result = " << result
397 " header offset = " << header_read_buffer_->offset() << 471 << " header offset = " << header_read_buffer_->offset()
398 " body offset = " << body_read_buffer_->offset(); 472 << " body offset = " << body_read_buffer_->offset();
399 read_callback_pending_ = false; 473 read_callback_pending_ = false;
400 if (result <= 0) { 474 if (result <= 0) {
401 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR); 475 CloseWithError(CHANNEL_ERROR_SOCKET_ERROR);
402 return; 476 return;
403 } 477 }
404 // We read some data. Move the offset in the current buffer forward. 478 // We read some data. Move the offset in the current buffer forward.
405 DCHECK_LE(current_read_buffer_->offset() + result, 479 DCHECK_LE(current_read_buffer_->offset() + result,
406 current_read_buffer_->capacity()); 480 current_read_buffer_->capacity());
407 current_read_buffer_->set_offset(current_read_buffer_->offset() + result); 481 current_read_buffer_->set_offset(current_read_buffer_->offset() + result);
408 482
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 525
452 bool CastSocket::ParseMessageFromBody() { 526 bool CastSocket::ParseMessageFromBody() {
453 DCHECK(CalledOnValidThread()); 527 DCHECK(CalledOnValidThread());
454 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()), 528 DCHECK_EQ(static_cast<uint32>(body_read_buffer_->offset()),
455 current_message_size_); 529 current_message_size_);
456 CastMessage message_proto; 530 CastMessage message_proto;
457 if (!message_proto.ParseFromArray( 531 if (!message_proto.ParseFromArray(
458 body_read_buffer_->StartOfBuffer(), 532 body_read_buffer_->StartOfBuffer(),
459 current_message_size_)) 533 current_message_size_))
460 return false; 534 return false;
461 DVLOG(1) << "Parsed message " << MessageProtoToString(message_proto); 535 DVLOG(1) << "Parsed message " << CastMessageToString(message_proto);
462 if (delegate_) { 536 // If the message is an auth message then we handle it internally.
537 if (IsAuthMessage(message_proto)) {
538 challenge_reply_.reset(new CastMessage(message_proto));
539 OnChallengeEvent(net::OK);
540 } else if (delegate_) {
463 MessageInfo message; 541 MessageInfo message;
464 if (!CastMessageToMessageInfo(message_proto, &message)) 542 if (!CastMessageToMessageInfo(message_proto, &message))
465 return false; 543 return false;
466 delegate_->OnMessage(this, message); 544 delegate_->OnMessage(this, message);
467 } 545 }
468 return true; 546 return true;
469 } 547 }
470 548
471 // static 549 // static
472 bool CastSocket::Serialize(const CastMessage& message_proto, 550 bool CastSocket::Serialize(const CastMessage& message_proto,
(...skipping 16 matching lines...) Expand all
489 socket_.reset(NULL); 567 socket_.reset(NULL);
490 ready_state_ = READY_STATE_CLOSED; 568 ready_state_ = READY_STATE_CLOSED;
491 error_state_ = error; 569 error_state_ = error;
492 if (delegate_) 570 if (delegate_)
493 delegate_->OnError(this, error); 571 delegate_->OnError(this, error);
494 } 572 }
495 573
496 bool CastSocket::ParseChannelUrl(const GURL& url) { 574 bool CastSocket::ParseChannelUrl(const GURL& url) {
497 DVLOG(1) << "url = " + url.spec(); 575 DVLOG(1) << "url = " + url.spec();
498 if (url.SchemeIs(kCastInsecureScheme)) { 576 if (url.SchemeIs(kCastInsecureScheme)) {
499 is_secure_ = false; 577 auth_required_ = false;
500 } else if (url.SchemeIs(kCastSecureScheme)) { 578 } else if (url.SchemeIs(kCastSecureScheme)) {
501 is_secure_ = true; 579 auth_required_ = true;
502 } else { 580 } else {
503 return false; 581 return false;
504 } 582 }
505 // TODO(mfoltz): Manual parsing, yech. Register cast[s] as standard schemes? 583 // TODO(mfoltz): Manual parsing, yech. Register cast[s] as standard schemes?
506 // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets? 584 // TODO(mfoltz): Test for IPv6 addresses. Brackets or no brackets?
507 // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 link-local 585 // TODO(mfoltz): Maybe enforce restriction to IPv4 private and IPv6 link-local
508 // networks 586 // networks
509 const std::string& path = url.path(); 587 const std::string& path = url.path();
510 // Shortest possible: //A:B 588 // Shortest possible: //A:B
511 if (path.size() < 5) { 589 if (path.size() < 5) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data), 655 io_buffer = new net::DrainableIOBuffer(new net::StringIOBuffer(message_data),
578 message_data.size()); 656 message_data.size());
579 return true; 657 return true;
580 } 658 }
581 659
582 CastSocket::WriteRequest::~WriteRequest() { } 660 CastSocket::WriteRequest::~WriteRequest() { }
583 661
584 } // namespace cast_channel 662 } // namespace cast_channel
585 } // namespace api 663 } // namespace api
586 } // namespace extensions 664 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698