// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/cast_channel/cast_socket.h"

#include <stdint.h>

#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/sys_byteorder.h"
#include "base/test/bind_test_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/timer/mock_timer.h"
#include "build/build_config.h"
#include "components/cast_channel/cast_auth_util.h"
#include "components/cast_channel/cast_framer.h"
#include "components/cast_channel/cast_message_util.h"
#include "components/cast_channel/cast_test_util.h"
#include "components/cast_channel/cast_transport.h"
#include "components/cast_channel/logger.h"
#include "components/cast_channel/proto/cast_channel.pb.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "crypto/rsa_private_key.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/cert/pem_tokenizer.h"
#include "net/socket/socket_test_util.h"
#include "net/socket/ssl_client_socket.h"
#include "net/socket/ssl_server_socket.h"
#include "net/socket/tcp_client_socket.h"
#include "net/socket/tcp_server_socket.h"
#include "net/ssl/ssl_info.h"
#include "net/ssl/ssl_server_config.h"
#include "net/test/cert_test_util.h"
#include "net/test/test_data_directory.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/network_context.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

const int64_t kDistantTimeoutMillis = 100000;  // 100 seconds (never hit).

using ::testing::A;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::InvokeArgument;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::_;

namespace cast_channel {
namespace {
const char kAuthNamespace[] = "urn:x-cast:com.google.cast.tp.deviceauth";

// Returns an auth challenge message inline.
CastMessage CreateAuthChallenge() {
  CastMessage output;
  CreateAuthChallengeMessage(&output, AuthContext::Create());
  return output;
}

// Returns an auth challenge response message inline.
CastMessage CreateAuthReply() {
  CastMessage output;
  output.set_protocol_version(CastMessage::CASTV2_1_0);
  output.set_source_id("sender-0");
  output.set_destination_id("receiver-0");
  output.set_payload_type(CastMessage::BINARY);
  output.set_payload_binary("abcd");
  output.set_namespace_(kAuthNamespace);
  return output;
}

CastMessage CreateTestMessage() {
  CastMessage test_message;
  test_message.set_protocol_version(CastMessage::CASTV2_1_0);
  test_message.set_namespace_("ns");
  test_message.set_source_id("source");
  test_message.set_destination_id("dest");
  test_message.set_payload_type(CastMessage::STRING);
  test_message.set_payload_utf8("payload");
  return test_message;
}

base::FilePath GetTestCertsDirectory() {
  base::FilePath path;
  base::PathService::Get(base::DIR_SOURCE_ROOT, &path);
  path = path.Append(FILE_PATH_LITERAL("components"));
  path = path.Append(FILE_PATH_LITERAL("test"));
  path = path.Append(FILE_PATH_LITERAL("data"));
  path = path.Append(FILE_PATH_LITERAL("cast_channel"));
  return path;
}

class MockTCPSocket : public net::MockTCPClientSocket {
 public:
  MockTCPSocket(bool do_nothing, net::SocketDataProvider* socket_provider)
      : net::MockTCPClientSocket(net::AddressList(), nullptr, socket_provider) {
    do_nothing_ = do_nothing;
    set_enable_read_if_ready(true);
  }

  int Connect(net::CompletionOnceCallback callback) override {
    if (do_nothing_) {
      // Stall the I/O event loop.
      return net::ERR_IO_PENDING;
    }
    return net::MockTCPClientSocket::Connect(std::move(callback));
  }

 private:
  bool do_nothing_;

  DISALLOW_COPY_AND_ASSIGN(MockTCPSocket);
};

class CompleteHandler {
 public:
  CompleteHandler() {}
  MOCK_METHOD1(OnCloseComplete, void(int result));
  MOCK_METHOD1(OnConnectComplete, void(CastSocket* socket));
  MOCK_METHOD1(OnWriteComplete, void(int result));
  MOCK_METHOD1(OnReadComplete, void(int result));

 private:
  DISALLOW_COPY_AND_ASSIGN(CompleteHandler);
};

class TestCastSocketBase : public CastSocketImpl {
 public:
  TestCastSocketBase(network::mojom::NetworkContext* network_context,
                     const CastSocketOpenParams& open_params,
                     Logger* logger)
      : CastSocketImpl(base::BindRepeating(
                           [](network::mojom::NetworkContext* network_context) {
                             return network_context;
                           },
                           network_context),
                       open_params,
                       logger,
                       AuthContext::Create()),
        verify_challenge_result_(true),
        verify_challenge_disallow_(false),
        mock_timer_(new base::MockOneShotTimer()) {
    SetPeerCertForTesting(
        net::ImportCertFromFile(GetTestCertsDirectory(), "self_signed.pem"));
  }
  ~TestCastSocketBase() override {}

  void SetVerifyChallengeResult(bool value) {
    verify_challenge_result_ = value;
  }

  void TriggerTimeout() { mock_timer_->Fire(); }

  bool TestVerifyChannelPolicyNone() {
    AuthResult authResult;
    return VerifyChannelPolicy(authResult);
  }

  void DisallowVerifyChallengeResult() { verify_challenge_disallow_ = true; }

