// Copyright (c) 2012 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 "net/socket/socks_client_socket_pool.h"

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "net/base/load_timing_info.h"
#include "net/base/load_timing_info_test_util.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/mock_host_resolver.h"
#include "net/log/net_log_source.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using net::test::IsError;
using net::test::IsOk;

namespace net {

namespace {

const int kMaxSockets = 32;
const int kMaxSocketsPerGroup = 6;

// Make sure |handle|'s load times are set correctly.  Only connect times should
// be set.
void TestLoadTimingInfo(const ClientSocketHandle& handle) {
  LoadTimingInfo load_timing_info;
  EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));

  // None of these tests use a NetLog.
  EXPECT_EQ(NetLogSource::kInvalidId, load_timing_info.socket_log_id);

  EXPECT_FALSE(load_timing_info.socket_reused);

  ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
                              CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
  ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
}


scoped_refptr<TransportSocketParams> CreateProxyHostParams() {
  return new TransportSocketParams(
      HostPortPair("proxy", 80), false, OnHostResolutionCallback(),
      TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT);
}

scoped_refptr<SOCKSSocketParams> CreateSOCKSv4Params() {
  return new SOCKSSocketParams(CreateProxyHostParams(), false /* socks_v5 */,
                               HostPortPair("host", 80),
                               TRAFFIC_ANNOTATION_FOR_TESTS);
}

scoped_refptr<SOCKSSocketParams> CreateSOCKSv5Params() {
  return new SOCKSSocketParams(CreateProxyHostParams(), true /* socks_v5 */,
                               HostPortPair("host", 80),
                               TRAFFIC_ANNOTATION_FOR_TESTS);
}

class SOCKSClientSocketPoolTest : public TestWithScopedTaskEnvironment {
 protected:
  class SOCKS5MockData {
   public:
    explicit SOCKS5MockData(IoMode mode) {
      writes_.reset(new MockWrite[3]);
      writes_[0] = MockWrite(mode, kSOCKS5GreetRequest,
                             kSOCKS5GreetRequestLength);
      writes_[1] = MockWrite(mode, kSOCKS5OkRequest, kSOCKS5OkRequestLength);
      writes_[2] = MockWrite(mode, 0);

      reads_.reset(new MockRead[3]);
      reads_[0] = MockRead(mode, kSOCKS5GreetResponse,
                           kSOCKS5GreetResponseLength);
      reads_[1] = MockRead(mode, kSOCKS5OkResponse, kSOCKS5OkResponseLength);
      reads_[2] = MockRead(mode, 0);

      data_.reset(new StaticSocketDataProvider(
          base::make_span(reads_.get(), 3), base::make_span(writes_.get(), 3)));
    }

    SocketDataProvider* data_provider() { return data_.get(); }

   private:
    std::unique_ptr<StaticSocketDataProvider> data_;
    std::unique_ptr<MockWrite[]> writes_;
    std::unique_ptr<MockRead[]> reads_;
  };

  SOCKSClientSocketPoolTest()
      : transport_socket_pool_(kMaxSockets,
                               kMaxSocketsPerGroup,
                               &transport_client_socket_factory_),
        pool_(kMaxSockets,
              kMaxSocketsPerGroup,
              &host_resolver_,
              &transport_socket_pool_,
              NULL,
              NULL) {}

  ~SOCKSClientSocketPoolTest() override = default;

  int StartRequestV5(const std::string& group_name, RequestPriority priority) {
    return test_base_.StartRequestUsingPool(
        &pool_, group_name, priority, ClientSocketPool::RespectLimits::ENABLED,
        CreateSOCKSv5Params());
  }

  int GetOrderOfRequest(size_t index) const {
    return test_base_.GetOrderOfRequest(index);
  }

  std::vector<std::unique_ptr<TestSocketRequest>>* requests() {
    return test_base_.requests();
  }

