// Copyright (c) 2013 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/quic/quic_config.h"

#include "net/quic/crypto/crypto_handshake_message.h"
#include "net/quic/crypto/crypto_protocol.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_time.h"
#include "net/quic/quic_utils.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"

using std::string;

namespace net {
namespace test {
namespace {

class QuicConfigTest : public ::testing::Test {
 protected:
  QuicConfig config_;
};

TEST_F(QuicConfigTest, ToHandshakeMessage) {
  config_.SetInitialFlowControlWindowToSend(
      kInitialSessionFlowControlWindowForTest);
  config_.SetInitialStreamFlowControlWindowToSend(
      kInitialStreamFlowControlWindowForTest);
  config_.SetInitialSessionFlowControlWindowToSend(
      kInitialSessionFlowControlWindowForTest);
  config_.SetIdleConnectionStateLifetime(QuicTime::Delta::FromSeconds(5),
                                         QuicTime::Delta::FromSeconds(2));
  config_.SetMaxStreamsPerConnection(4, 2);
  config_.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer);
  CryptoHandshakeMessage msg;
  config_.ToHandshakeMessage(&msg);

  uint32 value;
  QuicErrorCode error = msg.GetUint32(kICSL, &value);
  EXPECT_EQ(QUIC_NO_ERROR, error);
  EXPECT_EQ(5u, value);

  error = msg.GetUint32(kMSPC, &value);
  EXPECT_EQ(QUIC_NO_ERROR, error);
  EXPECT_EQ(4u, value);

  error = msg.GetUint32(kIFCW, &value);
  EXPECT_EQ(QUIC_NO_ERROR, error);
  EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);

  error = msg.GetUint32(kSFCW, &value);
  EXPECT_EQ(QUIC_NO_ERROR, error);
  EXPECT_EQ(kInitialStreamFlowControlWindowForTest, value);

  error = msg.GetUint32(kCFCW, &value);
  EXPECT_EQ(QUIC_NO_ERROR, error);
  EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);

  error = msg.GetUint32(kSRBF, &value);
  EXPECT_EQ(QUIC_NO_ERROR, error);
  EXPECT_EQ(kDefaultSocketReceiveBuffer, value);

  const QuicTag* out;
  size_t out_len;
  error = msg.GetTaglist(kCGST, &out, &out_len);
  EXPECT_EQ(1u, out_len);
  EXPECT_EQ(kQBIC, *out);
}

TEST_F(QuicConfigTest, ProcessClientHello) {
  QuicConfig client_config;
  QuicTagVector cgst;
  cgst.push_back(kQBIC);
  client_config.SetCongestionFeedback(cgst, kQBIC);
  client_config.SetIdleConnectionStateLifetime(
      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
  client_config.SetMaxStreamsPerConnection(
      2 * kDefaultMaxStreamsPerConnection, kDefaultMaxStreamsPerConnection);
  client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
  client_config.SetInitialFlowControlWindowToSend(
      2 * kInitialSessionFlowControlWindowForTest);
  client_config.SetInitialStreamFlowControlWindowToSend(
      2 * kInitialStreamFlowControlWindowForTest);
  client_config.SetInitialSessionFlowControlWindowToSend(
      2 * kInitialSessionFlowControlWindowForTest);
  client_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer);
  QuicTagVector copt;
  copt.push_back(kTBBR);
  copt.push_back(kFHDR);
  client_config.SetConnectionOptionsToSend(copt);
  CryptoHandshakeMessage msg;
  client_config.ToHandshakeMessage(&msg);

  string error_details;
  const QuicErrorCode error =
      config_.ProcessPeerHello(msg, CLIENT, &error_details);
  EXPECT_EQ(QUIC_NO_ERROR, error);
  EXPECT_TRUE(config_.negotiated());
  EXPECT_EQ(kQBIC, config_.CongestionFeedback());
  EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
            config_.IdleConnectionStateLifetime());
  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
            config_.MaxStreamsPerConnection());
  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
  EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
  EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kTBBR);
  EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kFHDR);
  EXPECT_EQ(config_.ReceivedInitialFlowControlWindowBytes(),
            2 * kInitialSessionFlowControlWindowForTest);
  EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
            2 * kInitialStreamFlowControlWindowForTest);
  EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
            2 * kInitialSessionFlowControlWindowForTest);
  EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(),
            kDefaultSocketReceiveBuffer);
}