 protected:
  bool VerifyChallengeReply() override {
    EXPECT_FALSE(verify_challenge_disallow_);
    return verify_challenge_result_;
  }

  base::OneShotTimer* GetTimer() override { return mock_timer_.get(); }

  // Simulated result of verifying challenge reply.
  bool verify_challenge_result_;
  bool verify_challenge_disallow_;
  std::unique_ptr<base::MockOneShotTimer> mock_timer_;

 private:
  DISALLOW_COPY_AND_ASSIGN(TestCastSocketBase);
};

class MockTestCastSocket : public TestCastSocketBase {
 public:
  static std::unique_ptr<MockTestCastSocket> CreateSecure(
      network::mojom::NetworkContext* network_context,
      const CastSocketOpenParams& open_params,
      Logger* logger) {
    return std::unique_ptr<MockTestCastSocket>(
        new MockTestCastSocket(network_context, open_params, logger));
  }

  using TestCastSocketBase::TestCastSocketBase;

  MockTestCastSocket(network::mojom::NetworkContext* network_context,
                     const CastSocketOpenParams& open_params,
                     Logger* logger)
      : TestCastSocketBase(network_context, open_params, logger) {}

  ~MockTestCastSocket() override {}

  void SetupMockTransport() {
    mock_transport_ = new MockCastTransport;
    SetTransportForTesting(base::WrapUnique(mock_transport_));
  }

  bool TestVerifyChannelPolicyAudioOnly() {
    AuthResult authResult;
    authResult.channel_policies |= AuthResult::POLICY_AUDIO_ONLY;
    return VerifyChannelPolicy(authResult);
  }

  MockCastTransport* GetMockTransport() {
    CHECK(mock_transport_);
    return mock_transport_;
  }

 private:
  MockCastTransport* mock_transport_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(MockTestCastSocket);
};

// TODO(https://crbug.com/928467):  Remove this class.
class TestSocketFactory : public net::ClientSocketFactory {
 public:
  explicit TestSocketFactory(net::IPEndPoint ip) : ip_(ip) {}
  ~TestSocketFactory() override = default;

  // Socket connection helpers.
  void SetupTcpConnect(net::IoMode mode, int result) {
    tcp_connect_data_.reset(new net::MockConnect(mode, result, ip_));
  }
  void SetupSslConnect(net::IoMode mode, int result) {
    ssl_connect_data_.reset(new net::MockConnect(mode, result, ip_));
  }

  // Socket I/O helpers.
  void AddWriteResult(const net::MockWrite& write) { writes_.push_back(write); }
  void AddWriteResult(net::IoMode mode, int result) {
    AddWriteResult(net::MockWrite(mode, result));
  }
  void AddWriteResultForData(net::IoMode mode, const std::string& msg) {
    AddWriteResult(mode, msg.size());
  }
  void AddReadResult(const net::MockRead& read) { reads_.push_back(read); }
  void AddReadResult(net::IoMode mode, int result) {
    AddReadResult(net::MockRead(mode, result));
  }
  void AddReadResultForData(net::IoMode mode, const std::string& data) {
    AddReadResult(net::MockRead(mode, data.c_str(), data.size()));
  }

  // Helpers for modifying other connection-related behaviors.
  void SetupTcpConnectUnresponsive() { tcp_unresponsive_ = true; }

  void SetTcpSocket(
      std::unique_ptr<net::TransportClientSocket> tcp_client_socket) {
    tcp_client_socket_ = std::move(tcp_client_socket);
  }

  void SetTLSSocketCreatedClosure(base::OnceClosure closure) {
    tls_socket_created_ = std::move(closure);
  }

  void Pause() {
    if (socket_data_provider_)
      socket_data_provider_->Pause();
    else
      socket_data_provider_paused_ = true;
  }

  void Resume() { socket_data_provider_->Resume(); }

