blob: 22f80240894af28aad00e9a7948dc5b5095fa22c [file] [log] [blame]
[email protected]dd3fd0e2012-11-04 05:14:401// 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.
4
5#include "net/quic/quic_client_session.h"
6
7#include <vector>
8
[email protected]4d283b32013-10-17 12:57:279#include "base/rand_util.h"
[email protected]0d10b592013-02-14 16:09:2610#include "net/base/capturing_net_log.h"
[email protected]8ee611b2012-11-20 01:48:1211#include "net/base/test_completion_callback.h"
[email protected]0bbeb6972013-05-23 04:10:2112#include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
[email protected]dd3fd0e2012-11-04 05:14:4013#include "net/quic/crypto/crypto_protocol.h"
[email protected]4df69842013-02-27 06:32:1614#include "net/quic/crypto/quic_decrypter.h"
15#include "net/quic/crypto/quic_encrypter.h"
[email protected]17bf15c2014-03-14 10:08:0416#include "net/quic/crypto/quic_server_info.h"
[email protected]cbd731e2013-10-24 00:20:3917#include "net/quic/quic_default_packet_writer.h"
[email protected]ed3fc15d2013-03-08 18:37:4418#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]899951652013-05-16 12:52:3919#include "net/quic/test_tools/quic_client_session_peer.h"
[email protected]dd3fd0e2012-11-04 05:14:4020#include "net/quic/test_tools/quic_test_utils.h"
[email protected]c58a83ec2014-04-20 22:21:5021#include "net/quic/test_tools/simple_quic_framer.h"
[email protected]4d283b32013-10-17 12:57:2722#include "net/socket/socket_test_util.h"
[email protected]18ccfdb2013-08-15 00:13:4423#include "net/udp/datagram_client_socket.h"
[email protected]dd3fd0e2012-11-04 05:14:4024
[email protected]ce7bb1412014-05-17 15:51:3325using net::test::kInitialFlowControlWindowForTest;
[email protected]dd3fd0e2012-11-04 05:14:4026using testing::_;
27
28namespace net {
29namespace test {
30namespace {
31
[email protected]41d6b172013-01-29 16:10:5732const char kServerHostname[] = "www.example.com";
[email protected]e4c3ea62014-03-15 00:45:1433const uint16 kServerPort = 80;
[email protected]41d6b172013-01-29 16:10:5734
[email protected]cbd731e2013-10-24 00:20:3935class TestPacketWriter : public QuicDefaultPacketWriter {
36 public:
[email protected]c58a83ec2014-04-20 22:21:5037 TestPacketWriter(QuicVersion version) : version_(version) {
[email protected]cbd731e2013-10-24 00:20:3938 }
39
40 // QuicPacketWriter
41 virtual WriteResult WritePacket(
42 const char* buffer, size_t buf_len,
43 const IPAddressNumber& self_address,
[email protected]c5e1aca2014-01-30 04:03:0444 const IPEndPoint& peer_address) OVERRIDE {
[email protected]c58a83ec2014-04-20 22:21:5045 SimpleQuicFramer framer(SupportedVersions(version_));
[email protected]cbd731e2013-10-24 00:20:3946 QuicEncryptedPacket packet(buffer, buf_len);
47 EXPECT_TRUE(framer.ProcessPacket(packet));
[email protected]c58a83ec2014-04-20 22:21:5048 header_ = framer.header();
[email protected]cbd731e2013-10-24 00:20:3949 return WriteResult(WRITE_STATUS_OK, packet.length());
50 }
51
52 virtual bool IsWriteBlockedDataBuffered() const OVERRIDE {
53 // Chrome sockets' Write() methods buffer the data until the Write is
54 // permitted.
55 return true;
56 }
57
58 // Returns the header from the last packet written.
59 const QuicPacketHeader& header() { return header_; }
60
61 private:
[email protected]c58a83ec2014-04-20 22:21:5062 QuicVersion version_;
[email protected]cbd731e2013-10-24 00:20:3963 QuicPacketHeader header_;
64};
65
[email protected]4d640792013-12-18 22:21:0866class QuicClientSessionTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]dd3fd0e2012-11-04 05:14:4067 protected:
68 QuicClientSessionTest()
[email protected]c58a83ec2014-04-20 22:21:5069 : writer_(new TestPacketWriter(GetParam())),
[email protected]5d45daa2014-01-02 21:07:4670 connection_(
71 new PacketSavingConnection(false, SupportedVersions(GetParam()))),
[email protected]89f79a42014-03-19 11:30:0172 session_(connection_, GetSocket().Pass(), writer_.Pass(), NULL, NULL,
73 make_scoped_ptr((QuicServerInfo*)NULL),
[email protected]257f24f2014-04-01 09:15:3774 QuicServerId(kServerHostname, kServerPort, false,
75 PRIVACY_MODE_DISABLED),
[email protected]ce7bb1412014-05-17 15:51:3376 DefaultQuicConfig(), kInitialFlowControlWindowForTest,
77 &crypto_config_, &net_log_) {
[email protected]47a71542013-05-17 07:58:5478 session_.config()->SetDefaults();
[email protected]ef95114d2013-04-17 17:57:0179 crypto_config_.SetDefaults();
[email protected]dd3fd0e2012-11-04 05:14:4080 }
81
[email protected]4d283b32013-10-17 12:57:2782 virtual void TearDown() OVERRIDE {
83 session_.CloseSessionOnError(ERR_ABORTED);
84 }
85
86 scoped_ptr<DatagramClientSocket> GetSocket() {
87 socket_factory_.AddSocketDataProvider(&socket_data_);
88 return socket_factory_.CreateDatagramClientSocket(
89 DatagramSocket::DEFAULT_BIND, base::Bind(&base::RandInt),
90 &net_log_, NetLog::Source());
91 }
92
[email protected]ed3fc15d2013-03-08 18:37:4493 void CompleteCryptoHandshake() {
94 ASSERT_EQ(ERR_IO_PENDING,
[email protected]11c05872013-08-20 02:04:1295 session_.CryptoConnect(false, callback_.callback()));
[email protected]e8ff26842013-03-22 21:02:0596 CryptoTestUtils::HandshakeWithFakeServer(
97 connection_, session_.GetCryptoStream());
[email protected]ed3fc15d2013-03-08 18:37:4498 ASSERT_EQ(OK, callback_.WaitForResult());
[email protected]ed3fc15d2013-03-08 18:37:4499 }
100
[email protected]cbd731e2013-10-24 00:20:39101 scoped_ptr<QuicDefaultPacketWriter> writer_;
[email protected]dd3fd0e2012-11-04 05:14:40102 PacketSavingConnection* connection_;
[email protected]ed3fc15d2013-03-08 18:37:44103 CapturingNetLog net_log_;
[email protected]4d283b32013-10-17 12:57:27104 MockClientSocketFactory socket_factory_;
105 StaticSocketDataProvider socket_data_;
[email protected]dd3fd0e2012-11-04 05:14:40106 QuicClientSession session_;
[email protected]ed3fc15d2013-03-08 18:37:44107 MockClock clock_;
108 MockRandom random_;
[email protected]dd3fd0e2012-11-04 05:14:40109 QuicConnectionVisitorInterface* visitor_;
[email protected]8ee611b2012-11-20 01:48:12110 TestCompletionCallback callback_;
[email protected]ef95114d2013-04-17 17:57:01111 QuicCryptoClientConfig crypto_config_;
[email protected]dd3fd0e2012-11-04 05:14:40112};
113
[email protected]4d640792013-12-18 22:21:08114INSTANTIATE_TEST_CASE_P(Tests, QuicClientSessionTest,
115 ::testing::ValuesIn(QuicSupportedVersions()));
116
117TEST_P(QuicClientSessionTest, CryptoConnect) {
[email protected]ed3fc15d2013-03-08 18:37:44118 CompleteCryptoHandshake();
[email protected]8ee611b2012-11-20 01:48:12119}
120
[email protected]4d640792013-12-18 22:21:08121TEST_P(QuicClientSessionTest, MaxNumStreams) {
[email protected]ed3fc15d2013-03-08 18:37:44122 CompleteCryptoHandshake();
[email protected]dd3fd0e2012-11-04 05:14:40123
124 std::vector<QuicReliableClientStream*> streams;
125 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) {
[email protected]457d6952013-12-13 09:24:58126 QuicReliableClientStream* stream = session_.CreateOutgoingDataStream();
[email protected]dd3fd0e2012-11-04 05:14:40127 EXPECT_TRUE(stream);
[email protected]f702d572012-12-04 15:56:20128 streams.push_back(stream);
[email protected]dd3fd0e2012-11-04 05:14:40129 }
[email protected]457d6952013-12-13 09:24:58130 EXPECT_FALSE(session_.CreateOutgoingDataStream());
[email protected]dd3fd0e2012-11-04 05:14:40131
132 // Close a stream and ensure I can now open a new one.
133 session_.CloseStream(streams[0]->id());
[email protected]457d6952013-12-13 09:24:58134 EXPECT_TRUE(session_.CreateOutgoingDataStream());
[email protected]dd3fd0e2012-11-04 05:14:40135}
136
[email protected]4d640792013-12-18 22:21:08137TEST_P(QuicClientSessionTest, MaxNumStreamsViaRequest) {
[email protected]0b2294d32013-08-02 00:46:36138 CompleteCryptoHandshake();
139
140 std::vector<QuicReliableClientStream*> streams;
141 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) {
[email protected]457d6952013-12-13 09:24:58142 QuicReliableClientStream* stream = session_.CreateOutgoingDataStream();
[email protected]0b2294d32013-08-02 00:46:36143 EXPECT_TRUE(stream);
144 streams.push_back(stream);
145 }
146
147 QuicReliableClientStream* stream;
148 QuicClientSession::StreamRequest stream_request;
149 TestCompletionCallback callback;
150 ASSERT_EQ(ERR_IO_PENDING,
151 stream_request.StartRequest(session_.GetWeakPtr(), &stream,
152 callback.callback()));
153
154 // Close a stream and ensure I can now open a new one.
155 session_.CloseStream(streams[0]->id());
156 ASSERT_TRUE(callback.have_result());
157 EXPECT_EQ(OK, callback.WaitForResult());
158 EXPECT_TRUE(stream != NULL);
159}
160
[email protected]4d640792013-12-18 22:21:08161TEST_P(QuicClientSessionTest, GoAwayReceived) {
[email protected]8ba81212013-05-03 13:11:48162 CompleteCryptoHandshake();
[email protected]9db443912013-02-25 05:27:03163
164 // After receiving a GoAway, I should no longer be able to create outgoing
165 // streams.
166 session_.OnGoAway(QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away."));
[email protected]457d6952013-12-13 09:24:58167 EXPECT_EQ(NULL, session_.CreateOutgoingDataStream());
[email protected]9db443912013-02-25 05:27:03168}
169
[email protected]dd3fd0e2012-11-04 05:14:40170} // namespace
171} // namespace test
172} // namespace net