Project import generated by Copybara.
PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_config_test.cc b/quic/core/quic_config_test.cc
new file mode 100644
index 0000000..59ad0ef
--- /dev/null
+++ b/quic/core/quic_config_test.cc
@@ -0,0 +1,287 @@
+// 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/third_party/quiche/src/quic/core/quic_config.h"
+
+#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
+#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/quic_time.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicConfigTest : public QuicTest {
+ protected:
+ QuicConfig config_;
+};
+
+TEST_F(QuicConfigTest, ToHandshakeMessage) {
+ config_.SetInitialStreamFlowControlWindowToSend(
+ kInitialStreamFlowControlWindowForTest);
+ config_.SetInitialSessionFlowControlWindowToSend(
+ kInitialSessionFlowControlWindowForTest);
+ config_.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(5),
+ QuicTime::Delta::FromSeconds(2));
+ CryptoHandshakeMessage msg;
+ config_.ToHandshakeMessage(&msg);
+
+ uint32_t value;
+ QuicErrorCode error = msg.GetUint32(kICSL, &value);
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+ EXPECT_EQ(5u, 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);
+}
+
+TEST_F(QuicConfigTest, ProcessClientHello) {
+ QuicConfig client_config;
+ QuicTagVector cgst;
+ cgst.push_back(kQBIC);
+ client_config.SetIdleNetworkTimeout(
+ QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
+ QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
+ client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
+ client_config.SetInitialStreamFlowControlWindowToSend(
+ 2 * kInitialStreamFlowControlWindowForTest);
+ client_config.SetInitialSessionFlowControlWindowToSend(
+ 2 * kInitialSessionFlowControlWindowForTest);
+ QuicTagVector copt;
+ copt.push_back(kTBBR);
+ client_config.SetConnectionOptionsToSend(copt);
+ CryptoHandshakeMessage msg;
+ client_config.ToHandshakeMessage(&msg);
+
+ QuicString error_details;
+ QuicTagVector initial_received_options;
+ initial_received_options.push_back(kIW50);
+ EXPECT_TRUE(
+ config_.SetInitialReceivedConnectionOptions(initial_received_options));
+ EXPECT_FALSE(
+ config_.SetInitialReceivedConnectionOptions(initial_received_options))
+ << "You can only set initial options once.";
+ const QuicErrorCode error =
+ config_.ProcessPeerHello(msg, CLIENT, &error_details);
+ EXPECT_FALSE(
+ config_.SetInitialReceivedConnectionOptions(initial_received_options))
+ << "You cannot set initial options after the hello.";
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+ EXPECT_TRUE(config_.negotiated());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
+ config_.IdleNetworkTimeout());
+ EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
+ EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+ EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
+ EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kIW50);
+ EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kTBBR);
+ EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
+ 2 * kInitialStreamFlowControlWindowForTest);
+ EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
+ 2 * kInitialSessionFlowControlWindowForTest);
+}
+
+TEST_F(QuicConfigTest, ProcessServerHello) {
+ QuicIpAddress host;
+ host.FromString("127.0.3.1");
+ const QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
+ const QuicUint128 kTestResetToken = MakeQuicUint128(0, 10111100001);
+ QuicConfig server_config;
+ QuicTagVector cgst;
+ cgst.push_back(kQBIC);
+ server_config.SetIdleNetworkTimeout(
+ QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
+ QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
+ server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
+ server_config.SetInitialStreamFlowControlWindowToSend(
+ 2 * kInitialStreamFlowControlWindowForTest);
+ server_config.SetInitialSessionFlowControlWindowToSend(
+ 2 * kInitialSessionFlowControlWindowForTest);
+ server_config.SetAlternateServerAddressToSend(kTestServerAddress);
+ server_config.SetStatelessResetTokenToSend(kTestResetToken);
+ CryptoHandshakeMessage msg;
+ server_config.ToHandshakeMessage(&msg);
+ QuicString error_details;
+ const QuicErrorCode error =
+ config_.ProcessPeerHello(msg, SERVER, &error_details);
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+ EXPECT_TRUE(config_.negotiated());
+ EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
+ config_.IdleNetworkTimeout());
+ EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
+ EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
+ 2 * kInitialStreamFlowControlWindowForTest);
+ EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
+ 2 * kInitialSessionFlowControlWindowForTest);
+ EXPECT_TRUE(config_.HasReceivedAlternateServerAddress());
+ EXPECT_EQ(kTestServerAddress, config_.ReceivedAlternateServerAddress());
+ EXPECT_TRUE(config_.HasReceivedStatelessResetToken());
+ EXPECT_EQ(kTestResetToken, config_.ReceivedStatelessResetToken());
+}
+
+TEST_F(QuicConfigTest, MissingOptionalValuesInCHLO) {
+ CryptoHandshakeMessage msg;
+ msg.SetValue(kICSL, 1);
+
+ // Set all REQUIRED tags.
+ msg.SetValue(kICSL, 1);
+ msg.SetValue(kMIDS, 1);
+
+ // No error, as rest are optional.
+ QuicString error_details;
+ const QuicErrorCode error =
+ config_.ProcessPeerHello(msg, CLIENT, &error_details);
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+ EXPECT_TRUE(config_.negotiated());
+}
+
+TEST_F(QuicConfigTest, MissingOptionalValuesInSHLO) {
+ CryptoHandshakeMessage msg;
+
+ // Set all REQUIRED tags.
+ msg.SetValue(kICSL, 1);
+ msg.SetValue(kMIDS, 1);
+
+ // No error, as rest are optional.
+ QuicString error_details;
+ const QuicErrorCode error =
+ config_.ProcessPeerHello(msg, SERVER, &error_details);
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+ EXPECT_TRUE(config_.negotiated());
+}
+
+TEST_F(QuicConfigTest, MissingValueInCHLO) {
+ // Server receives CHLO with missing kICSL.
+ CryptoHandshakeMessage msg;
+ QuicString error_details;
+ const QuicErrorCode error =
+ config_.ProcessPeerHello(msg, CLIENT, &error_details);
+ EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
+}
+
+TEST_F(QuicConfigTest, MissingValueInSHLO) {
+ // Client receives SHLO with missing kICSL.
+ CryptoHandshakeMessage msg;
+ QuicString 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.SetIdleNetworkTimeout(
+ QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
+ QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
+
+ CryptoHandshakeMessage msg;
+ server_config.ToHandshakeMessage(&msg);
+ QuicString error_details;
+ const QuicErrorCode error =
+ config_.ProcessPeerHello(msg, SERVER, &error_details);
+ EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, 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_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+ EXPECT_QUIC_BUG(
+ config.SetInitialStreamFlowControlWindowToSend(kInvalidWindow),
+ "Initial stream flow control receive window");
+
+ EXPECT_EQ(kMinimumFlowControlSendWindow,
+ config.GetInitialStreamFlowControlWindowToSend());
+}
+
+TEST_F(QuicConfigTest, HasClientSentConnectionOption) {
+ QuicConfig client_config;
+ QuicTagVector copt;
+ copt.push_back(kTBBR);
+ client_config.SetConnectionOptionsToSend(copt);
+ EXPECT_TRUE(client_config.HasClientSentConnectionOption(
+ kTBBR, Perspective::IS_CLIENT));
+
+ CryptoHandshakeMessage msg;
+ client_config.ToHandshakeMessage(&msg);
+
+ QuicString error_details;
+ const QuicErrorCode error =
+ config_.ProcessPeerHello(msg, CLIENT, &error_details);
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+ EXPECT_TRUE(config_.negotiated());
+
+ EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+ EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
+ EXPECT_TRUE(
+ config_.HasClientSentConnectionOption(kTBBR, Perspective::IS_SERVER));
+}
+
+TEST_F(QuicConfigTest, DontSendClientConnectionOptions) {
+ QuicConfig client_config;
+ QuicTagVector copt;
+ copt.push_back(kTBBR);
+ client_config.SetClientConnectionOptions(copt);
+
+ CryptoHandshakeMessage msg;
+ client_config.ToHandshakeMessage(&msg);
+
+ QuicString error_details;
+ const QuicErrorCode error =
+ config_.ProcessPeerHello(msg, CLIENT, &error_details);
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+ EXPECT_TRUE(config_.negotiated());
+
+ EXPECT_FALSE(config_.HasReceivedConnectionOptions());
+}
+
+TEST_F(QuicConfigTest, HasClientRequestedIndependentOption) {
+ QuicConfig client_config;
+ QuicTagVector client_opt;
+ client_opt.push_back(kRENO);
+ QuicTagVector copt;
+ copt.push_back(kTBBR);
+ client_config.SetClientConnectionOptions(client_opt);
+ client_config.SetConnectionOptionsToSend(copt);
+ EXPECT_TRUE(client_config.HasClientSentConnectionOption(
+ kTBBR, Perspective::IS_CLIENT));
+ EXPECT_TRUE(client_config.HasClientRequestedIndependentOption(
+ kRENO, Perspective::IS_CLIENT));
+ EXPECT_FALSE(client_config.HasClientRequestedIndependentOption(
+ kTBBR, Perspective::IS_CLIENT));
+
+ CryptoHandshakeMessage msg;
+ client_config.ToHandshakeMessage(&msg);
+
+ QuicString error_details;
+ const QuicErrorCode error =
+ config_.ProcessPeerHello(msg, CLIENT, &error_details);
+ EXPECT_EQ(QUIC_NO_ERROR, error);
+ EXPECT_TRUE(config_.negotiated());
+
+ EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+ EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
+ EXPECT_FALSE(config_.HasClientRequestedIndependentOption(
+ kRENO, Perspective::IS_SERVER));
+ EXPECT_TRUE(config_.HasClientRequestedIndependentOption(
+ kTBBR, Perspective::IS_SERVER));
+}
+
+} // namespace
+} // namespace test
+} // namespace quic