 private:
  std::unique_ptr<net::DatagramClientSocket> CreateDatagramClientSocket(
      net::DatagramSocket::BindType,
      net::NetLog*,
      const net::NetLogSource&) override {
    NOTIMPLEMENTED();
    return nullptr;
  }
  std::unique_ptr<net::TransportClientSocket> CreateTransportClientSocket(
      const net::AddressList&,
      std::unique_ptr<net::SocketPerformanceWatcher>,
      net::NetLog*,
      const net::NetLogSource&) override {
    if (tcp_client_socket_)
      return std::move(tcp_client_socket_);

    if (tcp_unresponsive_) {
      socket_data_provider_ = std::make_unique<net::StaticSocketDataProvider>();
      return std::unique_ptr<net::TransportClientSocket>(
          new MockTCPSocket(true, socket_data_provider_.get()));
    } else {
      socket_data_provider_ =
          std::make_unique<net::StaticSocketDataProvider>(reads_, writes_);
      socket_data_provider_->set_connect_data(*tcp_connect_data_);
      if (socket_data_provider_paused_)
        socket_data_provider_->Pause();
      return std::unique_ptr<net::TransportClientSocket>(
          new MockTCPSocket(false, socket_data_provider_.get()));
    }
  }
  std::unique_ptr<net::SSLClientSocket> CreateSSLClientSocket(
      std::unique_ptr<net::StreamSocket> nested_socket,
      const net::HostPortPair& host_and_port,
      const net::SSLConfig& ssl_config,
      const net::SSLClientSocketContext& context) override {
    if (!ssl_connect_data_) {
      // Test isn't overriding SSL socket creation.
      return net::ClientSocketFactory::GetDefaultFactory()
          ->CreateSSLClientSocket(std::move(nested_socket), host_and_port,
                                  ssl_config, context);
    }
    ssl_socket_data_provider_ = std::make_unique<net::SSLSocketDataProvider>(
        ssl_connect_data_->mode, ssl_connect_data_->result);

    if (tls_socket_created_)
      std::move(tls_socket_created_).Run();

    return std::make_unique<net::MockSSLClientSocket>(
        std::move(nested_socket), net::HostPortPair(), net::SSLConfig(),
        ssl_socket_data_provider_.get());
  }
  std::unique_ptr<net::ProxyClientSocket> CreateProxyClientSocket(
      std::unique_ptr<net::StreamSocket> stream_socket,
      const std::string& user_agent,
      const net::HostPortPair& endpoint,
      const net::ProxyServer& proxy_server,
      net::HttpAuthController* http_auth_controller,
      bool tunnel,
      bool using_spdy,
      net::NextProto negotiated_protocol,
      net::ProxyDelegate* proxy_delegate,
      const net::NetworkTrafficAnnotationTag& traffic_annotation) override {
    NOTIMPLEMENTED();
    return nullptr;
  }

  net::IPEndPoint ip_;
  // Simulated connect data
  std::unique_ptr<net::MockConnect> tcp_connect_data_;
  std::unique_ptr<net::MockConnect> ssl_connect_data_;
  // Simulated read / write data
  std::vector<net::MockWrite> writes_;
  std::vector<net::MockRead> reads_;
  std::unique_ptr<net::StaticSocketDataProvider> socket_data_provider_;
  std::unique_ptr<net::SSLSocketDataProvider> ssl_socket_data_provider_;
  bool socket_data_provider_paused_ = false;
  // If true, makes TCP connection process stall. For timeout testing.
  bool tcp_unresponsive_ = false;
  std::unique_ptr<net::TransportClientSocket> tcp_client_socket_;
  base::OnceClosure tls_socket_created_;

  DISALLOW_COPY_AND_ASSIGN(TestSocketFactory);
};

class CastSocketTestBase : public testing::Test {
 protected:
  CastSocketTestBase()
      : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
        url_request_context_(true),
        logger_(new Logger()),
        observer_(new MockCastSocketObserver()),
        socket_open_params_(
            CreateIPEndPointForTest(),
            base::TimeDelta::FromMilliseconds(kDistantTimeoutMillis)),
        client_socket_factory_(socket_open_params_.ip_endpoint) {}
  ~CastSocketTestBase() override {}

  void SetUp() override {
    EXPECT_CALL(*observer_, OnMessage(_, _)).Times(0);

    url_request_context_.set_client_socket_factory(&client_socket_factory_);
    url_request_context_.Init();
    network_context_ = std::make_unique<network::NetworkContext>(
        nullptr, mojo::MakeRequest(&network_context_ptr_),
        &url_request_context_,
        /*cors_exempt_header_list=*/std::vector<std::string>());
  }

  // Runs all pending tasks in the message loop.
  void RunPendingTasks() {
    base::RunLoop run_loop;
    run_loop.RunUntilIdle();
  }

  TestSocketFactory* client_socket_factory() { return &client_socket_factory_; }

  content::TestBrowserThreadBundle thread_bundle_;
  net::TestURLRequestContext url_request_context_;
  std::unique_ptr<network::NetworkContext> network_context_;
  network::mojom::NetworkContextPtr network_context_ptr_;
  Logger* logger_;
  CompleteHandler handler_;
  std::unique_ptr<MockCastSocketObserver> observer_;
  CastSocketOpenParams socket_open_params_;
  TestSocketFactory client_socket_factory_;

 private:
  DISALLOW_COPY_AND_ASSIGN(CastSocketTestBase);
};

class MockCastSocketTest : public CastSocketTestBase {
 protected:
  MockCastSocketTest() {}

  void TearDown() override {
    if (socket_) {
      EXPECT_CALL(handler_, OnCloseComplete(net::OK));
      socket_->Close(base::BindOnce(&CompleteHandler::OnCloseComplete,
                                    base::Unretained(&handler_)));
    }
  }

  void CreateCastSocketSecure() {
    socket_ = MockTestCastSocket::CreateSecure(network_context_.get(),
                                               socket_open_params_, logger_);
  }

  void HandleAuthHandshake() {
    socket_->SetupMockTransport();
    CastMessage challenge_proto = CreateAuthChallenge();
    EXPECT_CALL(*socket_->GetMockTransport(),
                SendMessage(EqualsProto(challenge_proto), _))
        .WillOnce(PostCompletionCallbackTask<1>(net::OK));
    EXPECT_CALL(*socket_->GetMockTransport(), Start());
    EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
    socket_->AddObserver(observer_.get());
    socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                    base::Unretained(&handler_)));
    RunPendingTasks();
    socket_->GetMockTransport()->current_delegate()->OnMessage(
        CreateAuthReply());
    RunPendingTasks();
  }

