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/quic/quic_client_session.h"
9 #include "base/rand_util.h"
10 #include "net/base/capturing_net_log.h"
11 #include "net/base/test_completion_callback.h"
12 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h"
13 #include "net/quic/crypto/crypto_protocol.h"
14 #include "net/quic/crypto/quic_decrypter.h"
15 #include "net/quic/crypto/quic_encrypter.h"
16 #include "net/quic/crypto/quic_server_info.h"
17 #include "net/quic/quic_default_packet_writer.h"
18 #include "net/quic/test_tools/crypto_test_utils.h"
19 #include "net/quic/test_tools/quic_client_session_peer.h"
20 #include "net/quic/test_tools/quic_test_utils.h"
21 #include "net/socket/socket_test_util.h"
22 #include "net/udp/datagram_client_socket.h"
30 const char kServerHostname
[] = "www.example.com";
31 const uint16 kServerPort
= 80;
33 class TestPacketWriter
: public QuicDefaultPacketWriter
{
39 virtual WriteResult
WritePacket(
40 const char* buffer
, size_t buf_len
,
41 const IPAddressNumber
& self_address
,
42 const IPEndPoint
& peer_address
) OVERRIDE
{
43 QuicFramer
framer(QuicSupportedVersions(), QuicTime::Zero(), true);
44 FramerVisitorCapturingFrames visitor
;
45 framer
.set_visitor(&visitor
);
46 QuicEncryptedPacket
packet(buffer
, buf_len
);
47 EXPECT_TRUE(framer
.ProcessPacket(packet
));
48 header_
= *visitor
.header();
49 return WriteResult(WRITE_STATUS_OK
, packet
.length());
52 virtual bool IsWriteBlockedDataBuffered() const OVERRIDE
{
53 // Chrome sockets' Write() methods buffer the data until the Write is
58 // Returns the header from the last packet written.
59 const QuicPacketHeader
& header() { return header_
; }
62 QuicPacketHeader header_
;
65 class QuicClientSessionTest
: public ::testing::TestWithParam
<QuicVersion
> {
67 QuicClientSessionTest()
68 : writer_(new TestPacketWriter()),
70 new PacketSavingConnection(false, SupportedVersions(GetParam()))),
71 session_(connection_
, GetSocket().Pass(), writer_
.Pass(), NULL
, NULL
,
72 make_scoped_ptr((QuicServerInfo
*)NULL
),
73 QuicSessionKey(kServerHostname
, kServerPort
, false,
74 kPrivacyModeDisabled
),
75 DefaultQuicConfig(), &crypto_config_
, &net_log_
) {
76 session_
.config()->SetDefaults();
77 crypto_config_
.SetDefaults();
80 virtual void TearDown() OVERRIDE
{
81 session_
.CloseSessionOnError(ERR_ABORTED
);
84 scoped_ptr
<DatagramClientSocket
> GetSocket() {
85 socket_factory_
.AddSocketDataProvider(&socket_data_
);
86 return socket_factory_
.CreateDatagramClientSocket(
87 DatagramSocket::DEFAULT_BIND
, base::Bind(&base::RandInt
),
88 &net_log_
, NetLog::Source());
91 void CompleteCryptoHandshake() {
92 ASSERT_EQ(ERR_IO_PENDING
,
93 session_
.CryptoConnect(false, callback_
.callback()));
94 CryptoTestUtils::HandshakeWithFakeServer(
95 connection_
, session_
.GetCryptoStream());
96 ASSERT_EQ(OK
, callback_
.WaitForResult());
99 scoped_ptr
<QuicDefaultPacketWriter
> writer_
;
100 PacketSavingConnection
* connection_
;
101 CapturingNetLog net_log_
;
102 MockClientSocketFactory socket_factory_
;
103 StaticSocketDataProvider socket_data_
;
104 QuicClientSession session_
;
107 QuicConnectionVisitorInterface
* visitor_
;
108 TestCompletionCallback callback_
;
109 QuicCryptoClientConfig crypto_config_
;
112 INSTANTIATE_TEST_CASE_P(Tests
, QuicClientSessionTest
,
113 ::testing::ValuesIn(QuicSupportedVersions()));
115 TEST_P(QuicClientSessionTest
, CryptoConnect
) {
116 CompleteCryptoHandshake();
119 TEST_P(QuicClientSessionTest
, MaxNumStreams
) {
120 CompleteCryptoHandshake();
122 std::vector
<QuicReliableClientStream
*> streams
;
123 for (size_t i
= 0; i
< kDefaultMaxStreamsPerConnection
; i
++) {
124 QuicReliableClientStream
* stream
= session_
.CreateOutgoingDataStream();
126 streams
.push_back(stream
);
128 EXPECT_FALSE(session_
.CreateOutgoingDataStream());
130 // Close a stream and ensure I can now open a new one.
131 session_
.CloseStream(streams
[0]->id());
132 EXPECT_TRUE(session_
.CreateOutgoingDataStream());
135 TEST_P(QuicClientSessionTest
, MaxNumStreamsViaRequest
) {
136 CompleteCryptoHandshake();
138 std::vector
<QuicReliableClientStream
*> streams
;
139 for (size_t i
= 0; i
< kDefaultMaxStreamsPerConnection
; i
++) {
140 QuicReliableClientStream
* stream
= session_
.CreateOutgoingDataStream();
142 streams
.push_back(stream
);
145 QuicReliableClientStream
* stream
;
146 QuicClientSession::StreamRequest stream_request
;
147 TestCompletionCallback callback
;
148 ASSERT_EQ(ERR_IO_PENDING
,
149 stream_request
.StartRequest(session_
.GetWeakPtr(), &stream
,
150 callback
.callback()));
152 // Close a stream and ensure I can now open a new one.
153 session_
.CloseStream(streams
[0]->id());
154 ASSERT_TRUE(callback
.have_result());
155 EXPECT_EQ(OK
, callback
.WaitForResult());
156 EXPECT_TRUE(stream
!= NULL
);
159 TEST_P(QuicClientSessionTest
, GoAwayReceived
) {
160 CompleteCryptoHandshake();
162 // After receiving a GoAway, I should no longer be able to create outgoing
164 session_
.OnGoAway(QuicGoAwayFrame(QUIC_PEER_GOING_AWAY
, 1u, "Going away."));
165 EXPECT_EQ(NULL
, session_
.CreateOutgoingDataStream());