Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / tools / quic / quic_client_session_test.cc
blob1543f56dd81d7ca097cf7724f2663e392a0256e0
1 // Copyright (c) 2012 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.
5 #include "net/tools/quic/quic_client_session.h"
7 #include <vector>
9 #include "net/base/ip_endpoint.h"
10 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
11 #include "net/quic/quic_flags.h"
12 #include "net/quic/test_tools/crypto_test_utils.h"
13 #include "net/quic/test_tools/quic_spdy_session_peer.h"
14 #include "net/quic/test_tools/quic_test_utils.h"
15 #include "net/tools/quic/quic_spdy_client_stream.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using net::test::ConstructEncryptedPacket;
19 using net::test::ConstructMisFramedEncryptedPacket;
20 using net::test::CryptoTestUtils;
21 using net::test::DefaultQuicConfig;
22 using net::test::MockConnection;
23 using net::test::PacketSavingConnection;
24 using net::test::QuicSpdySessionPeer;
25 using net::test::SupportedVersions;
26 using net::test::TestPeerIPAddress;
27 using net::test::ValueRestore;
28 using net::test::kTestPort;
29 using testing::AnyNumber;
30 using testing::Invoke;
31 using testing::Truly;
32 using testing::_;
34 namespace net {
35 namespace tools {
36 namespace test {
37 namespace {
39 const char kServerHostname[] = "www.example.org";
40 const uint16 kPort = 80;
42 class ToolsQuicClientSessionTest
43 : public ::testing::TestWithParam<QuicVersion> {
44 protected:
45 ToolsQuicClientSessionTest()
46 : connection_(new PacketSavingConnection(Perspective::IS_CLIENT,
47 SupportedVersions(GetParam()))) {
48 session_.reset(new QuicClientSession(
49 DefaultQuicConfig(), connection_,
50 QuicServerId(kServerHostname, kPort, false, PRIVACY_MODE_DISABLED),
51 &crypto_config_));
52 session_->Initialize();
53 // Advance the time, because timers do not like uninitialized times.
54 connection_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
57 void CompleteCryptoHandshake() {
58 session_->CryptoConnect();
59 CryptoTestUtils::HandshakeWithFakeServer(
60 connection_, session_->GetCryptoStream());
63 PacketSavingConnection* connection_;
64 scoped_ptr<QuicClientSession> session_;
65 QuicCryptoClientConfig crypto_config_;
68 INSTANTIATE_TEST_CASE_P(Tests, ToolsQuicClientSessionTest,
69 ::testing::ValuesIn(QuicSupportedVersions()));
71 TEST_P(ToolsQuicClientSessionTest, CryptoConnect) {
72 CompleteCryptoHandshake();
75 TEST_P(ToolsQuicClientSessionTest, MaxNumStreams) {
76 EXPECT_CALL(*connection_, SendRstStream(_, _, _)).Times(AnyNumber());
78 session_->config()->SetMaxStreamsPerConnection(1, 1);
80 // Initialize crypto before the client session will create a stream.
81 CompleteCryptoHandshake();
83 QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
84 ASSERT_TRUE(stream);
85 EXPECT_FALSE(session_->CreateOutgoingDynamicStream());
87 // Close a stream and ensure I can now open a new one.
88 session_->CloseStream(stream->id());
89 stream = session_->CreateOutgoingDynamicStream();
90 EXPECT_TRUE(stream);
93 TEST_P(ToolsQuicClientSessionTest, GoAwayReceived) {
94 CompleteCryptoHandshake();
96 // After receiving a GoAway, I should no longer be able to create outgoing
97 // streams.
98 session_->OnGoAway(QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away."));
99 EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream());
102 TEST_P(ToolsQuicClientSessionTest, SetFecProtectionFromConfig) {
103 ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true);
105 // Set FEC config in client's connection options.
106 QuicTagVector copt;
107 copt.push_back(kFHDR);
108 session_->config()->SetConnectionOptionsToSend(copt);
110 // Doing the handshake should set up FEC config correctly.
111 CompleteCryptoHandshake();
113 // Verify that headers stream is always protected and data streams are
114 // optionally protected.
115 EXPECT_EQ(FEC_PROTECT_ALWAYS, QuicSpdySessionPeer::GetHeadersStream(
116 session_.get())->fec_policy());
117 QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
118 ASSERT_TRUE(stream);
119 EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy());
122 static bool CheckForDecryptionError(QuicFramer* framer) {
123 return framer->error() == QUIC_DECRYPTION_FAILURE;
126 // Regression test for b/17206611.
127 TEST_P(ToolsQuicClientSessionTest, InvalidPacketReceived) {
128 IPEndPoint server_address(TestPeerIPAddress(), kTestPort);
129 IPEndPoint client_address(TestPeerIPAddress(), kTestPort);
131 EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
132 .WillRepeatedly(Invoke(implicit_cast<MockConnection*>(connection_),
133 &MockConnection::ReallyProcessUdpPacket));
134 EXPECT_CALL(*connection_, OnCanWrite()).Times(AnyNumber());
135 EXPECT_CALL(*connection_, OnError(_)).Times(1);
137 // Verify that empty packets don't close the connection.
138 QuicEncryptedPacket zero_length_packet(nullptr, 0, false);
139 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
140 session_->connection()->ProcessUdpPacket(client_address, server_address,
141 zero_length_packet);
143 // Verifiy that small, invalid packets don't close the connection.
144 char buf[2] = {0x00, 0x01};
145 QuicEncryptedPacket valid_packet(buf, 2, false);
146 // Close connection shouldn't be called.
147 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
148 session_->connection()->ProcessUdpPacket(client_address, server_address,
149 valid_packet);
151 // Verify that a non-decryptable packet doesn't close the connection.
152 QuicConnectionId connection_id = session_->connection()->connection_id();
153 scoped_ptr<QuicEncryptedPacket> packet(
154 ConstructEncryptedPacket(connection_id, false, false, 100, "data"));
155 // Change the last byte of the encrypted data.
156 *(const_cast<char*>(packet->data() + packet->length() - 1)) += 1;
157 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
158 EXPECT_CALL(*connection_, OnError(Truly(CheckForDecryptionError))).Times(1);
159 session_->connection()->ProcessUdpPacket(client_address, server_address,
160 *packet);
163 // A packet with invalid framing should cause a connection to be closed.
164 TEST_P(ToolsQuicClientSessionTest, InvalidFramedPacketReceived) {
165 IPEndPoint server_address(TestPeerIPAddress(), kTestPort);
166 IPEndPoint client_address(TestPeerIPAddress(), kTestPort);
168 EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
169 .WillRepeatedly(Invoke(implicit_cast<MockConnection*>(connection_),
170 &MockConnection::ReallyProcessUdpPacket));
171 EXPECT_CALL(*connection_, OnError(_)).Times(1);
173 // Verify that a decryptable packet with bad frames does close the connection.
174 QuicConnectionId connection_id = session_->connection()->connection_id();
175 scoped_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
176 connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID,
177 PACKET_6BYTE_SEQUENCE_NUMBER, nullptr));
178 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(1);
179 session_->connection()->ProcessUdpPacket(client_address, server_address,
180 *packet);
183 } // namespace
184 } // namespace test
185 } // namespace tools
186 } // namespace net