Home | History | Annotate | Download | only in quic
      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