Home | History | Annotate | Download | only in quic
      1 // Copyright 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/tools/quic/quic_server_session.h"
      6 
      7 #include "net/quic/crypto/quic_crypto_server_config.h"
      8 #include "net/quic/crypto/quic_random.h"
      9 #include "net/quic/crypto/source_address_token.h"
     10 #include "net/quic/quic_connection.h"
     11 #include "net/quic/quic_crypto_server_stream.h"
     12 #include "net/quic/quic_flags.h"
     13 #include "net/quic/quic_utils.h"
     14 #include "net/quic/test_tools/quic_config_peer.h"
     15 #include "net/quic/test_tools/quic_connection_peer.h"
     16 #include "net/quic/test_tools/quic_data_stream_peer.h"
     17 #include "net/quic/test_tools/quic_sent_packet_manager_peer.h"
     18 #include "net/quic/test_tools/quic_session_peer.h"
     19 #include "net/quic/test_tools/quic_sustained_bandwidth_recorder_peer.h"
     20 #include "net/quic/test_tools/quic_test_utils.h"
     21 #include "net/tools/quic/quic_spdy_server_stream.h"
     22 #include "net/tools/quic/test_tools/quic_test_utils.h"
     23 #include "testing/gmock/include/gmock/gmock.h"
     24 #include "testing/gtest/include/gtest/gtest.h"
     25 
     26 using __gnu_cxx::vector;
     27 using net::test::MockConnection;
     28 using net::test::QuicConfigPeer;
     29 using net::test::QuicConnectionPeer;
     30 using net::test::QuicDataStreamPeer;
     31 using net::test::QuicSentPacketManagerPeer;
     32 using net::test::QuicSessionPeer;
     33 using net::test::QuicSustainedBandwidthRecorderPeer;
     34 using net::test::SupportedVersions;
     35 using net::test::ValueRestore;
     36 using net::test::kClientDataStreamId1;
     37 using net::test::kClientDataStreamId2;
     38 using net::test::kClientDataStreamId3;
     39 using net::test::kClientDataStreamId4;
     40 using testing::StrictMock;
     41 using testing::_;
     42 
     43 namespace net {
     44 namespace tools {
     45 namespace test {
     46 
     47 class QuicServerSessionPeer {
     48  public:
     49   static QuicDataStream* GetIncomingDataStream(
     50       QuicServerSession* s, QuicStreamId id) {
     51     return s->GetIncomingDataStream(id);
     52   }
     53   static QuicDataStream* GetDataStream(QuicServerSession* s, QuicStreamId id) {
     54     return s->GetDataStream(id);
     55   }
     56   static void SetCryptoStream(QuicServerSession* s,
     57                               QuicCryptoServerStream* crypto_stream) {
     58     s->crypto_stream_.reset(crypto_stream);
     59   }
     60 };
     61 
     62 namespace {
     63 
     64 const size_t kMaxStreamsForTest = 10;
     65 
     66 class QuicServerSessionTest : public ::testing::TestWithParam<QuicVersion> {
     67  protected:
     68   QuicServerSessionTest()
     69       : crypto_config_(QuicCryptoServerConfig::TESTING,
     70                        QuicRandom::GetInstance()) {
     71     config_.SetDefaults();
     72     config_.set_max_streams_per_connection(kMaxStreamsForTest,
     73                                            kMaxStreamsForTest);
     74     config_.SetInitialFlowControlWindowToSend(
     75         kInitialSessionFlowControlWindowForTest);
     76     config_.SetInitialStreamFlowControlWindowToSend(
     77         kInitialStreamFlowControlWindowForTest);
     78     config_.SetInitialSessionFlowControlWindowToSend(
     79         kInitialSessionFlowControlWindowForTest);
     80 
     81     connection_ =
     82         new StrictMock<MockConnection>(true, SupportedVersions(GetParam()));
     83     session_.reset(new QuicServerSession(config_, connection_, &owner_));
     84     MockClock clock;
     85     handshake_message_.reset(crypto_config_.AddDefaultConfig(
     86         QuicRandom::GetInstance(), &clock,
     87         QuicCryptoServerConfig::ConfigOptions()));
     88     session_->InitializeSession(crypto_config_);
     89     visitor_ = QuicConnectionPeer::GetVisitor(connection_);
     90   }
     91 
     92   QuicVersion version() const { return connection_->version(); }
     93 
     94   StrictMock<MockQuicServerSessionVisitor> owner_;
     95   StrictMock<MockConnection>* connection_;
     96   QuicConfig config_;
     97   QuicCryptoServerConfig crypto_config_;
     98   scoped_ptr<QuicServerSession> session_;
     99   scoped_ptr<CryptoHandshakeMessage> handshake_message_;
    100   QuicConnectionVisitorInterface* visitor_;
    101 };
    102 
    103 // Compares CachedNetworkParameters.
    104 MATCHER_P(EqualsProto, network_params, "") {
    105   CachedNetworkParameters reference(network_params);
    106   return (arg->bandwidth_estimate_bytes_per_second() ==
    107           reference.bandwidth_estimate_bytes_per_second() &&
    108           arg->bandwidth_estimate_bytes_per_second() ==
    109           reference.bandwidth_estimate_bytes_per_second() &&
    110           arg->max_bandwidth_estimate_bytes_per_second() ==
    111           reference.max_bandwidth_estimate_bytes_per_second() &&
    112           arg->max_bandwidth_timestamp_seconds() ==
    113           reference.max_bandwidth_timestamp_seconds() &&
    114           arg->min_rtt_ms() == reference.min_rtt_ms() &&
    115           arg->previous_connection_state() ==
    116           reference.previous_connection_state());
    117 }
    118 
    119 INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionTest,
    120                         ::testing::ValuesIn(QuicSupportedVersions()));
    121 
    122 TEST_P(QuicServerSessionTest, CloseStreamDueToReset) {
    123   // Open a stream, then reset it.
    124   // Send two bytes of payload to open it.
    125   QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT"));
    126   vector<QuicStreamFrame> frames;
    127   frames.push_back(data1);
    128   session_->OnStreamFrames(frames);
    129   EXPECT_EQ(1u, session_->GetNumOpenStreams());
    130 
    131   // Send a reset (and expect the peer to send a RST in response).
    132   QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
    133   EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1,
    134                                           QUIC_RST_FLOW_CONTROL_ACCOUNTING, 0));
    135   visitor_->OnRstStream(rst1);
    136   EXPECT_EQ(0u, session_->GetNumOpenStreams());
    137 
    138   // Send the same two bytes of payload in a new packet.
    139   visitor_->OnStreamFrames(frames);
    140 
    141   // The stream should not be re-opened.
    142   EXPECT_EQ(0u, session_->GetNumOpenStreams());
    143   EXPECT_TRUE(connection_->connected());
    144 }
    145 
    146 TEST_P(QuicServerSessionTest, NeverOpenStreamDueToReset) {
    147   // Send a reset (and expect the peer to send a RST in response).
    148   QuicRstStreamFrame rst1(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
    149   EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1,
    150                                           QUIC_RST_FLOW_CONTROL_ACCOUNTING, 0));
    151   visitor_->OnRstStream(rst1);
    152   EXPECT_EQ(0u, session_->GetNumOpenStreams());
    153 
    154   // Send two bytes of payload.
    155   QuicStreamFrame data1(kClientDataStreamId1, false, 0, MakeIOVector("HT"));
    156   vector<QuicStreamFrame> frames;
    157   frames.push_back(data1);
    158   visitor_->OnStreamFrames(frames);
    159 
    160   // The stream should never be opened, now that the reset is received.
    161   EXPECT_EQ(0u, session_->GetNumOpenStreams());
    162   EXPECT_TRUE(connection_->connected());
    163 }
    164 
    165 TEST_P(QuicServerSessionTest, AcceptClosedStream) {
    166   vector<QuicStreamFrame> frames;
    167   // Send (empty) compressed headers followed by two bytes of data.
    168   frames.push_back(QuicStreamFrame(kClientDataStreamId1, false, 0,
    169                                    MakeIOVector("\1\0\0\0\0\0\0\0HT")));
    170   frames.push_back(QuicStreamFrame(kClientDataStreamId2, false, 0,
    171                                    MakeIOVector("\2\0\0\0\0\0\0\0HT")));
    172   visitor_->OnStreamFrames(frames);
    173   EXPECT_EQ(2u, session_->GetNumOpenStreams());
    174 
    175   // Send a reset (and expect the peer to send a RST in response).
    176   QuicRstStreamFrame rst(kClientDataStreamId1, QUIC_STREAM_NO_ERROR, 0);
    177   EXPECT_CALL(*connection_, SendRstStream(kClientDataStreamId1,
    178                                           QUIC_RST_FLOW_CONTROL_ACCOUNTING, 0));
    179   visitor_->OnRstStream(rst);
    180 
    181   // If we were tracking, we'd probably want to reject this because it's data
    182   // past the reset point of stream 3.  As it's a closed stream we just drop the
    183   // data on the floor, but accept the packet because it has data for stream 5.
    184   frames.clear();
    185   frames.push_back(
    186       QuicStreamFrame(kClientDataStreamId1, false, 2, MakeIOVector("TP")));
    187   frames.push_back(
    188       QuicStreamFrame(kClientDataStreamId2, false, 2, MakeIOVector("TP")));
    189   visitor_->OnStreamFrames(frames);
    190   // The stream should never be opened, now that the reset is received.
    191   EXPECT_EQ(1u, session_->GetNumOpenStreams());
    192   EXPECT_TRUE(connection_->connected());
    193 }
    194 
    195 TEST_P(QuicServerSessionTest, MaxOpenStreams) {
    196   ValueRestore<bool> old_flag(&FLAGS_quic_allow_more_open_streams, true);
    197   // Test that the server closes the connection if a client attempts to open too
    198   // many data streams. The server accepts slightly more than the negotiated
    199   // stream limit to deal with rare cases where a client FIN/RST is lost.
    200 
    201   // The slightly increased stream limit is set during config negotiation.
    202   EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams());
    203   session_->OnConfigNegotiated();
    204   EXPECT_EQ(kMaxStreamsMultiplier * kMaxStreamsForTest,
    205             session_->get_max_open_streams());
    206 
    207   EXPECT_EQ(0u, session_->GetNumOpenStreams());
    208   QuicStreamId stream_id = kClientDataStreamId1;
    209   // Open the max configured number of streams, should be no problem.
    210   for (size_t i = 0; i < kMaxStreamsForTest; ++i) {
    211     EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(session_.get(),
    212                                                              stream_id));
    213     stream_id += 2;
    214   }
    215 
    216   // Open one more stream: server should accept slightly more than the
    217   // configured limit.
    218   EXPECT_TRUE(
    219       QuicServerSessionPeer::GetIncomingDataStream(session_.get(), stream_id));
    220 
    221   // Now violate the server's internal stream limit.
    222   EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
    223   stream_id += 2;
    224   EXPECT_FALSE(
    225       QuicServerSessionPeer::GetIncomingDataStream(session_.get(), stream_id));
    226 }
    227 
    228 TEST_P(QuicServerSessionTest, MaxOpenStreamsImplicit) {
    229   ValueRestore<bool> old_flag(&FLAGS_quic_allow_more_open_streams, true);
    230   // Test that the server closes the connection if a client attempts to open too
    231   // many data streams implicitly.  The server accepts slightly more than the
    232   // negotiated stream limit to deal with rare cases where a client FIN/RST is
    233   // lost.
    234 
    235   // The slightly increased stream limit is set during config negotiation.
    236   EXPECT_EQ(kMaxStreamsForTest, session_->get_max_open_streams());
    237   session_->OnConfigNegotiated();
    238   EXPECT_EQ(kMaxStreamsMultiplier * kMaxStreamsForTest,
    239             session_->get_max_open_streams());
    240 
    241   EXPECT_EQ(0u, session_->GetNumOpenStreams());
    242   EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(
    243       session_.get(), kClientDataStreamId1));
    244   // Implicitly open streams up to the server's limit.
    245   const int kActualMaxStreams = kMaxStreamsMultiplier * kMaxStreamsForTest;
    246   const int kMaxValidStreamId =
    247       kClientDataStreamId1 + (kActualMaxStreams - 1) * 2;
    248   EXPECT_TRUE(QuicServerSessionPeer::GetIncomingDataStream(
    249       session_.get(), kMaxValidStreamId));
    250 
    251   // Opening a further stream will result in connection close.
    252   EXPECT_CALL(*connection_, SendConnectionClose(QUIC_TOO_MANY_OPEN_STREAMS));
    253   EXPECT_FALSE(QuicServerSessionPeer::GetIncomingDataStream(
    254       session_.get(), kMaxValidStreamId + 2));
    255 }
    256 
    257 TEST_P(QuicServerSessionTest, GetEvenIncomingError) {
    258   // Incoming streams on the server session must be odd.
    259   EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_STREAM_ID));
    260   EXPECT_EQ(NULL,
    261             QuicServerSessionPeer::GetIncomingDataStream(session_.get(), 4));
    262 }
    263 
    264 TEST_P(QuicServerSessionTest, SetFecProtectionFromConfig) {
    265   ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true);
    266 
    267   // Set received config to have FEC connection option.
    268   QuicTagVector copt;
    269   copt.push_back(kFHDR);
    270   QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
    271   session_->OnConfigNegotiated();
    272 
    273   // Verify that headers stream is always protected and data streams are
    274   // optionally protected.
    275   EXPECT_EQ(FEC_PROTECT_ALWAYS,
    276             QuicSessionPeer::GetHeadersStream(session_.get())->fec_policy());
    277   QuicDataStream* stream = QuicServerSessionPeer::GetIncomingDataStream(
    278       session_.get(), kClientDataStreamId1);
    279   ASSERT_TRUE(stream);
    280   EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy());
    281 }
    282 
    283 class MockQuicCryptoServerStream : public QuicCryptoServerStream {
    284  public:
    285   explicit MockQuicCryptoServerStream(
    286       const QuicCryptoServerConfig& crypto_config, QuicSession* session)
    287       : QuicCryptoServerStream(crypto_config, session) {}
    288   virtual ~MockQuicCryptoServerStream() {}
    289 
    290   MOCK_METHOD1(SendServerConfigUpdate,
    291                void(const CachedNetworkParameters* cached_network_parameters));
    292  private:
    293   DISALLOW_COPY_AND_ASSIGN(MockQuicCryptoServerStream);
    294 };
    295 
    296 TEST_P(QuicServerSessionTest, BandwidthEstimates) {
    297   if (version() <= QUIC_VERSION_21) {
    298     return;
    299   }
    300   // Test that bandwidth estimate updates are sent to the client, only after the
    301   // bandwidth estimate has changes sufficiently, and enough time has passed.
    302 
    303   int32 bandwidth_estimate_kbytes_per_second = 123;
    304   int32 max_bandwidth_estimate_kbytes_per_second = 134;
    305   int32 max_bandwidth_estimate_timestamp = 1122334455;
    306   const string serving_region = "not a real region";
    307   session_->set_serving_region(serving_region);
    308 
    309   MockQuicCryptoServerStream* crypto_stream =
    310       new MockQuicCryptoServerStream(crypto_config_, session_.get());
    311   QuicServerSessionPeer::SetCryptoStream(session_.get(), crypto_stream);
    312 
    313   // Set some initial bandwidth values.
    314   QuicSentPacketManager* sent_packet_manager =
    315       QuicConnectionPeer::GetSentPacketManager(session_->connection());
    316   QuicSustainedBandwidthRecorder& bandwidth_recorder =
    317       QuicSentPacketManagerPeer::GetBandwidthRecorder(sent_packet_manager);
    318   QuicSustainedBandwidthRecorderPeer::SetBandwidthEstimate(
    319       &bandwidth_recorder, bandwidth_estimate_kbytes_per_second);
    320   QuicSustainedBandwidthRecorderPeer::SetMaxBandwidthEstimate(
    321       &bandwidth_recorder, max_bandwidth_estimate_kbytes_per_second,
    322       max_bandwidth_estimate_timestamp);
    323 
    324   // There will be no update sent yet - not enough time has passed.
    325   QuicTime now = QuicTime::Zero();
    326   session_->OnCongestionWindowChange(now);
    327 
    328   // Bandwidth estimate has now changed sufficiently but not enough time has
    329   // passed to send a Server Config Update.
    330   bandwidth_estimate_kbytes_per_second =
    331       bandwidth_estimate_kbytes_per_second * 1.6;
    332   session_->OnCongestionWindowChange(now);
    333 
    334   // Bandwidth estimate has now changed sufficiently and enough time has passed.
    335   int64 srtt_ms =
    336       sent_packet_manager->GetRttStats()->SmoothedRtt().ToMilliseconds();
    337   now = now.Add(QuicTime::Delta::FromMilliseconds(
    338       kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms));
    339 
    340   // Verify that the proto has exactly the values we expect.
    341   CachedNetworkParameters expected_network_params;
    342   expected_network_params.set_bandwidth_estimate_bytes_per_second(
    343       bandwidth_recorder.BandwidthEstimate().ToBytesPerSecond());
    344   expected_network_params.set_max_bandwidth_estimate_bytes_per_second(
    345       bandwidth_recorder.MaxBandwidthEstimate().ToBytesPerSecond());
    346   expected_network_params.set_max_bandwidth_timestamp_seconds(
    347       bandwidth_recorder.MaxBandwidthTimestamp());
    348   expected_network_params.set_min_rtt_ms(session_->connection()
    349                                              ->sent_packet_manager()
    350                                              .GetRttStats()
    351                                              ->min_rtt()
    352                                              .ToMilliseconds());
    353   expected_network_params.set_previous_connection_state(
    354       CachedNetworkParameters::CONGESTION_AVOIDANCE);
    355   expected_network_params.set_serving_region(serving_region);
    356 
    357   EXPECT_CALL(*crypto_stream,
    358               SendServerConfigUpdate(EqualsProto(expected_network_params)))
    359       .Times(1);
    360   session_->OnCongestionWindowChange(now);
    361 }
    362 
    363 }  // namespace
    364 }  // namespace test
    365 }  // namespace tools
    366 }  // namespace net
    367