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