  MockClientSocketFactory transport_client_socket_factory_;
  MockTransportClientSocketPool transport_socket_pool_;

  MockHostResolver host_resolver_;
  SOCKSClientSocketPool pool_;
  ClientSocketPoolTest test_base_;
};

TEST_F(SOCKSClientSocketPoolTest, Simple) {
  SOCKS5MockData data(SYNCHRONOUS);
  data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
  transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());

  ClientSocketHandle handle;
  int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
                       ClientSocketPool::RespectLimits::ENABLED,
                       CompletionCallback(), &pool_, NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  TestLoadTimingInfo(handle);
}

// Make sure that SOCKSConnectJob passes on its priority to its
// socket request on Init.
TEST_F(SOCKSClientSocketPoolTest, SetSocketRequestPriorityOnInit) {
  for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
    RequestPriority priority = static_cast<RequestPriority>(i);
    SOCKS5MockData data(SYNCHRONOUS);
    data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
    transport_client_socket_factory_.AddSocketDataProvider(
        data.data_provider());

    ClientSocketHandle handle;
    EXPECT_EQ(OK,
              handle.Init("a", CreateSOCKSv5Params(), priority, SocketTag(),
                          ClientSocketPool::RespectLimits::ENABLED,
                          CompletionCallback(), &pool_, NetLogWithSource()));
    EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
    handle.socket()->Disconnect();
  }
}

// Make sure that SOCKSConnectJob passes on its priority to its
// HostResolver request (for non-SOCKS5) on Init.
TEST_F(SOCKSClientSocketPoolTest, SetResolvePriorityOnInit) {
  for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
    RequestPriority priority = static_cast<RequestPriority>(i);
    SOCKS5MockData data(SYNCHRONOUS);
    data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
    transport_client_socket_factory_.AddSocketDataProvider(
        data.data_provider());

    ClientSocketHandle handle;
    EXPECT_EQ(ERR_IO_PENDING,
              handle.Init("a", CreateSOCKSv4Params(), priority, SocketTag(),
                          ClientSocketPool::RespectLimits::ENABLED,
                          CompletionCallback(), &pool_, NetLogWithSource()));
    EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
    EXPECT_EQ(priority, host_resolver_.last_request_priority());
    EXPECT_TRUE(handle.socket() == NULL);
  }
}

TEST_F(SOCKSClientSocketPoolTest, Async) {
  SOCKS5MockData data(ASYNC);
  transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());

  TestCompletionCallback callback;
  ClientSocketHandle handle;
  int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
                       ClientSocketPool::RespectLimits::ENABLED,
                       callback.callback(), &pool_, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_THAT(callback.WaitForResult(), IsOk());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  TestLoadTimingInfo(handle);
}

TEST_F(SOCKSClientSocketPoolTest, TransportConnectError) {
  StaticSocketDataProvider socket_data;
  socket_data.set_connect_data(MockConnect(SYNCHRONOUS,
                                           ERR_CONNECTION_REFUSED));
  transport_client_socket_factory_.AddSocketDataProvider(&socket_data);

  ClientSocketHandle handle;
  int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
                       ClientSocketPool::RespectLimits::ENABLED,
                       CompletionCallback(), &pool_, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_PROXY_CONNECTION_FAILED));
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
}

TEST_F(SOCKSClientSocketPoolTest, AsyncTransportConnectError) {
  StaticSocketDataProvider socket_data;
  socket_data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
  transport_client_socket_factory_.AddSocketDataProvider(&socket_data);

  TestCompletionCallback callback;
  ClientSocketHandle handle;
  int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
                       ClientSocketPool::RespectLimits::ENABLED,
                       callback.callback(), &pool_, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PROXY_CONNECTION_FAILED));
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
}