TEST_F(QuicConfigTest, ProcessServerHello) {
  QuicConfig server_config;
  QuicTagVector cgst;
  cgst.push_back(kQBIC);
  server_config.SetCongestionFeedback(cgst, kQBIC);
  server_config.SetIdleConnectionStateLifetime(
      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
  server_config.SetMaxStreamsPerConnection(
      kDefaultMaxStreamsPerConnection / 2,
      kDefaultMaxStreamsPerConnection / 2);
  server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
  server_config.SetInitialFlowControlWindowToSend(
      2 * kInitialSessionFlowControlWindowForTest);
  server_config.SetInitialStreamFlowControlWindowToSend(
      2 * kInitialStreamFlowControlWindowForTest);
  server_config.SetInitialSessionFlowControlWindowToSend(
      2 * kInitialSessionFlowControlWindowForTest);
  server_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer);
  CryptoHandshakeMessage msg;
  server_config.ToHandshakeMessage(&msg);
  string error_details;
  const QuicErrorCode error =
      config_.ProcessPeerHello(msg, SERVER, &error_details);
  EXPECT_EQ(QUIC_NO_ERROR, error);
  EXPECT_TRUE(config_.negotiated());
  EXPECT_EQ(kQBIC, config_.CongestionFeedback());
  EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
            config_.IdleConnectionStateLifetime());
  EXPECT_EQ(kDefaultMaxStreamsPerConnection / 2,
            config_.MaxStreamsPerConnection());
  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
  EXPECT_EQ(config_.ReceivedInitialFlowControlWindowBytes(),
            2 * kInitialSessionFlowControlWindowForTest);
  EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
            2 * kInitialStreamFlowControlWindowForTest);
  EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
            2 * kInitialSessionFlowControlWindowForTest);
  EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(),
            kDefaultSocketReceiveBuffer);
}

TEST_F(QuicConfigTest, MissingOptionalValuesInCHLO) {
  CryptoHandshakeMessage msg;
  msg.SetValue(kICSL, 1);
  msg.SetVector(kCGST, QuicTagVector(1, kQBIC));

  // Set all REQUIRED tags.
  msg.SetValue(kICSL, 1);
  msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
  msg.SetValue(kMSPC, 1);

  // No error, as rest are optional.
  string error_details;
  const QuicErrorCode error =
      config_.ProcessPeerHello(msg, CLIENT, &error_details);
  EXPECT_EQ(QUIC_NO_ERROR, error);
  EXPECT_TRUE(config_.negotiated());

  EXPECT_FALSE(config_.HasReceivedInitialFlowControlWindowBytes());
}

TEST_F(QuicConfigTest, MissingOptionalValuesInSHLO) {
  CryptoHandshakeMessage msg;

  // Set all REQUIRED tags.
  msg.SetValue(kICSL, 1);
  msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
  msg.SetValue(kMSPC, 1);

  // No error, as rest are optional.
  string error_details;
  const QuicErrorCode error =
      config_.ProcessPeerHello(msg, SERVER, &error_details);
  EXPECT_EQ(QUIC_NO_ERROR, error);
  EXPECT_TRUE(config_.negotiated());

  EXPECT_FALSE(config_.HasReceivedInitialFlowControlWindowBytes());
}

TEST_F(QuicConfigTest, MissingValueInCHLO) {
  CryptoHandshakeMessage msg;
  msg.SetValue(kICSL, 1);
  msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
  // Missing kMSPC. KATO is optional.
  string error_details;
  const QuicErrorCode error =
      config_.ProcessPeerHello(msg, CLIENT, &error_details);
  EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
}

TEST_F(QuicConfigTest, MissingValueInSHLO) {
  CryptoHandshakeMessage msg;
  msg.SetValue(kICSL, 1);
  msg.SetValue(kMSPC, 3);
  // Missing CGST. KATO is optional.
  string error_details;
  const QuicErrorCode error =
      config_.ProcessPeerHello(msg, SERVER, &error_details);
  EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
}

TEST_F(QuicConfigTest, OutOfBoundSHLO) {
  QuicConfig server_config;
  server_config.SetIdleConnectionStateLifetime(
      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));

  CryptoHandshakeMessage msg;
  server_config.ToHandshakeMessage(&msg);
  string error_details;
  const QuicErrorCode error =
      config_.ProcessPeerHello(msg, SERVER, &error_details);
  EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
}

TEST_F(QuicConfigTest, MultipleNegotiatedValuesInVectorTag) {
  QuicConfig server_config;
  QuicTagVector cgst;
  cgst.push_back(kQBIC);
  cgst.push_back(kTBBR);
  server_config.SetCongestionFeedback(cgst, kQBIC);

  CryptoHandshakeMessage msg;
  server_config.ToHandshakeMessage(&msg);
  string error_details;
  const QuicErrorCode error =
      config_.ProcessPeerHello(msg, SERVER, &error_details);
  EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
}

TEST_F(QuicConfigTest, NoOverLapInCGST) {
  QuicConfig server_config;
  QuicTagVector cgst;
  cgst.push_back(kTBBR);
  server_config.SetCongestionFeedback(cgst, kTBBR);

  CryptoHandshakeMessage msg;
  string error_details;
  server_config.ToHandshakeMessage(&msg);
  const QuicErrorCode error =
      config_.ProcessPeerHello(msg, CLIENT, &error_details);
  DVLOG(1) << QuicUtils::ErrorToString(error);
  EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP, error);
}

TEST_F(QuicConfigTest, InvalidFlowControlWindow) {
  // QuicConfig should not accept an invalid flow control window to send to the
  // peer: the receive window must be at least the default of 16 Kb.
  QuicConfig config;
  const uint64 kInvalidWindow = kDefaultFlowControlSendWindow - 1;
  EXPECT_DFATAL(config.SetInitialFlowControlWindowToSend(kInvalidWindow),
                "Initial flow control receive window");

  EXPECT_EQ(kDefaultFlowControlSendWindow,
            config.GetInitialFlowControlWindowToSend());
}

}  // namespace
}  // namespace test
}  // namespace net