  std::unique_ptr<MockTestCastSocket> socket_;

 private:
  DISALLOW_COPY_AND_ASSIGN(MockCastSocketTest);
};

class SslCastSocketTest : public CastSocketTestBase {
 protected:
  SslCastSocketTest() {}

  void TearDown() override {
    if (socket_) {
      EXPECT_CALL(handler_, OnCloseComplete(net::OK));
      socket_->Close(base::BindOnce(&CompleteHandler::OnCloseComplete,
                                    base::Unretained(&handler_)));
    }
  }

  void CreateSockets() {
    socket_ = std::make_unique<TestCastSocketBase>(
        network_context_.get(), socket_open_params_, logger_);

    server_cert_ =
        net::ImportCertFromFile(GetTestCertsDirectory(), "self_signed.pem");
    ASSERT_TRUE(server_cert_);
    server_private_key_ = ReadTestKeyFromPEM("self_signed.pem");
    ASSERT_TRUE(server_private_key_);
    server_context_ = CreateSSLServerContext(
        server_cert_.get(), *server_private_key_, server_ssl_config_);

    tcp_server_socket_.reset(
        new net::TCPServerSocket(nullptr, net::NetLogSource()));
    ASSERT_EQ(net::OK,
              tcp_server_socket_->ListenWithAddressAndPort("127.0.0.1", 0, 1));
    net::IPEndPoint server_address;
    ASSERT_EQ(net::OK, tcp_server_socket_->GetLocalAddress(&server_address));
    tcp_client_socket_.reset(
        new net::TCPClientSocket(net::AddressList(server_address), nullptr,
                                 nullptr, net::NetLogSource()));

    std::unique_ptr<net::StreamSocket> accepted_socket;
    accept_result_ = tcp_server_socket_->Accept(
        &accepted_socket, base::BindOnce(&SslCastSocketTest::TcpAcceptCallback,
                                         base::Unretained(this)));
    connect_result_ = tcp_client_socket_->Connect(base::BindOnce(
        &SslCastSocketTest::TcpConnectCallback, base::Unretained(this)));
    while (accept_result_ == net::ERR_IO_PENDING ||
           connect_result_ == net::ERR_IO_PENDING) {
      RunPendingTasks();
    }
    ASSERT_EQ(net::OK, accept_result_);
    ASSERT_EQ(net::OK, connect_result_);
    ASSERT_TRUE(accepted_socket);
    ASSERT_TRUE(tcp_client_socket_->IsConnected());

    server_socket_ =
        server_context_->CreateSSLServerSocket(std::move(accepted_socket));
    ASSERT_TRUE(server_socket_);

    client_socket_factory()->SetTcpSocket(std::move(tcp_client_socket_));
  }

  void ConnectSockets() {
    socket_->AddObserver(observer_.get());
    socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                    base::Unretained(&handler_)));

    net::TestCompletionCallback handshake_callback;
    int server_ret = handshake_callback.GetResult(
        server_socket_->Handshake(handshake_callback.callback()));

    ASSERT_EQ(net::OK, server_ret);
  }

  void TcpAcceptCallback(int result) { accept_result_ = result; }

  void TcpConnectCallback(int result) { connect_result_ = result; }

  std::unique_ptr<crypto::RSAPrivateKey> ReadTestKeyFromPEM(
      const base::StringPiece& name) {
    base::FilePath key_path = GetTestCertsDirectory().AppendASCII(name);
    std::vector<std::string> headers({"PRIVATE KEY"});
    std::string pem_data;
    if (!base::ReadFileToString(key_path, &pem_data)) {
      return nullptr;
    }
    net::PEMTokenizer pem_tokenizer(pem_data, headers);
    if (!pem_tokenizer.GetNext()) {
      return nullptr;
    }
    std::vector<uint8_t> key_vector(pem_tokenizer.data().begin(),
                                    pem_tokenizer.data().end());
    std::unique_ptr<crypto::RSAPrivateKey> key(
        crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_vector));
    return key;
  }

  int ReadExactLength(net::IOBuffer* buffer,
                      int buffer_length,
                      net::Socket* socket) {
    scoped_refptr<net::DrainableIOBuffer> draining_buffer =
        base::MakeRefCounted<net::DrainableIOBuffer>(buffer, buffer_length);
    while (draining_buffer->BytesRemaining() > 0) {
      net::TestCompletionCallback read_callback;
      int read_result = read_callback.GetResult(server_socket_->Read(
          draining_buffer.get(), draining_buffer->BytesRemaining(),
          read_callback.callback()));
      EXPECT_GT(read_result, 0);
      draining_buffer->DidConsume(read_result);
    }
    return buffer_length;
  }

  int WriteExactLength(net::IOBuffer* buffer,
                       int buffer_length,
                       net::Socket* socket) {
    scoped_refptr<net::DrainableIOBuffer> draining_buffer =
        base::MakeRefCounted<net::DrainableIOBuffer>(buffer, buffer_length);
    while (draining_buffer->BytesRemaining() > 0) {
      net::TestCompletionCallback write_callback;
      int write_result = write_callback.GetResult(server_socket_->Write(
          draining_buffer.get(), draining_buffer->BytesRemaining(),
          write_callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS));
      EXPECT_GT(write_result, 0);
      draining_buffer->DidConsume(write_result);
    }
    return buffer_length;
  }

  // Result values used for TCP socket setup.  These should contain values from
  // net::Error.
  int accept_result_;
  int connect_result_;

  // Underlying TCP sockets for |socket_| to communicate with |server_socket_|
  // when testing with the real SSL implementation.
  std::unique_ptr<net::TransportClientSocket> tcp_client_socket_;
  std::unique_ptr<net::TCPServerSocket> tcp_server_socket_;

  std::unique_ptr<TestCastSocketBase> socket_;

  // |server_socket_| is used for the *RealSSL tests in order to test the
  // CastSocket over a real SSL socket.  The other members below are used to
  // initialize |server_socket_|.
  std::unique_ptr<net::SSLServerSocket> server_socket_;
  std::unique_ptr<net::SSLServerContext> server_context_;
  std::unique_ptr<crypto::RSAPrivateKey> server_private_key_;
  scoped_refptr<net::X509Certificate> server_cert_;
  net::SSLServerConfig server_ssl_config_;

 private:
  DISALLOW_COPY_AND_ASSIGN(SslCastSocketTest);
};

}  // namespace

