blob: 9381e05a2323f1d71f11d133dc5df1b5164e653c [file] [log] [blame]
[email protected]8b37a092012-10-18 21:53:491// 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/test_tools/quic_test_utils.h"
[email protected]9c0b1352012-11-04 00:03:276
[email protected]701bc892013-01-17 04:51:547#include "base/stl_util.h"
[email protected]8b37a092012-10-18 21:53:498#include "net/quic/crypto/crypto_framer.h"
[email protected]6f54ab32013-03-02 17:43:359#include "net/quic/crypto/crypto_handshake.h"
[email protected]872edd9e2013-01-16 08:51:1510#include "net/quic/crypto/crypto_utils.h"
[email protected]5351cc4b2013-03-03 07:22:4111#include "net/quic/crypto/null_encrypter.h"
[email protected]4df69842013-02-27 06:32:1612#include "net/quic/crypto/quic_decrypter.h"
13#include "net/quic/crypto/quic_encrypter.h"
[email protected]a57e0272013-04-26 07:31:4714#include "net/quic/quic_framer.h"
[email protected]5351cc4b2013-03-03 07:22:4115#include "net/quic/quic_packet_creator.h"
[email protected]c244c5a12013-05-07 20:55:0416#include "net/spdy/spdy_frame_builder.h"
[email protected]8b37a092012-10-18 21:53:4917
[email protected]c244c5a12013-05-07 20:55:0418using base::StringPiece;
[email protected]8b37a092012-10-18 21:53:4919using std::max;
20using std::min;
21using std::string;
[email protected]cff7b7b2013-01-11 08:49:0722using testing::_;
[email protected]8b37a092012-10-18 21:53:4923
24namespace net {
25namespace test {
[email protected]965dbe62013-08-09 21:34:3126namespace {
27
28// No-op alarm implementation used by MockHelper.
29class TestAlarm : public QuicAlarm {
30 public:
31 explicit TestAlarm(QuicAlarm::Delegate* delegate)
32 : QuicAlarm(delegate) {
33 }
34
35 virtual void SetImpl() OVERRIDE {}
36 virtual void CancelImpl() OVERRIDE {}
37};
38
39} // namespace
[email protected]8b37a092012-10-18 21:53:4940
41MockFramerVisitor::MockFramerVisitor() {
42 // By default, we want to accept packets.
[email protected]14e8106c2013-03-14 16:25:3343 ON_CALL(*this, OnProtocolVersionMismatch(_))
44 .WillByDefault(testing::Return(false));
45
46 // By default, we want to accept packets.
[email protected]cff7b7b2013-01-11 08:49:0747 ON_CALL(*this, OnPacketHeader(_))
[email protected]8b37a092012-10-18 21:53:4948 .WillByDefault(testing::Return(true));
[email protected]a57e0272013-04-26 07:31:4749
50 ON_CALL(*this, OnStreamFrame(_))
51 .WillByDefault(testing::Return(true));
52
53 ON_CALL(*this, OnAckFrame(_))
54 .WillByDefault(testing::Return(true));
55
56 ON_CALL(*this, OnCongestionFeedbackFrame(_))
57 .WillByDefault(testing::Return(true));
58
59 ON_CALL(*this, OnRstStreamFrame(_))
60 .WillByDefault(testing::Return(true));
61
62 ON_CALL(*this, OnConnectionCloseFrame(_))
63 .WillByDefault(testing::Return(true));
64
65 ON_CALL(*this, OnGoAwayFrame(_))
66 .WillByDefault(testing::Return(true));
[email protected]8b37a092012-10-18 21:53:4967}
68
[email protected]044ac2b2012-11-13 21:41:0669MockFramerVisitor::~MockFramerVisitor() {
70}
[email protected]8b37a092012-10-18 21:53:4971
[email protected]48878092013-07-26 14:51:5672bool NoOpFramerVisitor::OnProtocolVersionMismatch(QuicVersion version) {
[email protected]14e8106c2013-03-14 16:25:3373 return false;
74}
75
[email protected]8b37a092012-10-18 21:53:4976bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) {
77 return true;
78}
79
[email protected]a57e0272013-04-26 07:31:4780bool NoOpFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) {
81 return true;
82}
83
84bool NoOpFramerVisitor::OnAckFrame(const QuicAckFrame& frame) {
85 return true;
86}
87
88bool NoOpFramerVisitor::OnCongestionFeedbackFrame(
89 const QuicCongestionFeedbackFrame& frame) {
90 return true;
91}
92
93bool NoOpFramerVisitor::OnRstStreamFrame(
94 const QuicRstStreamFrame& frame) {
95 return true;
96}
97
98bool NoOpFramerVisitor::OnConnectionCloseFrame(
99 const QuicConnectionCloseFrame& frame) {
100 return true;
101}
102
103bool NoOpFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
104 return true;
105}
106
[email protected]9db443912013-02-25 05:27:03107FramerVisitorCapturingFrames::FramerVisitorCapturingFrames() : frame_count_(0) {
[email protected]134e5c32012-12-12 19:20:36108}
109
[email protected]9db443912013-02-25 05:27:03110FramerVisitorCapturingFrames::~FramerVisitorCapturingFrames() {
[email protected]26f3f8e2012-12-13 21:07:19111}
112
[email protected]9db443912013-02-25 05:27:03113bool FramerVisitorCapturingFrames::OnPacketHeader(
[email protected]4e6f0ed2012-11-02 22:15:38114 const QuicPacketHeader& header) {
115 header_ = header;
[email protected]9db443912013-02-25 05:27:03116 frame_count_ = 0;
[email protected]4e6f0ed2012-11-02 22:15:38117 return true;
118}
119
[email protected]a57e0272013-04-26 07:31:47120bool FramerVisitorCapturingFrames::OnStreamFrame(const QuicStreamFrame& frame) {
[email protected]9db443912013-02-25 05:27:03121 // TODO(ianswett): Own the underlying string, so it will not exist outside
122 // this callback.
123 stream_frames_.push_back(frame);
124 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47125 return true;
[email protected]26f3f8e2012-12-13 21:07:19126}
127
[email protected]a57e0272013-04-26 07:31:47128bool FramerVisitorCapturingFrames::OnAckFrame(const QuicAckFrame& frame) {
[email protected]9db443912013-02-25 05:27:03129 ack_.reset(new QuicAckFrame(frame));
130 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47131 return true;
[email protected]9db443912013-02-25 05:27:03132}
133
[email protected]a57e0272013-04-26 07:31:47134bool FramerVisitorCapturingFrames::OnCongestionFeedbackFrame(
[email protected]26f3f8e2012-12-13 21:07:19135 const QuicCongestionFeedbackFrame& frame) {
136 feedback_.reset(new QuicCongestionFeedbackFrame(frame));
[email protected]9db443912013-02-25 05:27:03137 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47138 return true;
[email protected]9db443912013-02-25 05:27:03139}
140
[email protected]a57e0272013-04-26 07:31:47141bool FramerVisitorCapturingFrames::OnRstStreamFrame(
[email protected]9db443912013-02-25 05:27:03142 const QuicRstStreamFrame& frame) {
143 rst_.reset(new QuicRstStreamFrame(frame));
144 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47145 return true;
[email protected]9db443912013-02-25 05:27:03146}
147
[email protected]a57e0272013-04-26 07:31:47148bool FramerVisitorCapturingFrames::OnConnectionCloseFrame(
[email protected]9db443912013-02-25 05:27:03149 const QuicConnectionCloseFrame& frame) {
150 close_.reset(new QuicConnectionCloseFrame(frame));
151 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47152 return true;
[email protected]9db443912013-02-25 05:27:03153}
154
[email protected]a57e0272013-04-26 07:31:47155bool FramerVisitorCapturingFrames::OnGoAwayFrame(const QuicGoAwayFrame& frame) {
[email protected]9db443912013-02-25 05:27:03156 goaway_.reset(new QuicGoAwayFrame(frame));
157 ++frame_count_;
[email protected]a57e0272013-04-26 07:31:47158 return true;
[email protected]4e6f0ed2012-11-02 22:15:38159}
160
[email protected]14e8106c2013-03-14 16:25:33161void FramerVisitorCapturingFrames::OnVersionNegotiationPacket(
162 const QuicVersionNegotiationPacket& packet) {
163 version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet));
164 frame_count_ = 0;
165}
166
[email protected]fee17f72013-02-03 07:47:41167FramerVisitorCapturingPublicReset::FramerVisitorCapturingPublicReset() {
168}
169
170FramerVisitorCapturingPublicReset::~FramerVisitorCapturingPublicReset() {
171}
172
173void FramerVisitorCapturingPublicReset::OnPublicResetPacket(
174 const QuicPublicResetPacket& public_reset) {
175 public_reset_packet_ = public_reset;
176}
177
[email protected]8d659e22013-01-19 04:26:10178MockConnectionVisitor::MockConnectionVisitor() {
179}
180
181MockConnectionVisitor::~MockConnectionVisitor() {
182}
183
[email protected]9c0b1352012-11-04 00:03:27184MockHelper::MockHelper() {
185}
186
187MockHelper::~MockHelper() {
188}
189
[email protected]97693d12012-11-16 16:05:00190const QuicClock* MockHelper::GetClock() const {
[email protected]9c0b1352012-11-04 00:03:27191 return &clock_;
192}
193
[email protected]9558c5d32012-12-22 00:08:14194QuicRandom* MockHelper::GetRandomGenerator() {
195 return &random_generator_;
196}
197
[email protected]965dbe62013-08-09 21:34:31198QuicAlarm* MockHelper::CreateAlarm(QuicAlarm::Delegate* delegate) {
199 return new TestAlarm(delegate);
200}
201
[email protected]fe053f92013-04-23 20:18:55202void MockHelper::AdvanceTime(QuicTime::Delta delta) {
203 clock_.AdvanceTime(delta);
204}
205
[email protected]14e8106c2013-03-14 16:25:33206MockConnection::MockConnection(QuicGuid guid,
207 IPEndPoint address,
208 bool is_server)
[email protected]2532de12013-05-09 12:29:33209 : QuicConnection(guid, address, new testing::NiceMock<MockHelper>(),
[email protected]48878092013-07-26 14:51:56210 is_server, QuicVersionMax()),
[email protected]fe053f92013-04-23 20:18:55211 has_mock_helper_(true) {
[email protected]044ac2b2012-11-13 21:41:06212}
213
[email protected]872edd9e2013-01-16 08:51:15214MockConnection::MockConnection(QuicGuid guid,
215 IPEndPoint address,
[email protected]14e8106c2013-03-14 16:25:33216 QuicConnectionHelperInterface* helper,
217 bool is_server)
[email protected]48878092013-07-26 14:51:56218 : QuicConnection(guid, address, helper, is_server, QuicVersionMax()),
[email protected]fe053f92013-04-23 20:18:55219 has_mock_helper_(false) {
[email protected]872edd9e2013-01-16 08:51:15220}
221
[email protected]044ac2b2012-11-13 21:41:06222MockConnection::~MockConnection() {
223}
224
[email protected]fe053f92013-04-23 20:18:55225void MockConnection::AdvanceTime(QuicTime::Delta delta) {
226 CHECK(has_mock_helper_) << "Cannot advance time unless a MockClock is being"
227 " used";
228 static_cast<MockHelper*>(helper())->AdvanceTime(delta);
229}
230
[email protected]044ac2b2012-11-13 21:41:06231PacketSavingConnection::PacketSavingConnection(QuicGuid guid,
[email protected]14e8106c2013-03-14 16:25:33232 IPEndPoint address,
233 bool is_server)
234 : MockConnection(guid, address, is_server) {
[email protected]044ac2b2012-11-13 21:41:06235}
236
237PacketSavingConnection::~PacketSavingConnection() {
[email protected]701bc892013-01-17 04:51:54238 STLDeleteElements(&packets_);
[email protected]2532de12013-05-09 12:29:33239 STLDeleteElements(&encrypted_packets_);
[email protected]044ac2b2012-11-13 21:41:06240}
241
[email protected]fee17f72013-02-03 07:47:41242bool PacketSavingConnection::SendOrQueuePacket(
[email protected]8ba81212013-05-03 13:11:48243 EncryptionLevel level,
[email protected]fee17f72013-02-03 07:47:41244 QuicPacketSequenceNumber sequence_number,
245 QuicPacket* packet,
[email protected]ed3fc15d2013-03-08 18:37:44246 QuicPacketEntropyHash entropy_hash,
[email protected]74bda142013-03-31 02:49:11247 HasRetransmittableData retransmittable) {
[email protected]044ac2b2012-11-13 21:41:06248 packets_.push_back(packet);
[email protected]2532de12013-05-09 12:29:33249 QuicEncryptedPacket* encrypted =
250 framer_.EncryptPacket(level, sequence_number, *packet);
251 encrypted_packets_.push_back(encrypted);
[email protected]044ac2b2012-11-13 21:41:06252 return true;
253}
254
255MockSession::MockSession(QuicConnection* connection, bool is_server)
[email protected]b064310782013-05-30 21:12:17256 : QuicSession(connection, DefaultQuicConfig(), is_server) {
[email protected]cff7b7b2013-01-11 08:49:07257 ON_CALL(*this, WriteData(_, _, _, _))
258 .WillByDefault(testing::Return(QuicConsumedData(0, false)));
[email protected]044ac2b2012-11-13 21:41:06259}
260
261MockSession::~MockSession() {
262}
263
[email protected]899951652013-05-16 12:52:39264TestSession::TestSession(QuicConnection* connection,
265 const QuicConfig& config,
266 bool is_server)
267 : QuicSession(connection, config, is_server),
[email protected]2532de12013-05-09 12:29:33268 crypto_stream_(NULL) {
269}
270
[email protected]b064310782013-05-30 21:12:17271TestSession::~TestSession() {}
[email protected]2532de12013-05-09 12:29:33272
273void TestSession::SetCryptoStream(QuicCryptoStream* stream) {
274 crypto_stream_ = stream;
275}
276
277QuicCryptoStream* TestSession::GetCryptoStream() {
278 return crypto_stream_;
279}
280
[email protected]fee17f72013-02-03 07:47:41281MockSendAlgorithm::MockSendAlgorithm() {
[email protected]8d659e22013-01-19 04:26:10282}
283
[email protected]fee17f72013-02-03 07:47:41284MockSendAlgorithm::~MockSendAlgorithm() {
[email protected]8d659e22013-01-19 04:26:10285}
286
[email protected]97cf3022013-09-05 14:30:16287MockAckNotifierDelegate::MockAckNotifierDelegate() {
288}
289
290MockAckNotifierDelegate::~MockAckNotifierDelegate() {
291}
292
[email protected]8b37a092012-10-18 21:53:49293namespace {
294
295string HexDumpWithMarks(const char* data, int length,
296 const bool* marks, int mark_length) {
297 static const char kHexChars[] = "0123456789abcdef";
298 static const int kColumns = 4;
299
300 const int kSizeLimit = 1024;
301 if (length > kSizeLimit || mark_length > kSizeLimit) {
302 LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes.";
303 length = min(length, kSizeLimit);
304 mark_length = min(mark_length, kSizeLimit);
305 }
306
307 string hex;
308 for (const char* row = data; length > 0;
309 row += kColumns, length -= kColumns) {
310 for (const char *p = row; p < row + 4; ++p) {
311 if (p < row + length) {
312 const bool mark =
313 (marks && (p - data) < mark_length && marks[p - data]);
314 hex += mark ? '*' : ' ';
315 hex += kHexChars[(*p & 0xf0) >> 4];
316 hex += kHexChars[*p & 0x0f];
317 hex += mark ? '*' : ' ';
318 } else {
319 hex += " ";
320 }
321 }
322 hex = hex + " ";
323
324 for (const char *p = row; p < row + 4 && p < row + length; ++p)
325 hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.';
326
327 hex = hex + '\n';
328 }
329 return hex;
330}
331
332} // namespace
333
334void CompareCharArraysWithHexError(
335 const string& description,
336 const char* actual,
337 const int actual_len,
338 const char* expected,
339 const int expected_len) {
340 const int min_len = min(actual_len, expected_len);
341 const int max_len = max(actual_len, expected_len);
[email protected]4356f0f2013-04-07 00:58:17342 scoped_ptr<bool[]> marks(new bool[max_len]);
[email protected]8b37a092012-10-18 21:53:49343 bool identical = (actual_len == expected_len);
344 for (int i = 0; i < min_len; ++i) {
345 if (actual[i] != expected[i]) {
346 marks[i] = true;
347 identical = false;
348 } else {
349 marks[i] = false;
350 }
351 }
352 for (int i = min_len; i < max_len; ++i) {
353 marks[i] = true;
354 }
355 if (identical) return;
356 ADD_FAILURE()
357 << "Description:\n"
358 << description
359 << "\n\nExpected:\n"
360 << HexDumpWithMarks(expected, expected_len, marks.get(), max_len)
361 << "\nActual:\n"
362 << HexDumpWithMarks(actual, actual_len, marks.get(), max_len);
363}
364
[email protected]d3d15bf2013-01-30 02:51:54365static QuicPacket* ConstructPacketFromHandshakeMessage(
366 QuicGuid guid,
[email protected]14e8106c2013-03-14 16:25:33367 const CryptoHandshakeMessage& message,
368 bool should_include_version) {
[email protected]8b37a092012-10-18 21:53:49369 CryptoFramer crypto_framer;
[email protected]dc2cc742012-10-21 13:56:13370 scoped_ptr<QuicData> data(crypto_framer.ConstructHandshakeMessage(message));
[email protected]48878092013-07-26 14:51:56371 QuicFramer quic_framer(QuicVersionMax(), QuicTime::Zero(), false);
[email protected]8b37a092012-10-18 21:53:49372
373 QuicPacketHeader header;
[email protected]c995c572013-01-18 05:43:20374 header.public_header.guid = guid;
[email protected]9db443912013-02-25 05:27:03375 header.public_header.reset_flag = false;
[email protected]14e8106c2013-03-14 16:25:33376 header.public_header.version_flag = should_include_version;
[email protected]8b37a092012-10-18 21:53:49377 header.packet_sequence_number = 1;
[email protected]9db443912013-02-25 05:27:03378 header.entropy_flag = false;
379 header.entropy_hash = 0;
380 header.fec_flag = false;
[email protected]8b37a092012-10-18 21:53:49381 header.fec_group = 0;
382
[email protected]be24ab22012-10-22 03:01:52383 QuicStreamFrame stream_frame(kCryptoStreamId, false, 0,
[email protected]044ac2b2012-11-13 21:41:06384 data->AsStringPiece());
[email protected]8b37a092012-10-18 21:53:49385
[email protected]be24ab22012-10-22 03:01:52386 QuicFrame frame(&stream_frame);
387 QuicFrames frames;
388 frames.push_back(frame);
[email protected]3e60db82013-08-05 19:43:06389 return quic_framer.BuildUnsizedDataPacket(header, frames).packet;
[email protected]8b37a092012-10-18 21:53:49390}
391
[email protected]2532de12013-05-09 12:29:33392QuicPacket* ConstructHandshakePacket(QuicGuid guid, QuicTag tag) {
[email protected]d3d15bf2013-01-30 02:51:54393 CryptoHandshakeMessage message;
[email protected]ccc66e8a2013-03-26 08:26:14394 message.set_tag(tag);
[email protected]14e8106c2013-03-14 16:25:33395 return ConstructPacketFromHandshakeMessage(guid, message, false);
[email protected]d3d15bf2013-01-30 02:51:54396}
397
[email protected]ea825e02013-08-21 18:12:45398size_t GetPacketLengthForOneStream(
399 QuicVersion version,
400 bool include_version,
401 QuicSequenceNumberLength sequence_number_length,
402 InFecGroup is_in_fec_group,
403 size_t* payload_length) {
[email protected]f62262b2013-07-05 20:57:30404 *payload_length = 1;
405 const size_t stream_length =
406 NullEncrypter().GetCiphertextSize(*payload_length) +
[email protected]b064310782013-05-30 21:12:17407 QuicPacketCreator::StreamFramePacketOverhead(
[email protected]3e60db82013-08-05 19:43:06408 version, PACKET_8BYTE_GUID, include_version,
[email protected]ea825e02013-08-21 18:12:45409 sequence_number_length, is_in_fec_group);
[email protected]f62262b2013-07-05 20:57:30410 const size_t ack_length = NullEncrypter().GetCiphertextSize(
[email protected]b064310782013-05-30 21:12:17411 QuicFramer::GetMinAckFrameSize()) +
[email protected]25c31dc2013-06-05 17:56:04412 GetPacketHeaderSize(PACKET_8BYTE_GUID, include_version,
[email protected]ea825e02013-08-21 18:12:45413 sequence_number_length, is_in_fec_group);
[email protected]f62262b2013-07-05 20:57:30414 if (stream_length < ack_length) {
415 *payload_length = 1 + ack_length - stream_length;
416 }
417
418 return NullEncrypter().GetCiphertextSize(*payload_length) +
419 QuicPacketCreator::StreamFramePacketOverhead(
[email protected]3e60db82013-08-05 19:43:06420 version, PACKET_8BYTE_GUID, include_version,
[email protected]ea825e02013-08-21 18:12:45421 sequence_number_length, is_in_fec_group);
[email protected]5351cc4b2013-03-03 07:22:41422}
423
[email protected]ea2ab47b2013-08-13 00:44:11424// Size in bytes of the stream frame fields for an arbitrary StreamID and
425// offset and the last frame in a packet.
[email protected]3e60db82013-08-05 19:43:06426size_t GetMinStreamFrameSize(QuicVersion version) {
[email protected]ea2ab47b2013-08-13 00:44:11427 return kQuicFrameTypeSize + kQuicMaxStreamIdSize + kQuicMaxStreamOffsetSize;
[email protected]3e60db82013-08-05 19:43:06428}
429
[email protected]48878092013-07-26 14:51:56430QuicPacketEntropyHash TestEntropyCalculator::EntropyHash(
[email protected]9db443912013-02-25 05:27:03431 QuicPacketSequenceNumber sequence_number) const {
432 return 1u;
433}
434
[email protected]b064310782013-05-30 21:12:17435QuicConfig DefaultQuicConfig() {
436 QuicConfig config;
437 config.SetDefaults();
438 return config;
439}
440
[email protected]c244c5a12013-05-07 20:55:04441bool TestDecompressorVisitor::OnDecompressedData(StringPiece data) {
442 data.AppendToString(&data_);
443 return true;
444}
445
[email protected]899951652013-05-16 12:52:39446void TestDecompressorVisitor::OnDecompressionError() {
447 error_ = true;
448}
449
[email protected]8b37a092012-10-18 21:53:49450} // namespace test
[email protected]8b37a092012-10-18 21:53:49451} // namespace net