TEST_F(SOCKSClientSocketPoolTest, SOCKSConnectError) {
  MockRead failed_read[] = {
    MockRead(SYNCHRONOUS, 0),
  };
  StaticSocketDataProvider socket_data(failed_read, base::span<MockWrite>());
  socket_data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
  transport_client_socket_factory_.AddSocketDataProvider(&socket_data);

  ClientSocketHandle handle;
  EXPECT_EQ(0, transport_socket_pool_.release_count());
  int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
                       ClientSocketPool::RespectLimits::ENABLED,
                       CompletionCallback(), &pool_, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_SOCKS_CONNECTION_FAILED));
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_EQ(1, transport_socket_pool_.release_count());
}

TEST_F(SOCKSClientSocketPoolTest, AsyncSOCKSConnectError) {
  MockRead failed_read[] = {
    MockRead(ASYNC, 0),
  };
  StaticSocketDataProvider socket_data(failed_read, base::span<MockWrite>());
  socket_data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
  transport_client_socket_factory_.AddSocketDataProvider(&socket_data);

  TestCompletionCallback callback;
  ClientSocketHandle handle;
  EXPECT_EQ(0, transport_socket_pool_.release_count());
  int rv = handle.Init("a", CreateSOCKSv5Params(), LOW, SocketTag(),
                       ClientSocketPool::RespectLimits::ENABLED,
                       callback.callback(), &pool_, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKS_CONNECTION_FAILED));
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_EQ(1, transport_socket_pool_.release_count());
}

TEST_F(SOCKSClientSocketPoolTest, CancelDuringTransportConnect) {
  SOCKS5MockData data(SYNCHRONOUS);
  transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
  // We need two connections because the pool base lets one cancelled
  // connect job proceed for potential future use.
  SOCKS5MockData data2(SYNCHRONOUS);
  transport_client_socket_factory_.AddSocketDataProvider(data2.data_provider());

  EXPECT_EQ(0, transport_socket_pool_.cancel_count());
  int rv = StartRequestV5("a", LOW);
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  rv = StartRequestV5("a", LOW);
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  pool_.CancelRequest("a", (*requests())[0]->handle());
  pool_.CancelRequest("a", (*requests())[1]->handle());
  // Requests in the connect phase don't actually get cancelled.
  EXPECT_EQ(0, transport_socket_pool_.cancel_count());

  // Now wait for the TCP sockets to connect.
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(1));
  EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(2));
  EXPECT_EQ(0, transport_socket_pool_.cancel_count());
  EXPECT_EQ(2, pool_.IdleSocketCount());

  (*requests())[0]->handle()->Reset();
  (*requests())[1]->handle()->Reset();
}

TEST_F(SOCKSClientSocketPoolTest, CancelDuringSOCKSConnect) {
  SOCKS5MockData data(ASYNC);
  data.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
  transport_client_socket_factory_.AddSocketDataProvider(data.data_provider());
  // We need two connections because the pool base lets one cancelled
  // connect job proceed for potential future use.
  SOCKS5MockData data2(ASYNC);
  data2.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
  transport_client_socket_factory_.AddSocketDataProvider(data2.data_provider());

  EXPECT_EQ(0, transport_socket_pool_.cancel_count());
  EXPECT_EQ(0, transport_socket_pool_.release_count());
  int rv = StartRequestV5("a", LOW);
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  rv = StartRequestV5("a", LOW);
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));

  pool_.CancelRequest("a", (*requests())[0]->handle());
  pool_.CancelRequest("a", (*requests())[1]->handle());
  EXPECT_EQ(0, transport_socket_pool_.cancel_count());
  // Requests in the connect phase don't actually get cancelled.
  EXPECT_EQ(0, transport_socket_pool_.release_count());

  // Now wait for the async data to reach the SOCKS connect jobs.
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(1));
  EXPECT_EQ(ClientSocketPoolTest::kRequestNotFound, GetOrderOfRequest(2));
  EXPECT_EQ(0, transport_socket_pool_.cancel_count());
  EXPECT_EQ(0, transport_socket_pool_.release_count());
  EXPECT_EQ(2, pool_.IdleSocketCount());

  (*requests())[0]->handle()->Reset();
  (*requests())[1]->handle()->Reset();
}

