Home | History | Annotate | Download | only in quic
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/quic/quic_config.h"
      6 
      7 #include "net/quic/crypto/crypto_handshake_message.h"
      8 #include "net/quic/crypto/crypto_protocol.h"
      9 #include "net/quic/quic_flags.h"
     10 #include "net/quic/quic_protocol.h"
     11 #include "net/quic/quic_time.h"
     12 #include "net/quic/quic_utils.h"
     13 #include "net/quic/test_tools/quic_test_utils.h"
     14 #include "net/test/gtest_util.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 using std::string;
     18 
     19 namespace net {
     20 namespace test {
     21 namespace {
     22 
     23 class QuicConfigTest : public ::testing::Test {
     24  protected:
     25   QuicConfigTest() {
     26     config_.SetDefaults();
     27   }
     28 
     29   QuicConfig config_;
     30 };
     31 
     32 TEST_F(QuicConfigTest, ToHandshakeMessage) {
     33   config_.SetDefaults();
     34   config_.SetInitialFlowControlWindowToSend(
     35       kInitialSessionFlowControlWindowForTest);
     36   config_.SetInitialStreamFlowControlWindowToSend(
     37       kInitialStreamFlowControlWindowForTest);
     38   config_.SetInitialSessionFlowControlWindowToSend(
     39       kInitialSessionFlowControlWindowForTest);
     40   config_.set_idle_connection_state_lifetime(QuicTime::Delta::FromSeconds(5),
     41                                              QuicTime::Delta::FromSeconds(2));
     42   config_.set_max_streams_per_connection(4, 2);
     43   config_.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer);
     44   CryptoHandshakeMessage msg;
     45   config_.ToHandshakeMessage(&msg);
     46 
     47   uint32 value;
     48   QuicErrorCode error = msg.GetUint32(kICSL, &value);
     49   EXPECT_EQ(QUIC_NO_ERROR, error);
     50   EXPECT_EQ(5u, value);
     51 
     52   error = msg.GetUint32(kMSPC, &value);
     53   EXPECT_EQ(QUIC_NO_ERROR, error);
     54   EXPECT_EQ(4u, value);
     55 
     56   error = msg.GetUint32(kIFCW, &value);
     57   EXPECT_EQ(QUIC_NO_ERROR, error);
     58   EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
     59 
     60   error = msg.GetUint32(kSFCW, &value);
     61   EXPECT_EQ(QUIC_NO_ERROR, error);
     62   EXPECT_EQ(kInitialStreamFlowControlWindowForTest, value);
     63 
     64   error = msg.GetUint32(kCFCW, &value);
     65   EXPECT_EQ(QUIC_NO_ERROR, error);
     66   EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
     67 
     68   error = msg.GetUint32(kSRBF, &value);
     69   EXPECT_EQ(QUIC_NO_ERROR, error);
     70   EXPECT_EQ(kDefaultSocketReceiveBuffer, value);
     71 
     72   const QuicTag* out;
     73   size_t out_len;
     74   error = msg.GetTaglist(kCGST, &out, &out_len);
     75   EXPECT_EQ(1u, out_len);
     76   EXPECT_EQ(kQBIC, *out);
     77 }
     78 
     79 TEST_F(QuicConfigTest, ProcessClientHello) {
     80   QuicConfig client_config;
     81   QuicTagVector cgst;
     82   cgst.push_back(kQBIC);
     83   client_config.set_congestion_feedback(cgst, kQBIC);
     84   client_config.set_idle_connection_state_lifetime(
     85       QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
     86       QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
     87   client_config.set_max_streams_per_connection(
     88       2 * kDefaultMaxStreamsPerConnection, kDefaultMaxStreamsPerConnection);
     89   client_config.SetInitialRoundTripTimeUsToSend(
     90       10 * base::Time::kMicrosecondsPerMillisecond);
     91   client_config.SetInitialFlowControlWindowToSend(
     92       2 * kInitialSessionFlowControlWindowForTest);
     93   client_config.SetInitialStreamFlowControlWindowToSend(
     94       2 * kInitialStreamFlowControlWindowForTest);
     95   client_config.SetInitialSessionFlowControlWindowToSend(
     96       2 * kInitialSessionFlowControlWindowForTest);
     97   client_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer);
     98   QuicTagVector copt;
     99   copt.push_back(kTBBR);
    100   copt.push_back(kFHDR);
    101   client_config.SetConnectionOptionsToSend(copt);
    102   CryptoHandshakeMessage msg;
    103   client_config.ToHandshakeMessage(&msg);
    104   string error_details;
    105   const QuicErrorCode error =
    106       config_.ProcessPeerHello(msg, CLIENT, &error_details);
    107   EXPECT_EQ(QUIC_NO_ERROR, error);
    108   EXPECT_TRUE(config_.negotiated());
    109   EXPECT_EQ(kQBIC, config_.congestion_feedback());
    110   EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
    111             config_.idle_connection_state_lifetime());
    112   EXPECT_EQ(kDefaultMaxStreamsPerConnection,
    113             config_.max_streams_per_connection());
    114   EXPECT_EQ(QuicTime::Delta::FromSeconds(0), config_.keepalive_timeout());
    115   EXPECT_EQ(10 * base::Time::kMicrosecondsPerMillisecond,
    116             config_.ReceivedInitialRoundTripTimeUs());
    117   EXPECT_FALSE(config_.HasReceivedLossDetection());
    118   EXPECT_TRUE(config_.HasReceivedConnectionOptions());
    119   EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
    120   EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kTBBR);
    121   EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kFHDR);
    122   EXPECT_EQ(config_.ReceivedInitialFlowControlWindowBytes(),
    123             2 * kInitialSessionFlowControlWindowForTest);
    124   EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
    125             2 * kInitialStreamFlowControlWindowForTest);
    126   EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
    127             2 * kInitialSessionFlowControlWindowForTest);
    128   EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(),
    129             kDefaultSocketReceiveBuffer);
    130 }
    131 
    132 TEST_F(QuicConfigTest, ProcessServerHello) {
    133   QuicConfig server_config;
    134   QuicTagVector cgst;
    135   cgst.push_back(kQBIC);
    136   server_config.set_congestion_feedback(cgst, kQBIC);
    137   server_config.set_idle_connection_state_lifetime(
    138       QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
    139       QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
    140   server_config.set_max_streams_per_connection(
    141       kDefaultMaxStreamsPerConnection / 2,
    142       kDefaultMaxStreamsPerConnection / 2);
    143   server_config.SetInitialCongestionWindowToSend(kDefaultInitialWindow / 2);
    144   server_config.SetInitialRoundTripTimeUsToSend(
    145       10 * base::Time::kMicrosecondsPerMillisecond);
    146   server_config.SetInitialFlowControlWindowToSend(
    147       2 * kInitialSessionFlowControlWindowForTest);
    148   server_config.SetInitialStreamFlowControlWindowToSend(
    149       2 * kInitialStreamFlowControlWindowForTest);
    150   server_config.SetInitialSessionFlowControlWindowToSend(
    151       2 * kInitialSessionFlowControlWindowForTest);
    152   server_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer);
    153   CryptoHandshakeMessage msg;
    154   server_config.ToHandshakeMessage(&msg);
    155   string error_details;
    156   const QuicErrorCode error =
    157       config_.ProcessPeerHello(msg, SERVER, &error_details);
    158   EXPECT_EQ(QUIC_NO_ERROR, error);
    159   EXPECT_TRUE(config_.negotiated());
    160   EXPECT_EQ(kQBIC, config_.congestion_feedback());
    161   EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
    162             config_.idle_connection_state_lifetime());
    163   EXPECT_EQ(kDefaultMaxStreamsPerConnection / 2,
    164             config_.max_streams_per_connection());
    165   EXPECT_EQ(kDefaultInitialWindow / 2,
    166             config_.ReceivedInitialCongestionWindow());
    167   EXPECT_EQ(QuicTime::Delta::FromSeconds(0), config_.keepalive_timeout());
    168   EXPECT_EQ(10 * base::Time::kMicrosecondsPerMillisecond,
    169             config_.ReceivedInitialRoundTripTimeUs());
    170   EXPECT_FALSE(config_.HasReceivedLossDetection());
    171   EXPECT_EQ(config_.ReceivedInitialFlowControlWindowBytes(),
    172             2 * kInitialSessionFlowControlWindowForTest);
    173   EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
    174             2 * kInitialStreamFlowControlWindowForTest);
    175   EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
    176             2 * kInitialSessionFlowControlWindowForTest);
    177   EXPECT_EQ(config_.ReceivedSocketReceiveBuffer(),
    178             kDefaultSocketReceiveBuffer);
    179 }
    180 
    181 TEST_F(QuicConfigTest, MissingOptionalValuesInCHLO) {
    182   CryptoHandshakeMessage msg;
    183   msg.SetValue(kICSL, 1);
    184   msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
    185 
    186   // Set all REQUIRED tags.
    187   msg.SetValue(kICSL, 1);
    188   msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
    189   msg.SetValue(kMSPC, 1);
    190 
    191   // No error, as rest are optional.
    192   string error_details;
    193   const QuicErrorCode error =
    194       config_.ProcessPeerHello(msg, CLIENT, &error_details);
    195   EXPECT_EQ(QUIC_NO_ERROR, error);
    196 
    197   EXPECT_FALSE(config_.HasReceivedInitialFlowControlWindowBytes());
    198 }
    199 
    200 TEST_F(QuicConfigTest, MissingOptionalValuesInSHLO) {
    201   CryptoHandshakeMessage msg;
    202 
    203   // Set all REQUIRED tags.
    204   msg.SetValue(kICSL, 1);
    205   msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
    206   msg.SetValue(kMSPC, 1);
    207 
    208   // No error, as rest are optional.
    209   string error_details;
    210   const QuicErrorCode error =
    211       config_.ProcessPeerHello(msg, SERVER, &error_details);
    212   EXPECT_EQ(QUIC_NO_ERROR, error);
    213 
    214   EXPECT_FALSE(config_.HasReceivedInitialFlowControlWindowBytes());
    215 }
    216 
    217 TEST_F(QuicConfigTest, MissingValueInCHLO) {
    218   CryptoHandshakeMessage msg;
    219   msg.SetValue(kICSL, 1);
    220   msg.SetVector(kCGST, QuicTagVector(1, kQBIC));
    221   // Missing kMSPC. KATO is optional.
    222   string error_details;
    223   const QuicErrorCode error =
    224       config_.ProcessPeerHello(msg, CLIENT, &error_details);
    225   EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
    226 }
    227 
    228 TEST_F(QuicConfigTest, MissingValueInSHLO) {
    229   CryptoHandshakeMessage msg;
    230   msg.SetValue(kICSL, 1);
    231   msg.SetValue(kMSPC, 3);
    232   // Missing CGST. KATO is optional.
    233   string error_details;
    234   const QuicErrorCode error =
    235       config_.ProcessPeerHello(msg, SERVER, &error_details);
    236   EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
    237 }
    238 
    239 TEST_F(QuicConfigTest, OutOfBoundSHLO) {
    240   QuicConfig server_config;
    241   server_config.set_idle_connection_state_lifetime(
    242       QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
    243       QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
    244 
    245   CryptoHandshakeMessage msg;
    246   server_config.ToHandshakeMessage(&msg);
    247   string error_details;
    248   const QuicErrorCode error =
    249       config_.ProcessPeerHello(msg, SERVER, &error_details);
    250   EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
    251 }
    252 
    253 TEST_F(QuicConfigTest, MultipleNegotiatedValuesInVectorTag) {
    254   QuicConfig server_config;
    255   QuicTagVector cgst;
    256   cgst.push_back(kQBIC);
    257   cgst.push_back(kTBBR);
    258   server_config.set_congestion_feedback(cgst, kQBIC);
    259 
    260   CryptoHandshakeMessage msg;
    261   server_config.ToHandshakeMessage(&msg);
    262   string error_details;
    263   const QuicErrorCode error =
    264       config_.ProcessPeerHello(msg, SERVER, &error_details);
    265   EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
    266 }
    267 
    268 TEST_F(QuicConfigTest, NoOverLapInCGST) {
    269   QuicConfig server_config;
    270   server_config.SetDefaults();
    271   QuicTagVector cgst;
    272   cgst.push_back(kTBBR);
    273   server_config.set_congestion_feedback(cgst, kTBBR);
    274 
    275   CryptoHandshakeMessage msg;
    276   string error_details;
    277   server_config.ToHandshakeMessage(&msg);
    278   const QuicErrorCode error =
    279       config_.ProcessPeerHello(msg, CLIENT, &error_details);
    280   DVLOG(1) << QuicUtils::ErrorToString(error);
    281   EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP, error);
    282 }
    283 
    284 TEST_F(QuicConfigTest, InvalidFlowControlWindow) {
    285   // QuicConfig should not accept an invalid flow control window to send to the
    286   // peer: the receive window must be at least the default of 16 Kb.
    287   QuicConfig config;
    288   const uint64 kInvalidWindow = kDefaultFlowControlSendWindow - 1;
    289   EXPECT_DFATAL(config.SetInitialFlowControlWindowToSend(kInvalidWindow),
    290                 "Initial flow control receive window");
    291 
    292   EXPECT_EQ(kDefaultFlowControlSendWindow,
    293             config.GetInitialFlowControlWindowToSend());
    294 }
    295 
    296 }  // namespace
    297 }  // namespace test
    298 }  // namespace net
    299