// Tests that the following connection flow works:
// - TCP connection succeeds (async)
// - SSL connection succeeds (async)
// - Cert is extracted successfully
// - Challenge request is sent (async)
// - Challenge response is received (async)
// - Credentials are verified successfuly
TEST_F(MockCastSocketTest, TestConnectFullSecureFlowAsync) {
  CreateCastSocketSecure();
  client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
  client_socket_factory()->SetupSslConnect(net::ASYNC, net::OK);

  HandleAuthHandshake();

  EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
  EXPECT_EQ(ChannelError::NONE, socket_->error_state());
}

// Tests that the following connection flow works:
// - TCP connection succeeds (sync)
// - SSL connection succeeds (sync)
// - Cert is extracted successfully
// - Challenge request is sent (sync)
// - Challenge response is received (sync)
// - Credentials are verified successfuly
TEST_F(MockCastSocketTest, TestConnectFullSecureFlowSync) {
  client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
  client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::OK);

  CreateCastSocketSecure();
  HandleAuthHandshake();

  EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
  EXPECT_EQ(ChannelError::NONE, socket_->error_state());
}

// Test that an AuthMessage with a mangled namespace triggers cancelation
// of the connection event loop.
TEST_F(MockCastSocketTest, TestConnectAuthMessageCorrupted) {
  CreateCastSocketSecure();
  socket_->SetupMockTransport();

  client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
  client_socket_factory()->SetupSslConnect(net::ASYNC, net::OK);

  CastMessage challenge_proto = CreateAuthChallenge();
  EXPECT_CALL(*socket_->GetMockTransport(),
              SendMessage(EqualsProto(challenge_proto), _))
      .WillOnce(PostCompletionCallbackTask<1>(net::OK));
  EXPECT_CALL(*socket_->GetMockTransport(), Start());
  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();
  CastMessage mangled_auth_reply = CreateAuthReply();
  mangled_auth_reply.set_namespace_("BOGUS_NAMESPACE");

  socket_->GetMockTransport()->current_delegate()->OnMessage(
      mangled_auth_reply);
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::TRANSPORT_ERROR, socket_->error_state());

  // Verifies that the CastSocket's resources were torn down during channel
  // close. (see http://crbug.com/504078)
  EXPECT_EQ(nullptr, socket_->transport());
}

// Test connection error - TCP connect fails (async)
TEST_F(MockCastSocketTest, TestConnectTcpConnectErrorAsync) {
  CreateCastSocketSecure();

  client_socket_factory()->SetupTcpConnect(net::ASYNC, net::ERR_FAILED);

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::CONNECT_ERROR, socket_->error_state());
}

// Test connection error - TCP connect fails (sync)
TEST_F(MockCastSocketTest, TestConnectTcpConnectErrorSync) {
  CreateCastSocketSecure();

  client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::ERR_FAILED);

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::CONNECT_ERROR, socket_->error_state());
}

// Test connection error - timeout
TEST_F(MockCastSocketTest, TestConnectTcpTimeoutError) {
  CreateCastSocketSecure();
  client_socket_factory()->SetupTcpConnectUnresponsive();
  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  EXPECT_CALL(*observer_, OnError(_, ChannelError::CONNECT_TIMEOUT));
  socket_->AddObserver(observer_.get());
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CONNECTING, socket_->ready_state());
  EXPECT_EQ(ChannelError::NONE, socket_->error_state());
  socket_->TriggerTimeout();
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
}

// Test connection error - TCP socket returns timeout
TEST_F(MockCastSocketTest, TestConnectTcpSocketTimeoutError) {
  CreateCastSocketSecure();
  client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS,
                                           net::ERR_CONNECTION_TIMED_OUT);
  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  EXPECT_CALL(*observer_, OnError(_, ChannelError::CONNECT_TIMEOUT));
  socket_->AddObserver(observer_.get());
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
  EXPECT_EQ(net::ERR_CONNECTION_TIMED_OUT,
            logger_->GetLastError(socket_->id()).net_return_value);
}

