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/quic_default_packet_writer.h"
17 #include "net/quic/test_tools/crypto_test_utils.h"
18 #include "net/quic/test_tools/quic_client_session_peer.h"
19 #include "net/quic/test_tools/quic_test_utils.h"
20 #include "net/socket/socket_test_util.h"
21 #include "net/udp/datagram_client_socket.h"
29 const char kServerHostname
[] = "www.example.com";
31 class TestPacketWriter
: public QuicDefaultPacketWriter
{
37 virtual WriteResult
WritePacket(
38 const char* buffer
, size_t buf_len
,
39 const IPAddressNumber
& self_address
,
40 const IPEndPoint
& peer_address
,
41 QuicBlockedWriterInterface
* blocked_writer
) OVERRIDE
{
42 QuicFramer
framer(QuicSupportedVersions(), QuicTime::Zero(), true);
43 FramerVisitorCapturingFrames visitor
;
44 framer
.set_visitor(&visitor
);
45 QuicEncryptedPacket
packet(buffer
, buf_len
);
46 EXPECT_TRUE(framer
.ProcessPacket(packet
));
47 header_
= *visitor
.header();
48 return WriteResult(WRITE_STATUS_OK
, packet
.length());
51 virtual bool IsWriteBlockedDataBuffered() const OVERRIDE
{
52 // Chrome sockets' Write() methods buffer the data until the Write is
57 // Returns the header from the last packet written.
58 const QuicPacketHeader
& header() { return header_
; }
61 QuicPacketHeader header_
;
64 class QuicClientSessionTest
: public ::testing::Test
{
66 QuicClientSessionTest()
68 writer_(new TestPacketWriter()),
69 connection_(new PacketSavingConnection(guid_
, IPEndPoint(), false)),
70 session_(connection_
, GetSocket().Pass(), writer_
.Pass(), NULL
, NULL
,
71 kServerHostname
, DefaultQuicConfig(), &crypto_config_
,
73 session_
.config()->SetDefaults();
74 crypto_config_
.SetDefaults();
77 virtual void TearDown() OVERRIDE
{
78 session_
.CloseSessionOnError(ERR_ABORTED
);
81 scoped_ptr
<DatagramClientSocket
> GetSocket() {
82 socket_factory_
.AddSocketDataProvider(&socket_data_
);
83 return socket_factory_
.CreateDatagramClientSocket(
84 DatagramSocket::DEFAULT_BIND
, base::Bind(&base::RandInt
),
85 &net_log_
, NetLog::Source());
88 void CompleteCryptoHandshake() {
89 ASSERT_EQ(ERR_IO_PENDING
,
90 session_
.CryptoConnect(false, callback_
.callback()));
91 CryptoTestUtils::HandshakeWithFakeServer(
92 connection_
, session_
.GetCryptoStream());
93 ASSERT_EQ(OK
, callback_
.WaitForResult());
97 scoped_ptr
<QuicDefaultPacketWriter
> writer_
;
98 PacketSavingConnection
* connection_
;
99 CapturingNetLog net_log_
;
100 MockClientSocketFactory socket_factory_
;
101 StaticSocketDataProvider socket_data_
;
102 QuicClientSession session_
;
105 QuicConnectionVisitorInterface
* visitor_
;
106 TestCompletionCallback callback_
;
107 QuicCryptoClientConfig crypto_config_
;
110 TEST_F(QuicClientSessionTest
, CryptoConnect
) {
111 CompleteCryptoHandshake();
114 TEST_F(QuicClientSessionTest
, MaxNumStreams
) {
115 CompleteCryptoHandshake();
117 std::vector
<QuicReliableClientStream
*> streams
;
118 for (size_t i
= 0; i
< kDefaultMaxStreamsPerConnection
; i
++) {
119 QuicReliableClientStream
* stream
= session_
.CreateOutgoingReliableStream();
121 streams
.push_back(stream
);
123 EXPECT_FALSE(session_
.CreateOutgoingReliableStream());
125 // Close a stream and ensure I can now open a new one.
126 session_
.CloseStream(streams
[0]->id());
127 EXPECT_TRUE(session_
.CreateOutgoingReliableStream());
130 TEST_F(QuicClientSessionTest
, MaxNumStreamsViaRequest
) {
131 CompleteCryptoHandshake();
133 std::vector
<QuicReliableClientStream
*> streams
;
134 for (size_t i
= 0; i
< kDefaultMaxStreamsPerConnection
; i
++) {
135 QuicReliableClientStream
* stream
= session_
.CreateOutgoingReliableStream();
137 streams
.push_back(stream
);
140 QuicReliableClientStream
* stream
;
141 QuicClientSession::StreamRequest stream_request
;
142 TestCompletionCallback callback
;
143 ASSERT_EQ(ERR_IO_PENDING
,
144 stream_request
.StartRequest(session_
.GetWeakPtr(), &stream
,
145 callback
.callback()));
147 // Close a stream and ensure I can now open a new one.
148 session_
.CloseStream(streams
[0]->id());
149 ASSERT_TRUE(callback
.have_result());
150 EXPECT_EQ(OK
, callback
.WaitForResult());
151 EXPECT_TRUE(stream
!= NULL
);
154 TEST_F(QuicClientSessionTest
, GoAwayReceived
) {
155 CompleteCryptoHandshake();
157 // After receiving a GoAway, I should no longer be able to create outgoing
159 session_
.OnGoAway(QuicGoAwayFrame(QUIC_PEER_GOING_AWAY
, 1u, "Going away."));
160 EXPECT_EQ(NULL
, session_
.CreateOutgoingReliableStream());