Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / net / tools / quic / quic_client_session_test.cc
blobc2b0d81859b23f6017bb5f05675b4fbb974b7cf3
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_->connection()->OnGoAwayFrame(
99 QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away."));
100 EXPECT_EQ(nullptr, session_->CreateOutgoingDynamicStream());
103 TEST_P(ToolsQuicClientSessionTest, SetFecProtectionFromConfig) {
104 ValueRestore<bool> old_flag(&FLAGS_enable_quic_fec, true);
106 // Set FEC config in client's connection options.
107 QuicTagVector copt;
108 copt.push_back(kFHDR);
109 session_->config()->SetConnectionOptionsToSend(copt);
111 // Doing the handshake should set up FEC config correctly.
112 CompleteCryptoHandshake();
114 // Verify that headers stream is always protected and data streams are
115 // optionally protected.
116 EXPECT_EQ(FEC_PROTECT_ALWAYS, QuicSpdySessionPeer::GetHeadersStream(
117 session_.get())->fec_policy());
118 QuicSpdyClientStream* stream = session_->CreateOutgoingDynamicStream();
119 ASSERT_TRUE(stream);
120 EXPECT_EQ(FEC_PROTECT_OPTIONAL, stream->fec_policy());
123 static bool CheckForDecryptionError(QuicFramer* framer) {
124 return framer->error() == QUIC_DECRYPTION_FAILURE;
127 // Regression test for b/17206611.
128 TEST_P(ToolsQuicClientSessionTest, InvalidPacketReceived) {
129 IPEndPoint server_address(TestPeerIPAddress(), kTestPort);
130 IPEndPoint client_address(TestPeerIPAddress(), kTestPort);
132 EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
133 .WillRepeatedly(Invoke(implicit_cast<MockConnection*>(connection_),
134 &MockConnection::ReallyProcessUdpPacket));
135 EXPECT_CALL(*connection_, OnCanWrite()).Times(AnyNumber());
136 EXPECT_CALL(*connection_, OnError(_)).Times(1);
138 // Verify that empty packets don't close the connection.
139 QuicEncryptedPacket zero_length_packet(nullptr, 0, false);
140 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
141 session_->connection()->ProcessUdpPacket(client_address, server_address,
142 zero_length_packet);
144 // Verifiy that small, invalid packets don't close the connection.
145 char buf[2] = {0x00, 0x01};
146 QuicEncryptedPacket valid_packet(buf, 2, false);
147 // Close connection shouldn't be called.
148 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
149 session_->connection()->ProcessUdpPacket(client_address, server_address,
150 valid_packet);
152 // Verify that a non-decryptable packet doesn't close the connection.
153 QuicConnectionId connection_id = session_->connection()->connection_id();
154 scoped_ptr<QuicEncryptedPacket> packet(
155 ConstructEncryptedPacket(connection_id, false, false, 100, "data"));
156 // Change the last byte of the encrypted data.
157 *(const_cast<char*>(packet->data() + packet->length() - 1)) += 1;
158 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(0);
159 EXPECT_CALL(*connection_, OnError(Truly(CheckForDecryptionError))).Times(1);
160 session_->connection()->ProcessUdpPacket(client_address, server_address,
161 *packet);
164 // A packet with invalid framing should cause a connection to be closed.
165 TEST_P(ToolsQuicClientSessionTest, InvalidFramedPacketReceived) {
166 IPEndPoint server_address(TestPeerIPAddress(), kTestPort);
167 IPEndPoint client_address(TestPeerIPAddress(), kTestPort);
169 EXPECT_CALL(*connection_, ProcessUdpPacket(server_address, client_address, _))
170 .WillRepeatedly(Invoke(implicit_cast<MockConnection*>(connection_),
171 &MockConnection::ReallyProcessUdpPacket));
172 EXPECT_CALL(*connection_, OnError(_)).Times(1);
174 // Verify that a decryptable packet with bad frames does close the connection.
175 QuicConnectionId connection_id = session_->connection()->connection_id();
176 scoped_ptr<QuicEncryptedPacket> packet(ConstructMisFramedEncryptedPacket(
177 connection_id, false, false, 100, "data", PACKET_8BYTE_CONNECTION_ID,
178 PACKET_6BYTE_PACKET_NUMBER, nullptr));
179 EXPECT_CALL(*connection_, SendConnectionCloseWithDetails(_, _)).Times(1);
180 session_->connection()->ProcessUdpPacket(client_address, server_address,
181 *packet);
184 } // namespace
185 } // namespace test
186 } // namespace tools
187 } // namespace net