15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifndef EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_ 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_ 74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <queue> 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string> 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/basictypes.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/cancelable_callback.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/gtest_prod_util.h" 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/ref_counted.h" 150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "base/threading/thread_checker.h" 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/timer/timer.h" 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/api_resource.h" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/api_resource_manager.h" 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/common/api/cast_channel.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/api/cast_channel/logging.pb.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/base/completion_callback.h" 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/base/io_buffer.h" 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/base/ip_endpoint.h" 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "net/base/net_log.h" 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace net { 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class AddressList; 288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class CertVerifier; 298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class SSLClientSocket; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class StreamSocket; 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class TCPClientSocket; 328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class TransportSecurityState; 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace extensions { 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace core_api { 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace cast_channel { 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class CastMessage; 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class Logger; 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)struct LastErrors; 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass MessageFramer; 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// This class implements a channel between Chrome and a Cast device using a TCP 450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// socket with SSL. The channel may authenticate that the receiver is a genuine 460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Cast device. All CastSocket objects must be used only on the IO thread. 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// NOTE: Not called "CastChannel" to reduce confusion with the generated API 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// code. 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// TODO(kmarshall): Inherit from CastSocket and rename to CastSocketImpl. 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class CastSocket : public ApiResource { 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Object to be informed of incoming messages and errors. The CastSocket 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // that owns the delegate must not be deleted by it, only by the 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // ApiResourceManager or in the callback to Close(). 564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) class Delegate { 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // An error occurred on the channel. |last_errors| contains the last errors 596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // logged for the channel from the implementation. 606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) virtual void OnError(const CastSocket* socket, 616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ChannelError error_state, 626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const LastErrors& last_errors) = 0; 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // A message was received on the channel. 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void OnMessage(const CastSocket* socket, 654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const MessageInfo& message) = 0; 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) protected: 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~Delegate() {} 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }; 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Creates a new CastSocket that connects to |ip_endpoint| with 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // |channel_auth|. |owner_extension_id| is the id of the extension that opened 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // the socket. |channel_auth| must not be CHANNEL_AUTH_NONE. 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) CastSocket(const std::string& owner_extension_id, 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const net::IPEndPoint& ip_endpoint, 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ChannelAuthType channel_auth, 778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) CastSocket::Delegate* delegate, 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) net::NetLog* net_log, 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::TimeDelta& connect_timeout, 806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const scoped_refptr<Logger>& logger); 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Ensures that the socket is closed. 834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual ~CastSocket(); 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // The IP endpoint for the destination of the channel. 860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const net::IPEndPoint& ip_endpoint() const { return ip_endpoint_; } 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // The authentication level requested for the channel. 890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ChannelAuthType channel_auth() const { return channel_auth_; } 900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Returns a cast:// or casts:// URL for the channel endpoint. 920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // For backwards compatibility. 930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch std::string CastUrl() const; 944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Channel id for the ApiResourceManager. 960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int id() const { return channel_id_; } 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Sets the channel id. 990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) void set_id(int channel_id) { channel_id_ = channel_id; } 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Returns the state of the channel. Virtual for testing. 1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual ReadyState ready_state() const; 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns the last error that occurred on this channel, or 1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // CHANNEL_ERROR_NONE if no error has occurred. Virtual for testing. 1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch virtual ChannelError error_state() const; 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Connects the channel to the peer. If successful, the channel will be in 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // READY_STATE_OPEN. DO NOT delete the CastSocket object in |callback|. 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Instead use Close(). 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Connect(const net::CompletionCallback& callback); 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Sends a message over a connected channel. The channel must be in 1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // READY_STATE_OPEN. 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Note that if an error occurs the following happens: 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 1. Completion callbacks for all pending writes are invoked with error. 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 2. Delegate::OnError is called once. 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // 3. CastSocket is closed. 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // DO NOT delete the CastSocket object in |callback|. Instead use Close(). 1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void SendMessage(const MessageInfo& message, 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const net::CompletionCallback& callback); 1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Closes the channel if not already closed. On completion, the channel will 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // be in READY_STATE_CLOSED. 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // It is fine to delete the CastSocket object in |callback|. 1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Close(const net::CompletionCallback& callback); 1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) friend class ApiResourceManager<CastSocket>; 1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) friend class CastSocketTest; 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) friend class TestCastSocket; 1351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) static const char* service_name() { return "CastSocketManager"; } 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Creates an instance of TCPClientSocket. 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual scoped_ptr<net::TCPClientSocket> CreateTcpSocket(); 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Creates an instance of SSLClientSocket with the given underlying |socket|. 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual scoped_ptr<net::SSLClientSocket> CreateSslSocket( 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<net::StreamSocket> socket); 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Extracts peer certificate from SSLClientSocket instance when the socket 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // is in cert error state. 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns whether certificate is successfully extracted. 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool ExtractPeerCert(std::string* cert); 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Verifies whether the challenge reply received from the peer is valid: 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 1. Signature in the reply is valid. 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 2. Certificate is rooted to a trusted CA. 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool VerifyChallengeReply(); 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Invoked by a cancelable closure when connection setup time 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // exceeds the interval specified at |connect_timeout|. 1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void OnConnectTimeout(); 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ///////////////////////////////////////////////////////////////////////////// 1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Following methods work together to implement the following flow: 1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // 1. Create a new TCP socket and connect to it 1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // 2. Create a new SSL socket and try connecting to it 1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // 3. If connection fails due to invalid cert authority, then extract the 1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // peer certificate from the error. 1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // 4. Whitelist the peer certificate and try #1 and #2 again. 1631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // 5. If SSL socket is connected successfully, and if protocol is casts:// 1641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // then issue an auth challenge request. 1651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // 6. Validate the auth challenge response. 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Main method that performs connection state transitions. 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void DoConnectLoop(int result); 1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Each of the below Do* method is executed in the corresponding 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // connection state. For example when connection state is TCP_CONNECT 1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // DoTcpConnect is called, and so on. 1728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int DoTcpConnect(); 1738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int DoTcpConnectComplete(int result); 1748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int DoSslConnect(); 1758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) int DoSslConnectComplete(int result); 1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int DoAuthChallengeSend(); 1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int DoAuthChallengeSendComplete(int result); 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void DoAuthChallengeSendWriteComplete(int result); 1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int DoAuthChallengeReplyComplete(int result); 1808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) ///////////////////////////////////////////////////////////////////////////// 1818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ///////////////////////////////////////////////////////////////////////////// 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Following methods work together to implement write flow. 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Main method that performs write flow state transitions. 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void DoWriteLoop(int result); 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Each of the below Do* method is executed in the corresponding 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // write state. For example when write state is WRITE_STATE_WRITE_COMPLETE 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // DowriteComplete is called, and so on. 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int DoWrite(); 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int DoWriteComplete(int result); 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int DoWriteCallback(); 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int DoWriteError(int result); 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ///////////////////////////////////////////////////////////////////////////// 1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ///////////////////////////////////////////////////////////////////////////// 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Following methods work together to implement read flow. 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Main method that performs write flow state transitions. 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void DoReadLoop(int result); 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Each of the below Do* method is executed in the corresponding 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // write state. For example when write state is READ_STATE_READ_COMPLETE 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // DoReadComplete is called, and so on. 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int DoRead(); 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int DoReadComplete(int result); 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int DoReadCallback(); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int DoReadError(int result); 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ///////////////////////////////////////////////////////////////////////////// 2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Runs the external connection callback and resets it. 2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) void DoConnectCallback(int result); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Adds |message| to the write queue and starts the write loop if needed. 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void SendCastMessageInternal(const CastMessage& message, 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const net::CompletionCallback& callback); 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void PostTaskToStartConnectLoop(int result); 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void PostTaskToStartReadLoop(); 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void StartReadLoop(); 2186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Closes socket, signaling the delegate that |error| has occurred. 2196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void CloseWithError(); 2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Frees resources and cancels pending callbacks. |ready_state_| will be set 2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // READY_STATE_CLOSED on completion. A no-op if |ready_state_| is already 2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // READY_STATE_CLOSED. 2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void CloseInternal(); 2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Runs pending callbacks that are passed into us to notify API clients that 2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // pending operations will fail because the socket has been closed. 2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) void RunPendingCallbacksOnClose(); 2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Serializes the content of message_proto (with a header) to |message_data|. 2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static bool Serialize(const CastMessage& message_proto, 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string* message_data); 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual bool CalledOnValidThread() const; 2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual base::Timer* GetTimer(); 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void SetConnectState(proto::ConnectionState connect_state); 2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void SetReadyState(ReadyState ready_state); 2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) void SetErrorState(ChannelError error_state); 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void SetReadState(proto::ReadState read_state); 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void SetWriteState(proto::WriteState write_state); 2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::ThreadChecker thread_checker_; 2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // The id of the channel. 2440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int channel_id_; 2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // The IP endpoint that the the channel is connected to. 2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch net::IPEndPoint ip_endpoint_; 2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // Receiver authentication requested for the channel. 2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ChannelAuthType channel_auth_; 2504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Delegate to inform of incoming messages and errors. 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Delegate* delegate_; 2524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // IOBuffer for reading the message header. 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<net::GrowableIOBuffer> read_buffer_; 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<MessageFramer> framer_; 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // The NetLog for this service. 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net::NetLog* net_log_; 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // The NetLog source for this service. 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net::NetLog::Source net_log_source_; 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Logger used to track multiple CastSockets. Does NOT own this object. 2636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<Logger> logger_; 2646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // CertVerifier is owned by us but should be deleted AFTER SSLClientSocket 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // since in some cases the destructor of SSLClientSocket may call a method 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // to cancel a cert verification request. 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<net::CertVerifier> cert_verifier_; 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<net::TransportSecurityState> transport_security_state_; 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Owned ptr to the underlying TCP socket. 2728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<net::TCPClientSocket> tcp_socket_; 2738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Owned ptr to the underlying SSL socket. 2748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scoped_ptr<net::SSLClientSocket> socket_; 2758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Certificate of the peer. This field may be empty if the peer 2768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // certificate is not yet fetched. 2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) std::string peer_cert_; 2781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Reply received from the receiver to a challenge request. 2791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) scoped_ptr<CastMessage> challenge_reply_; 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Callback invoked when the socket is connected or fails to connect. 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net::CompletionCallback connect_callback_; 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Callback invoked by |connect_timeout_timer_| to cancel the connection. 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::CancelableClosure connect_timeout_callback_; 2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Duration to wait before timing out. 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::TimeDelta connect_timeout_; 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Timer invoked when the connection has timed out. 2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<base::Timer> connect_timeout_timer_; 2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Set when a timeout is triggered and the connection process has 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // canceled. 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool is_canceled_; 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<CastMessage> current_message_; 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Connection flow state machine state. 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proto::ConnectionState connect_state_; 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Write flow state machine state. 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proto::WriteState write_state_; 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Read flow state machine state. 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proto::ReadState read_state_; 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The last error encountered by the channel. 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ChannelError error_state_; 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The current status of the channel. 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadyState ready_state_; 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Task invoked to (re)start the connect loop. Canceled on entry to the 3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // connect loop. 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::CancelableClosure connect_loop_callback_; 3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Task invoked to send the auth challenge. Canceled when the auth challenge 3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // has been sent. 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::CancelableClosure send_auth_challenge_callback_; 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Callback invoked to (re)start the read loop. Canceled on entry to the read 3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // loop. 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::CancelableClosure read_loop_callback_; 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Holds a message to be written to the socket. |callback| is invoked when the 3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // message is fully written or an error occurrs. 3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) struct WriteRequest { 3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) explicit WriteRequest(const net::CompletionCallback& callback); 3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ~WriteRequest(); 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Sets the content of the request by serializing |message| into |io_buffer| 3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // and prepending the header. Must only be called once. 3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool SetContent(const CastMessage& message_proto); 3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) net::CompletionCallback callback; 3276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) std::string message_namespace; 3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) scoped_refptr<net::DrainableIOBuffer> io_buffer; 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) }; 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Queue of pending writes. The message at the front of the queue is the one 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // being written. 3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::queue<WriteRequest> write_queue_; 3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestFullSecureConnectionFlowAsync); 3354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestRead); 3360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadHeaderParseError); 3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestReadMany); 3380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch FRIEND_TEST_ALL_PREFIXES(CastSocketTest, TestWriteErrorLargeMessage); 3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CastSocket); 3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace cast_channel 3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace core_api 3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace extensions 3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif // EXTENSIONS_BROWSER_API_CAST_CHANNEL_CAST_SOCKET_H_ 346