// It would be nice to also test the timeouts in SOCKSClientSocketPool.

// Test that SocketTag passed into SOCKSClientSocketPool is applied to returned
// sockets.
#if defined(OS_ANDROID)
TEST_F(SOCKSClientSocketPoolTest, Tag) {
  MockTaggingClientSocketFactory socket_factory;
  MockTransportClientSocketPool transport_socket_pool(
      kMaxSockets, kMaxSocketsPerGroup, &socket_factory);
  SOCKSClientSocketPool pool(kMaxSockets, kMaxSocketsPerGroup, &host_resolver_,
                             &transport_socket_pool, NULL, NULL);
  SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
  SocketTag tag2(getuid(), 0x87654321);
  scoped_refptr<TransportSocketParams> tcp_params(new TransportSocketParams(
      HostPortPair("proxy", 80), false, OnHostResolutionCallback(),
      TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT));
  scoped_refptr<SOCKSSocketParams> params(new SOCKSSocketParams(
      tcp_params, true /* socks_v5 */, HostPortPair("host", 80),
      TRAFFIC_ANNOTATION_FOR_TESTS));

  // Test socket is tagged when created synchronously.
  SOCKS5MockData data_sync(SYNCHRONOUS);
  data_sync.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
  socket_factory.AddSocketDataProvider(data_sync.data_provider());
  ClientSocketHandle handle;
  int rv = handle.Init("a", params, LOW, tag1,
                       ClientSocketPool::RespectLimits::ENABLED,
                       CompletionCallback(), &pool, NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  EXPECT_EQ(socket_factory.GetLastProducedTCPSocket()->tag(), tag1);
  EXPECT_TRUE(
      socket_factory.GetLastProducedTCPSocket()->tagged_before_connected());

  // Test socket is tagged when reused synchronously.
  StreamSocket* socket = handle.socket();
  handle.Reset();
  rv = handle.Init("a", params, LOW, tag2,
                   ClientSocketPool::RespectLimits::ENABLED,
                   CompletionCallback(), &pool, NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_TRUE(handle.socket());
  EXPECT_TRUE(handle.socket()->IsConnected());
  EXPECT_EQ(handle.socket(), socket);
  EXPECT_EQ(socket_factory.GetLastProducedTCPSocket()->tag(), tag2);
  handle.socket()->Disconnect();
  handle.Reset();

  // Test socket is tagged when created asynchronously.
  SOCKS5MockData data_async(ASYNC);
  socket_factory.AddSocketDataProvider(data_async.data_provider());
  TestCompletionCallback callback;
  rv = handle.Init("a", params, LOW, tag1,
                   ClientSocketPool::RespectLimits::ENABLED,
                   callback.callback(), &pool, NetLogWithSource());
  EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
  EXPECT_THAT(callback.WaitForResult(), IsOk());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  EXPECT_EQ(socket_factory.GetLastProducedTCPSocket()->tag(), tag1);
  EXPECT_TRUE(
      socket_factory.GetLastProducedTCPSocket()->tagged_before_connected());

  // Test socket is tagged when reused after being created asynchronously.
  socket = handle.socket();
  handle.Reset();
  rv = handle.Init("a", params, LOW, tag2,
                   ClientSocketPool::RespectLimits::ENABLED,
                   CompletionCallback(), &pool, NetLogWithSource());
  EXPECT_THAT(rv, IsOk());
  EXPECT_TRUE(handle.socket());
  EXPECT_TRUE(handle.socket()->IsConnected());
  EXPECT_EQ(handle.socket(), socket);
  EXPECT_EQ(socket_factory.GetLastProducedTCPSocket()->tag(), tag2);
}
#endif

}  // namespace

}  // namespace net
