Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_crypto_client_stream.h" | 5 #include "net/quic/quic_crypto_client_stream.h" |
| 6 | 6 |
| 7 #include "net/quic/quic_utils.h" | 7 #include "net/quic/quic_utils.h" |
| 8 #include "net/quic/test_tools/quic_test_utils.h" | 8 #include "net/quic/test_tools/quic_test_utils.h" |
| 9 | 9 |
| 10 using base::StringPiece; | |
| 11 using std::vector; | |
| 12 | |
| 10 namespace net { | 13 namespace net { |
| 11 namespace test { | 14 namespace test { |
| 12 namespace { | 15 namespace { |
| 13 | 16 |
| 17 class TestQuicVisitor : public NoOpFramerVisitor { | |
| 18 public: | |
| 19 TestQuicVisitor() {} | |
| 20 | |
| 21 // NoOpFramerVisitor | |
| 22 virtual void OnStreamFrame(const QuicStreamFrame& frame) { | |
| 23 frame_ = frame; | |
| 24 } | |
| 25 | |
| 26 QuicStreamFrame* frame() { return &frame_; } | |
| 27 | |
| 28 private: | |
| 29 QuicStreamFrame frame_; | |
| 30 | |
| 31 DISALLOW_COPY_AND_ASSIGN(TestQuicVisitor); | |
| 32 }; | |
| 33 | |
| 34 class TestCryptoVisitor : public CryptoFramerVisitorInterface { | |
| 35 public: | |
| 36 TestCryptoVisitor() | |
| 37 : error_count_(0) { | |
| 38 } | |
| 39 | |
| 40 virtual void OnError(CryptoFramer* framer) { | |
| 41 DLOG(ERROR) << "CryptoFramer Error: " << framer->error(); | |
| 42 ++error_count_; | |
| 43 } | |
| 44 | |
| 45 virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) { | |
| 46 messages_.push_back(message); | |
| 47 } | |
| 48 | |
| 49 // Counters from the visitor callbacks. | |
| 50 int error_count_; | |
| 51 | |
| 52 vector<CryptoHandshakeMessage> messages_; | |
| 53 }; | |
| 54 | |
| 55 // The same as MockHelper, except that WritePacketToWire() checks whether | |
| 56 // the packet has expected contents. | |
| 57 class TestMockHelper : public MockHelper { | |
| 58 public: | |
| 59 TestMockHelper() : packet_count_(0) {} | |
| 60 virtual ~TestMockHelper() {} | |
| 61 | |
| 62 virtual int WritePacketToWire(const QuicEncryptedPacket& packet, | |
| 63 int* error) { | |
| 64 packet_count_++; | |
| 65 | |
| 66 // The first packet should be ClientHello. | |
| 67 if (packet_count_ == 1) { | |
| 68 CheckClientHelloPacket(packet); | |
| 69 } | |
| 70 | |
| 71 return MockHelper::WritePacketToWire(packet, error); | |
| 72 } | |
| 73 | |
| 74 private: | |
| 75 void CheckClientHelloPacket(const QuicEncryptedPacket& packet); | |
| 76 | |
| 77 int packet_count_; | |
| 78 }; | |
| 79 | |
| 80 void TestMockHelper::CheckClientHelloPacket( | |
| 81 const QuicEncryptedPacket& packet) { | |
| 82 QuicFramer quic_framer(QuicDecrypter::Create(kNULL), | |
| 83 QuicEncrypter::Create(kNULL)); | |
| 84 TestQuicVisitor quic_visitor; | |
| 85 quic_framer.set_visitor(&quic_visitor); | |
| 86 ASSERT_TRUE(quic_framer.ProcessPacket(IPEndPoint(), IPEndPoint(), | |
| 87 packet)); | |
| 88 EXPECT_EQ(kCryptoStreamId, quic_visitor.frame()->stream_id); | |
| 89 EXPECT_FALSE(quic_visitor.frame()->fin); | |
| 90 EXPECT_EQ(0u, quic_visitor.frame()->offset); | |
| 91 | |
| 92 // Check quic_visitor.frame()->data. | |
| 93 test::TestCryptoVisitor crypto_visitor; | |
| 94 CryptoFramer crypto_framer; | |
| 95 crypto_framer.set_visitor(&crypto_visitor); | |
| 96 ASSERT_TRUE(crypto_framer.ProcessInput(quic_visitor.frame()->data)); | |
| 97 ASSERT_EQ(0u, crypto_framer.InputBytesRemaining()); | |
| 98 ASSERT_EQ(1u, crypto_visitor.messages_.size()); | |
| 99 EXPECT_EQ(kCHLO, crypto_visitor.messages_[0].tag); | |
| 100 | |
| 101 CryptoTagValueMap& tag_value_map = | |
| 102 crypto_visitor.messages_[0].tag_value_map; | |
| 103 ASSERT_EQ(7u, tag_value_map.size()); | |
| 104 | |
| 105 // kNONC | |
| 106 // TODO(wtc): check the nonce. | |
| 107 ASSERT_EQ(32u, tag_value_map[kNONC].size()); | |
| 108 | |
| 109 // kAEAD | |
| 110 ASSERT_EQ(8u, tag_value_map[kAEAD].size()); | |
| 111 CryptoTag cipher[2]; | |
| 112 memcpy(&cipher[0], &tag_value_map[kAEAD][0], 4); | |
| 113 memcpy(&cipher[1], &tag_value_map[kAEAD][4], 4); | |
| 114 EXPECT_EQ(kAESG, cipher[0]); | |
| 115 EXPECT_EQ(kAESH, cipher[1]); | |
| 116 | |
| 117 // kICSL | |
| 118 ASSERT_EQ(4u, tag_value_map[kICSL].size()); | |
| 119 uint32 idle_lifetime; | |
| 120 memcpy(&idle_lifetime, tag_value_map[kICSL].data(), 4); | |
| 121 EXPECT_EQ(300u, idle_lifetime); | |
| 122 | |
| 123 // kKATO | |
| 124 ASSERT_EQ(4u, tag_value_map[kKATO].size()); | |
| 125 uint32 keepalive_timeout; | |
| 126 memcpy(&keepalive_timeout, tag_value_map[kKATO].data(), 4); | |
| 127 EXPECT_EQ(0u, keepalive_timeout); | |
| 128 | |
| 129 // kVERS | |
| 130 ASSERT_EQ(2u, tag_value_map[kVERS].size()); | |
| 131 uint16 version; | |
| 132 memcpy(&version, tag_value_map[kVERS].data(), 2); | |
| 133 EXPECT_EQ(0u, version); | |
| 134 | |
| 135 // kKEXS | |
| 136 ASSERT_EQ(8u, tag_value_map[kKEXS].size()); | |
| 137 CryptoTag key_exchange[2]; | |
| 138 memcpy(&key_exchange[0], &tag_value_map[kKEXS][0], 4); | |
| 139 memcpy(&key_exchange[1], &tag_value_map[kKEXS][4], 4); | |
| 140 EXPECT_EQ(kC255, key_exchange[0]); | |
| 141 EXPECT_EQ(kP256, key_exchange[1]); | |
| 142 | |
| 143 // kCGST | |
| 144 ASSERT_EQ(4u, tag_value_map[kCGST].size()); | |
| 145 CryptoTag congestion[1]; | |
| 146 memcpy(&congestion[0], &tag_value_map[kCGST][0], 4); | |
| 147 EXPECT_EQ(kQBIC, congestion[0]); | |
| 148 } | |
| 149 | |
| 150 // The same as MockSession, except that WriteData() is not mocked. | |
| 151 class TestMockSession : public MockSession { | |
| 152 public: | |
| 153 TestMockSession(QuicConnection* connection, bool is_server) | |
| 154 : MockSession(connection, is_server) { | |
| 155 } | |
| 156 virtual ~TestMockSession() {} | |
| 157 | |
| 158 virtual int WriteData(QuicStreamId id, base::StringPiece data, | |
| 159 QuicStreamOffset offset, bool fin) { | |
| 160 return QuicSession::WriteData(id, data, offset, fin); | |
| 161 } | |
|
wtc
2013/01/15 23:11:03
I had to use the real WriteData() method of sessio
Ryan Hamilton
2013/01/16 00:29:36
I think this should be fine. If it ever breaks, t
| |
| 162 }; | |
| 163 | |
| 14 class QuicCryptoClientStreamTest : public ::testing::Test { | 164 class QuicCryptoClientStreamTest : public ::testing::Test { |
| 15 public: | 165 public: |
| 16 QuicCryptoClientStreamTest() | 166 QuicCryptoClientStreamTest() |
| 17 : connection_(new MockConnection(1, addr_)), | 167 : connection_(new MockConnection(1, addr_, new TestMockHelper())), |
| 18 session_(connection_, true), | 168 session_(connection_, true), |
| 19 stream_(&session_) { | 169 stream_(&session_) { |
| 20 message_.tag = kSHLO; | 170 message_.tag = kSHLO; |
| 21 message_.tag_value_map[1] = "abc"; | 171 message_.tag_value_map[1] = "abc"; |
| 22 message_.tag_value_map[2] = "def"; | 172 message_.tag_value_map[2] = "def"; |
| 23 ConstructHandshakeMessage(); | 173 ConstructHandshakeMessage(); |
| 24 } | 174 } |
| 25 | 175 |
| 26 void ConstructHandshakeMessage() { | 176 void ConstructHandshakeMessage() { |
| 27 CryptoFramer framer; | 177 CryptoFramer framer; |
| 28 message_data_.reset(framer.ConstructHandshakeMessage(message_)); | 178 message_data_.reset(framer.ConstructHandshakeMessage(message_)); |
| 29 } | 179 } |
| 30 | 180 |
| 31 IPEndPoint addr_; | 181 IPEndPoint addr_; |
| 32 MockConnection* connection_; | 182 MockConnection* connection_; |
| 33 MockSession session_; | 183 TestMockSession session_; |
| 34 QuicCryptoClientStream stream_; | 184 QuicCryptoClientStream stream_; |
| 35 CryptoHandshakeMessage message_; | 185 CryptoHandshakeMessage message_; |
| 36 scoped_ptr<QuicData> message_data_; | 186 scoped_ptr<QuicData> message_data_; |
| 37 }; | 187 }; |
| 38 | 188 |
| 39 TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) { | 189 TEST_F(QuicCryptoClientStreamTest, NotInitiallyConected) { |
| 40 EXPECT_FALSE(stream_.handshake_complete()); | 190 EXPECT_FALSE(stream_.handshake_complete()); |
| 41 } | 191 } |
| 42 | 192 |
| 43 TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) { | 193 TEST_F(QuicCryptoClientStreamTest, ConnectedAfterSHLO) { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 55 | 205 |
| 56 TEST_F(QuicCryptoClientStreamTest, BadMessageType) { | 206 TEST_F(QuicCryptoClientStreamTest, BadMessageType) { |
| 57 message_.tag = kCHLO; | 207 message_.tag = kCHLO; |
| 58 ConstructHandshakeMessage(); | 208 ConstructHandshakeMessage(); |
| 59 | 209 |
| 60 EXPECT_CALL(*connection_, | 210 EXPECT_CALL(*connection_, |
| 61 SendConnectionClose(QUIC_INVALID_CRYPTO_MESSAGE_TYPE)); | 211 SendConnectionClose(QUIC_INVALID_CRYPTO_MESSAGE_TYPE)); |
| 62 stream_.ProcessData(message_data_->data(), message_data_->length()); | 212 stream_.ProcessData(message_data_->data(), message_data_->length()); |
| 63 } | 213 } |
| 64 | 214 |
| 215 TEST_F(QuicCryptoClientStreamTest, CryptoConnect) { | |
| 216 EXPECT_TRUE(stream_.CryptoConnect()); | |
| 217 } | |
| 218 | |
| 65 } // namespace | 219 } // namespace |
| 66 } // namespace test | 220 } // namespace test |
| 67 } // namespace net | 221 } // namespace net |
| OLD | NEW |