// Test connection error - SSL connect fails (async)
TEST_F(MockCastSocketTest, TestConnectSslConnectErrorAsync) {
  CreateCastSocketSecure();

  client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
  client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::ERR_FAILED);

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::AUTHENTICATION_ERROR, socket_->error_state());
}

// Test connection error - SSL connect fails (sync)
TEST_F(MockCastSocketTest, TestConnectSslConnectErrorSync) {
  CreateCastSocketSecure();

  client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
  client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::ERR_FAILED);

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::AUTHENTICATION_ERROR, socket_->error_state());
  EXPECT_EQ(net::ERR_FAILED,
            logger_->GetLastError(socket_->id()).net_return_value);
}

// Test connection error - SSL connect times out (sync)
TEST_F(MockCastSocketTest, TestConnectSslConnectTimeoutSync) {
  client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
  client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS,
                                           net::ERR_CONNECTION_TIMED_OUT);

  CreateCastSocketSecure();

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
  EXPECT_EQ(net::ERR_CONNECTION_TIMED_OUT,
            logger_->GetLastError(socket_->id()).net_return_value);
}

// Test connection error - SSL connect times out (async)
TEST_F(MockCastSocketTest, TestConnectSslConnectTimeoutAsync) {
  CreateCastSocketSecure();

  client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
  client_socket_factory()->SetupSslConnect(net::ASYNC,
                                           net::ERR_CONNECTION_TIMED_OUT);

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::CONNECT_TIMEOUT, socket_->error_state());
}

// Test connection error - challenge send fails
TEST_F(MockCastSocketTest, TestConnectChallengeSendError) {
  CreateCastSocketSecure();
  socket_->SetupMockTransport();

  client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
  client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::OK);
  EXPECT_CALL(*socket_->GetMockTransport(),
              SendMessage(EqualsProto(CreateAuthChallenge()), _))
      .WillOnce(PostCompletionCallbackTask<1>(net::ERR_CONNECTION_RESET));

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::CAST_SOCKET_ERROR, socket_->error_state());
}

// Test connection error - connection is destroyed after the challenge is
// sent, with the async result still lurking in the task queue.
TEST_F(MockCastSocketTest, TestConnectDestroyedAfterChallengeSent) {
  CreateCastSocketSecure();
  socket_->SetupMockTransport();
  client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
  client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::OK);
  EXPECT_CALL(*socket_->GetMockTransport(),
              SendMessage(EqualsProto(CreateAuthChallenge()), _))
      .WillOnce(PostCompletionCallbackTask<1>(net::ERR_CONNECTION_RESET));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();
  socket_.reset();
  RunPendingTasks();
}

// Test connection error - challenge reply receive fails
TEST_F(MockCastSocketTest, TestConnectChallengeReplyReceiveError) {
  CreateCastSocketSecure();
  socket_->SetupMockTransport();

  client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
  client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::OK);
  EXPECT_CALL(*socket_->GetMockTransport(),
              SendMessage(EqualsProto(CreateAuthChallenge()), _))
      .WillOnce(PostCompletionCallbackTask<1>(net::OK));
  client_socket_factory()->AddReadResult(net::SYNCHRONOUS, net::ERR_FAILED);
  EXPECT_CALL(*observer_, OnError(_, ChannelError::CAST_SOCKET_ERROR));
  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  EXPECT_CALL(*socket_->GetMockTransport(), Start());
  socket_->AddObserver(observer_.get());
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();
  socket_->GetMockTransport()->current_delegate()->OnError(
      ChannelError::CAST_SOCKET_ERROR);
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::CAST_SOCKET_ERROR, socket_->error_state());
}

TEST_F(MockCastSocketTest, TestConnectChallengeVerificationFails) {
  CreateCastSocketSecure();
  socket_->SetupMockTransport();
  client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
  client_socket_factory()->SetupSslConnect(net::ASYNC, net::OK);
  socket_->SetVerifyChallengeResult(false);

  EXPECT_CALL(*observer_, OnError(_, ChannelError::AUTHENTICATION_ERROR));
  CastMessage challenge_proto = CreateAuthChallenge();
  EXPECT_CALL(*socket_->GetMockTransport(),
              SendMessage(EqualsProto(challenge_proto), _))
      .WillOnce(PostCompletionCallbackTask<1>(net::OK));
  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  EXPECT_CALL(*socket_->GetMockTransport(), Start());
  socket_->AddObserver(observer_.get());
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();
  socket_->GetMockTransport()->current_delegate()->OnMessage(CreateAuthReply());
  RunPendingTasks();

  EXPECT_EQ(ReadyState::CLOSED, socket_->ready_state());
  EXPECT_EQ(ChannelError::AUTHENTICATION_ERROR, socket_->error_state());
}

