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. 4 5 #include "net/quic/quic_client_session.h" 6 7 #include <vector> 8 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" 22 23 using testing::_; 24 25 namespace net { 26 namespace test { 27 namespace { 28 29 const char kServerHostname[] = "www.example.com"; 30 31 class TestPacketWriter : public QuicDefaultPacketWriter { 32 public: 33 TestPacketWriter() { 34 } 35 36 // QuicPacketWriter 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()); 49 } 50 51 virtual bool IsWriteBlockedDataBuffered() const OVERRIDE { 52 // Chrome sockets' Write() methods buffer the data until the Write is 53 // permitted. 54 return true; 55 } 56 57 // Returns the header from the last packet written. 58 const QuicPacketHeader& header() { return header_; } 59 60 private: 61 QuicPacketHeader header_; 62 }; 63 64 class QuicClientSessionTest : public ::testing::Test { 65 protected: 66 QuicClientSessionTest() 67 : writer_(new TestPacketWriter()), 68 connection_(new PacketSavingConnection(false)), 69 session_(connection_, GetSocket().Pass(), writer_.Pass(), NULL, NULL, 70 kServerHostname, DefaultQuicConfig(), &crypto_config_, 71 &net_log_) { 72 session_.config()->SetDefaults(); 73 crypto_config_.SetDefaults(); 74 } 75 76 virtual void TearDown() OVERRIDE { 77 session_.CloseSessionOnError(ERR_ABORTED); 78 } 79 80 scoped_ptr<DatagramClientSocket> GetSocket() { 81 socket_factory_.AddSocketDataProvider(&socket_data_); 82 return socket_factory_.CreateDatagramClientSocket( 83 DatagramSocket::DEFAULT_BIND, base::Bind(&base::RandInt), 84 &net_log_, NetLog::Source()); 85 } 86 87 void CompleteCryptoHandshake() { 88 ASSERT_EQ(ERR_IO_PENDING, 89 session_.CryptoConnect(false, callback_.callback())); 90 CryptoTestUtils::HandshakeWithFakeServer( 91 connection_, session_.GetCryptoStream()); 92 ASSERT_EQ(OK, callback_.WaitForResult()); 93 } 94 95 scoped_ptr<QuicDefaultPacketWriter> writer_; 96 PacketSavingConnection* connection_; 97 CapturingNetLog net_log_; 98 MockClientSocketFactory socket_factory_; 99 StaticSocketDataProvider socket_data_; 100 QuicClientSession session_; 101 MockClock clock_; 102 MockRandom random_; 103 QuicConnectionVisitorInterface* visitor_; 104 TestCompletionCallback callback_; 105 QuicCryptoClientConfig crypto_config_; 106 }; 107 108 TEST_F(QuicClientSessionTest, CryptoConnect) { 109 CompleteCryptoHandshake(); 110 } 111 112 TEST_F(QuicClientSessionTest, MaxNumStreams) { 113 CompleteCryptoHandshake(); 114 115 std::vector<QuicReliableClientStream*> streams; 116 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) { 117 QuicReliableClientStream* stream = session_.CreateOutgoingDataStream(); 118 EXPECT_TRUE(stream); 119 streams.push_back(stream); 120 } 121 EXPECT_FALSE(session_.CreateOutgoingDataStream()); 122 123 // Close a stream and ensure I can now open a new one. 124 session_.CloseStream(streams[0]->id()); 125 EXPECT_TRUE(session_.CreateOutgoingDataStream()); 126 } 127 128 TEST_F(QuicClientSessionTest, MaxNumStreamsViaRequest) { 129 CompleteCryptoHandshake(); 130 131 std::vector<QuicReliableClientStream*> streams; 132 for (size_t i = 0; i < kDefaultMaxStreamsPerConnection; i++) { 133 QuicReliableClientStream* stream = session_.CreateOutgoingDataStream(); 134 EXPECT_TRUE(stream); 135 streams.push_back(stream); 136 } 137 138 QuicReliableClientStream* stream; 139 QuicClientSession::StreamRequest stream_request; 140 TestCompletionCallback callback; 141 ASSERT_EQ(ERR_IO_PENDING, 142 stream_request.StartRequest(session_.GetWeakPtr(), &stream, 143 callback.callback())); 144 145 // Close a stream and ensure I can now open a new one. 146 session_.CloseStream(streams[0]->id()); 147 ASSERT_TRUE(callback.have_result()); 148 EXPECT_EQ(OK, callback.WaitForResult()); 149 EXPECT_TRUE(stream != NULL); 150 } 151 152 TEST_F(QuicClientSessionTest, GoAwayReceived) { 153 CompleteCryptoHandshake(); 154 155 // After receiving a GoAway, I should no longer be able to create outgoing 156 // streams. 157 session_.OnGoAway(QuicGoAwayFrame(QUIC_PEER_GOING_AWAY, 1u, "Going away.")); 158 EXPECT_EQ(NULL, session_.CreateOutgoingDataStream()); 159 } 160 161 } // namespace 162 } // namespace test 163 } // namespace net 164