// Sends message data through an actual non-mocked CastTransport object,
// testing the two components in integration.
TEST_F(MockCastSocketTest, TestConnectEndToEndWithRealTransportAsync) {
  CreateCastSocketSecure();
  client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
  client_socket_factory()->SetupSslConnect(net::ASYNC, net::OK);

  // Set low-level auth challenge expectations.
  CastMessage challenge = CreateAuthChallenge();
  std::string challenge_str;
  EXPECT_TRUE(MessageFramer::Serialize(challenge, &challenge_str));
  client_socket_factory()->AddWriteResultForData(net::ASYNC, challenge_str);

  // Set low-level auth reply expectations.
  CastMessage reply = CreateAuthReply();
  std::string reply_str;
  EXPECT_TRUE(MessageFramer::Serialize(reply, &reply_str));
  client_socket_factory()->AddReadResultForData(net::ASYNC, reply_str);
  client_socket_factory()->AddReadResult(net::ASYNC, net::ERR_IO_PENDING);
  // Make sure the data is ready by the TLS socket and not the TCP socket.
  client_socket_factory()->Pause();
  client_socket_factory()->SetTLSSocketCreatedClosure(
      base::BindLambdaForTesting([&] { client_socket_factory()->Resume(); }));

  CastMessage test_message = CreateTestMessage();
  std::string test_message_str;
  EXPECT_TRUE(MessageFramer::Serialize(test_message, &test_message_str));
  client_socket_factory()->AddWriteResultForData(net::ASYNC, test_message_str);

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();
  EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
  EXPECT_EQ(ChannelError::NONE, socket_->error_state());

  // Send the test message through a real transport object.
  EXPECT_CALL(handler_, OnWriteComplete(net::OK));
  socket_->transport()->SendMessage(
      test_message, base::BindOnce(&CompleteHandler::OnWriteComplete,
                                   base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
  EXPECT_EQ(ChannelError::NONE, socket_->error_state());
}

// Same as TestConnectEndToEndWithRealTransportAsync, except synchronous.
TEST_F(MockCastSocketTest, TestConnectEndToEndWithRealTransportSync) {
  CreateCastSocketSecure();
  client_socket_factory()->SetupTcpConnect(net::SYNCHRONOUS, net::OK);
  client_socket_factory()->SetupSslConnect(net::SYNCHRONOUS, net::OK);

  // Set low-level auth challenge expectations.
  CastMessage challenge = CreateAuthChallenge();
  std::string challenge_str;
  EXPECT_TRUE(MessageFramer::Serialize(challenge, &challenge_str));
  client_socket_factory()->AddWriteResultForData(net::SYNCHRONOUS,
                                                 challenge_str);

  // Set low-level auth reply expectations.
  CastMessage reply = CreateAuthReply();
  std::string reply_str;
  EXPECT_TRUE(MessageFramer::Serialize(reply, &reply_str));
  client_socket_factory()->AddReadResultForData(net::SYNCHRONOUS, reply_str);
  client_socket_factory()->AddReadResult(net::ASYNC, net::ERR_IO_PENDING);
  // Make sure the data is ready by the TLS socket and not the TCP socket.
  client_socket_factory()->Pause();
  client_socket_factory()->SetTLSSocketCreatedClosure(
      base::BindLambdaForTesting([&] { client_socket_factory()->Resume(); }));

  CastMessage test_message = CreateTestMessage();
  std::string test_message_str;
  EXPECT_TRUE(MessageFramer::Serialize(test_message, &test_message_str));
  client_socket_factory()->AddWriteResultForData(net::SYNCHRONOUS,
                                                 test_message_str);

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();
  EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
  EXPECT_EQ(ChannelError::NONE, socket_->error_state());

  // Send the test message through a real transport object.
  EXPECT_CALL(handler_, OnWriteComplete(net::OK));
  socket_->transport()->SendMessage(
      test_message, base::BindOnce(&CompleteHandler::OnWriteComplete,
                                   base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
  EXPECT_EQ(ChannelError::NONE, socket_->error_state());
}

TEST_F(MockCastSocketTest, TestObservers) {
  CreateCastSocketSecure();
  // Test AddObserever
  MockCastSocketObserver observer1;
  MockCastSocketObserver observer2;
  socket_->AddObserver(&observer1);
  socket_->AddObserver(&observer1);
  socket_->AddObserver(&observer2);
  socket_->AddObserver(&observer2);

  // Test notify observers
  EXPECT_CALL(observer1, OnError(_, cast_channel::ChannelError::CONNECT_ERROR));
  EXPECT_CALL(observer2, OnError(_, cast_channel::ChannelError::CONNECT_ERROR));
  CastSocketImpl::CastSocketMessageDelegate delegate(socket_.get());
  delegate.OnError(cast_channel::ChannelError::CONNECT_ERROR);
}

TEST_F(MockCastSocketTest, TestOpenChannelConnectingSocket) {
  CreateCastSocketSecure();
  client_socket_factory()->SetupTcpConnectUnresponsive();
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get())).Times(2);
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  socket_->TriggerTimeout();
  RunPendingTasks();
}

TEST_F(MockCastSocketTest, TestOpenChannelConnectedSocket) {
  CreateCastSocketSecure();
  client_socket_factory()->SetupTcpConnect(net::ASYNC, net::OK);
  client_socket_factory()->SetupSslConnect(net::ASYNC, net::OK);
  HandleAuthHandshake();

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
}

TEST_F(MockCastSocketTest, TestOpenChannelClosedSocket) {
  CreateCastSocketSecure();
  client_socket_factory()->SetupTcpConnect(net::ASYNC, net::ERR_FAILED);

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
  RunPendingTasks();

  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  socket_->Connect(base::BindOnce(&CompleteHandler::OnConnectComplete,
                                  base::Unretained(&handler_)));
}

// https://crbug.com/874491, flaky on Win and Mac
#if defined(OS_WIN) || defined(OS_MACOSX)
#define MAYBE_TestConnectEndToEndWithRealSSL \
  DISABLED_TestConnectEndToEndWithRealSSL
#else
#define MAYBE_TestConnectEndToEndWithRealSSL TestConnectEndToEndWithRealSSL
#endif
// Tests connecting through an actual non-mocked CastTransport object and
// non-mocked SSLClientSocket, testing the components in integration.
TEST_F(SslCastSocketTest, MAYBE_TestConnectEndToEndWithRealSSL) {
  CreateSockets();
  ConnectSockets();

  // Set low-level auth challenge expectations.
  CastMessage challenge = CreateAuthChallenge();
  std::string challenge_str;
  EXPECT_TRUE(MessageFramer::Serialize(challenge, &challenge_str));

  int challenge_buffer_length = challenge_str.size();
  scoped_refptr<net::IOBuffer> challenge_buffer =
      base::MakeRefCounted<net::IOBuffer>(challenge_buffer_length);
  int read = ReadExactLength(challenge_buffer.get(), challenge_buffer_length,
                             server_socket_.get());

  EXPECT_EQ(challenge_buffer_length, read);
  EXPECT_EQ(challenge_str,
            std::string(challenge_buffer->data(), challenge_buffer_length));

  // Set low-level auth reply expectations.
  CastMessage reply = CreateAuthReply();
  std::string reply_str;
  EXPECT_TRUE(MessageFramer::Serialize(reply, &reply_str));

  scoped_refptr<net::StringIOBuffer> reply_buffer =
      base::MakeRefCounted<net::StringIOBuffer>(reply_str);
  int written = WriteExactLength(reply_buffer.get(), reply_buffer->size(),
                                 server_socket_.get());

  EXPECT_EQ(reply_buffer->size(), written);
  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
  EXPECT_EQ(ChannelError::NONE, socket_->error_state());
}

// Sends message data through an actual non-mocked CastTransport object and
// non-mocked SSLClientSocket, testing the components in integration.
TEST_F(SslCastSocketTest, DISABLED_TestMessageEndToEndWithRealSSL) {
  CreateSockets();
  ConnectSockets();

  // Set low-level auth challenge expectations.
  CastMessage challenge = CreateAuthChallenge();
  std::string challenge_str;
  EXPECT_TRUE(MessageFramer::Serialize(challenge, &challenge_str));

  int challenge_buffer_length = challenge_str.size();
  scoped_refptr<net::IOBuffer> challenge_buffer =
      base::MakeRefCounted<net::IOBuffer>(challenge_buffer_length);

  int read = ReadExactLength(challenge_buffer.get(), challenge_buffer_length,
                             server_socket_.get());

  EXPECT_EQ(challenge_buffer_length, read);
  EXPECT_EQ(challenge_str,
            std::string(challenge_buffer->data(), challenge_buffer_length));

  // Set low-level auth reply expectations.
  CastMessage reply = CreateAuthReply();
  std::string reply_str;
  EXPECT_TRUE(MessageFramer::Serialize(reply, &reply_str));

  scoped_refptr<net::StringIOBuffer> reply_buffer =
      base::MakeRefCounted<net::StringIOBuffer>(reply_str);
  int written = WriteExactLength(reply_buffer.get(), reply_buffer->size(),
                                 server_socket_.get());

  EXPECT_EQ(reply_buffer->size(), written);
  EXPECT_CALL(handler_, OnConnectComplete(socket_.get()));
  RunPendingTasks();

  EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
  EXPECT_EQ(ChannelError::NONE, socket_->error_state());

  // Send a test message through the ssl socket.
  CastMessage test_message = CreateTestMessage();
  std::string test_message_str;
  EXPECT_TRUE(MessageFramer::Serialize(test_message, &test_message_str));

  int test_message_length = test_message_str.size();
  scoped_refptr<net::IOBuffer> test_message_buffer =
      base::MakeRefCounted<net::IOBuffer>(test_message_length);

  EXPECT_CALL(handler_, OnWriteComplete(net::OK));
  socket_->transport()->SendMessage(
      test_message, base::BindOnce(&CompleteHandler::OnWriteComplete,
                                   base::Unretained(&handler_)));
  RunPendingTasks();

  read = ReadExactLength(test_message_buffer.get(), test_message_length,
                         server_socket_.get());

  EXPECT_EQ(test_message_length, read);
  EXPECT_EQ(test_message_str,
            std::string(test_message_buffer->data(), test_message_length));

  EXPECT_EQ(ReadyState::OPEN, socket_->ready_state());
  EXPECT_EQ(ChannelError::NONE, socket_->error_state());
}

}  // namespace cast_channel
