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/test_tools/quic_test_utils.h"
8 #include "base/stl_util.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "net/quic/crypto/crypto_framer.h"
11 #include "net/quic/crypto/crypto_handshake.h"
12 #include "net/quic/crypto/crypto_utils.h"
13 #include "net/quic/crypto/null_encrypter.h"
14 #include "net/quic/crypto/quic_decrypter.h"
15 #include "net/quic/crypto/quic_encrypter.h"
16 #include "net/quic/quic_data_writer.h"
17 #include "net/quic/quic_framer.h"
18 #include "net/quic/quic_packet_creator.h"
19 #include "net/quic/quic_utils.h"
20 #include "net/quic/test_tools/quic_connection_peer.h"
21 #include "net/spdy/spdy_frame_builder.h"
22 #include "net/tools/quic/quic_per_connection_packet_writer.h"
24 using base::StringPiece
;
28 using testing::AnyNumber
;
35 // No-op alarm implementation used by MockHelper.
36 class TestAlarm
: public QuicAlarm
{
38 explicit TestAlarm(QuicAlarm::Delegate
* delegate
)
39 : QuicAlarm(delegate
) {
42 void SetImpl() override
{}
43 void CancelImpl() override
{}
48 QuicAckFrame
MakeAckFrame(QuicPacketSequenceNumber largest_observed
) {
50 ack
.largest_observed
= largest_observed
;
55 QuicAckFrame
MakeAckFrameWithNackRanges(
56 size_t num_nack_ranges
, QuicPacketSequenceNumber least_unacked
) {
57 QuicAckFrame ack
= MakeAckFrame(2 * num_nack_ranges
+ least_unacked
);
58 // Add enough missing packets to get num_nack_ranges nack ranges.
59 for (QuicPacketSequenceNumber i
= 1; i
< 2 * num_nack_ranges
; i
+= 2) {
60 ack
.missing_packets
.insert(least_unacked
+ i
);
65 QuicPacket
* BuildUnsizedDataPacket(QuicFramer
* framer
,
66 const QuicPacketHeader
& header
,
67 const QuicFrames
& frames
) {
68 const size_t max_plaintext_size
= framer
->GetMaxPlaintextSize(kMaxPacketSize
);
69 size_t packet_size
= GetPacketHeaderSize(header
);
70 for (size_t i
= 0; i
< frames
.size(); ++i
) {
71 DCHECK_LE(packet_size
, max_plaintext_size
);
72 bool first_frame
= i
== 0;
73 bool last_frame
= i
== frames
.size() - 1;
74 const size_t frame_size
= framer
->GetSerializedFrameLength(
75 frames
[i
], max_plaintext_size
- packet_size
, first_frame
, last_frame
,
76 header
.is_in_fec_group
,
77 header
.public_header
.sequence_number_length
);
79 packet_size
+= frame_size
;
81 return BuildUnsizedDataPacket(framer
, header
, frames
, packet_size
);
84 QuicPacket
* BuildUnsizedDataPacket(QuicFramer
* framer
,
85 const QuicPacketHeader
& header
,
86 const QuicFrames
& frames
,
88 char* buffer
= new char[packet_size
];
89 scoped_ptr
<QuicPacket
> packet(
90 framer
->BuildDataPacket(header
, frames
, buffer
, packet_size
));
91 DCHECK(packet
.get() != nullptr);
92 // Now I have to re-construct the data packet with data ownership.
93 return new QuicPacket(buffer
, packet
->length(), true,
94 header
.public_header
.connection_id_length
,
95 header
.public_header
.version_flag
,
96 header
.public_header
.sequence_number_length
);
99 uint64
SimpleRandom::RandUint64() {
100 unsigned char hash
[base::kSHA1Length
];
101 base::SHA1HashBytes(reinterpret_cast<unsigned char*>(&seed_
), sizeof(seed_
),
103 memcpy(&seed_
, hash
, sizeof(seed_
));
107 MockFramerVisitor::MockFramerVisitor() {
108 // By default, we want to accept packets.
109 ON_CALL(*this, OnProtocolVersionMismatch(_
))
110 .WillByDefault(testing::Return(false));
112 // By default, we want to accept packets.
113 ON_CALL(*this, OnUnauthenticatedHeader(_
))
114 .WillByDefault(testing::Return(true));
116 ON_CALL(*this, OnUnauthenticatedPublicHeader(_
))
117 .WillByDefault(testing::Return(true));
119 ON_CALL(*this, OnPacketHeader(_
))
120 .WillByDefault(testing::Return(true));
122 ON_CALL(*this, OnStreamFrame(_
))
123 .WillByDefault(testing::Return(true));
125 ON_CALL(*this, OnAckFrame(_
))
126 .WillByDefault(testing::Return(true));
128 ON_CALL(*this, OnStopWaitingFrame(_
))
129 .WillByDefault(testing::Return(true));
131 ON_CALL(*this, OnPingFrame(_
))
132 .WillByDefault(testing::Return(true));
134 ON_CALL(*this, OnRstStreamFrame(_
))
135 .WillByDefault(testing::Return(true));
137 ON_CALL(*this, OnConnectionCloseFrame(_
))
138 .WillByDefault(testing::Return(true));
140 ON_CALL(*this, OnGoAwayFrame(_
))
141 .WillByDefault(testing::Return(true));
144 MockFramerVisitor::~MockFramerVisitor() {
147 bool NoOpFramerVisitor::OnProtocolVersionMismatch(QuicVersion version
) {
151 bool NoOpFramerVisitor::OnUnauthenticatedPublicHeader(
152 const QuicPacketPublicHeader
& header
) {
156 bool NoOpFramerVisitor::OnUnauthenticatedHeader(
157 const QuicPacketHeader
& header
) {
161 bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader
& header
) {
165 bool NoOpFramerVisitor::OnStreamFrame(const QuicStreamFrame
& frame
) {
169 bool NoOpFramerVisitor::OnAckFrame(const QuicAckFrame
& frame
) {
173 bool NoOpFramerVisitor::OnStopWaitingFrame(
174 const QuicStopWaitingFrame
& frame
) {
178 bool NoOpFramerVisitor::OnPingFrame(const QuicPingFrame
& frame
) {
182 bool NoOpFramerVisitor::OnRstStreamFrame(
183 const QuicRstStreamFrame
& frame
) {
187 bool NoOpFramerVisitor::OnConnectionCloseFrame(
188 const QuicConnectionCloseFrame
& frame
) {
192 bool NoOpFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame
& frame
) {
196 bool NoOpFramerVisitor::OnWindowUpdateFrame(
197 const QuicWindowUpdateFrame
& frame
) {
201 bool NoOpFramerVisitor::OnBlockedFrame(const QuicBlockedFrame
& frame
) {
205 MockConnectionVisitor::MockConnectionVisitor() {
208 MockConnectionVisitor::~MockConnectionVisitor() {
211 MockHelper::MockHelper() {
214 MockHelper::~MockHelper() {
217 const QuicClock
* MockHelper::GetClock() const {
221 QuicRandom
* MockHelper::GetRandomGenerator() {
222 return &random_generator_
;
225 QuicAlarm
* MockHelper::CreateAlarm(QuicAlarm::Delegate
* delegate
) {
226 return new TestAlarm(delegate
);
229 void MockHelper::AdvanceTime(QuicTime::Delta delta
) {
230 clock_
.AdvanceTime(delta
);
233 QuicPacketWriter
* NiceMockPacketWriterFactory::Create(
234 QuicConnection
* /*connection*/) const {
235 return new testing::NiceMock
<MockPacketWriter
>();
238 MockConnection::MockConnection(Perspective perspective
)
239 : QuicConnection(kTestConnectionId
,
240 IPEndPoint(TestPeerIPAddress(), kTestPort
),
241 new testing::NiceMock
<MockHelper
>(),
242 NiceMockPacketWriterFactory(),
243 /* owns_writer= */ true,
245 /* is_secure= */ false,
246 QuicSupportedVersions()),
250 MockConnection::MockConnection(Perspective perspective
, bool is_secure
)
251 : QuicConnection(kTestConnectionId
,
252 IPEndPoint(TestPeerIPAddress(), kTestPort
),
253 new testing::NiceMock
<MockHelper
>(),
254 NiceMockPacketWriterFactory(),
255 /* owns_writer= */ true,
258 QuicSupportedVersions()),
262 MockConnection::MockConnection(IPEndPoint address
, Perspective perspective
)
263 : QuicConnection(kTestConnectionId
,
265 new testing::NiceMock
<MockHelper
>(),
266 NiceMockPacketWriterFactory(),
267 /* owns_writer= */ true,
269 /* is_secure= */ false,
270 QuicSupportedVersions()),
274 MockConnection::MockConnection(QuicConnectionId connection_id
,
275 Perspective perspective
)
276 : QuicConnection(connection_id
,
277 IPEndPoint(TestPeerIPAddress(), kTestPort
),
278 new testing::NiceMock
<MockHelper
>(),
279 NiceMockPacketWriterFactory(),
280 /* owns_writer= */ true,
282 /* is_secure= */ false,
283 QuicSupportedVersions()),
287 MockConnection::MockConnection(QuicConnectionId connection_id
,
288 Perspective perspective
,
290 : QuicConnection(connection_id
,
291 IPEndPoint(TestPeerIPAddress(), kTestPort
),
292 new testing::NiceMock
<MockHelper
>(),
293 NiceMockPacketWriterFactory(),
294 /* owns_writer= */ true,
297 QuicSupportedVersions()),
301 MockConnection::MockConnection(Perspective perspective
,
302 const QuicVersionVector
& supported_versions
)
303 : QuicConnection(kTestConnectionId
,
304 IPEndPoint(TestPeerIPAddress(), kTestPort
),
305 new testing::NiceMock
<MockHelper
>(),
306 NiceMockPacketWriterFactory(),
307 /* owns_writer= */ true,
309 /* is_secure= */ false,
314 MockConnection::~MockConnection() {
317 void MockConnection::AdvanceTime(QuicTime::Delta delta
) {
318 static_cast<MockHelper
*>(helper())->AdvanceTime(delta
);
321 PacketSavingConnection::PacketSavingConnection(Perspective perspective
)
322 : MockConnection(perspective
) {
325 PacketSavingConnection::PacketSavingConnection(
326 Perspective perspective
,
327 const QuicVersionVector
& supported_versions
)
328 : MockConnection(perspective
, supported_versions
) {
331 PacketSavingConnection::~PacketSavingConnection() {
332 STLDeleteElements(&encrypted_packets_
);
335 void PacketSavingConnection::SendOrQueuePacket(QueuedPacket packet
) {
336 encrypted_packets_
.push_back(packet
.serialized_packet
.packet
);
337 // Transfer ownership of the packet to the SentPacketManager and the
338 // ack notifier to the AckNotifierManager.
339 sent_packet_manager_
.OnPacketSent(
340 &packet
.serialized_packet
, 0, QuicTime::Zero(), 1000,
341 NOT_RETRANSMISSION
, HAS_RETRANSMITTABLE_DATA
);
344 MockSession::MockSession(QuicConnection
* connection
)
345 : QuicSession(connection
, DefaultQuicConfig()) {
347 ON_CALL(*this, WritevData(_
, _
, _
, _
, _
, _
))
348 .WillByDefault(testing::Return(QuicConsumedData(0, false)));
351 MockSession::~MockSession() {
354 TestSession::TestSession(QuicConnection
* connection
, const QuicConfig
& config
)
355 : QuicSession(connection
, config
),
356 crypto_stream_(nullptr) {
360 TestSession::~TestSession() {}
362 void TestSession::SetCryptoStream(QuicCryptoStream
* stream
) {
363 crypto_stream_
= stream
;
366 QuicCryptoStream
* TestSession::GetCryptoStream() {
367 return crypto_stream_
;
370 TestClientSession::TestClientSession(QuicConnection
* connection
,
371 const QuicConfig
& config
)
372 : QuicClientSessionBase(connection
, config
),
373 crypto_stream_(nullptr) {
374 EXPECT_CALL(*this, OnProofValid(_
)).Times(AnyNumber());
378 TestClientSession::~TestClientSession() {}
380 void TestClientSession::SetCryptoStream(QuicCryptoStream
* stream
) {
381 crypto_stream_
= stream
;
384 QuicCryptoStream
* TestClientSession::GetCryptoStream() {
385 return crypto_stream_
;
388 MockPacketWriter::MockPacketWriter() {
391 MockPacketWriter::~MockPacketWriter() {
394 MockSendAlgorithm::MockSendAlgorithm() {
397 MockSendAlgorithm::~MockSendAlgorithm() {
400 MockLossAlgorithm::MockLossAlgorithm() {
403 MockLossAlgorithm::~MockLossAlgorithm() {
406 MockAckNotifierDelegate::MockAckNotifierDelegate() {
409 MockAckNotifierDelegate::~MockAckNotifierDelegate() {
412 MockNetworkChangeVisitor::MockNetworkChangeVisitor() {
415 MockNetworkChangeVisitor::~MockNetworkChangeVisitor() {
420 string
HexDumpWithMarks(const char* data
, int length
,
421 const bool* marks
, int mark_length
) {
422 static const char kHexChars
[] = "0123456789abcdef";
423 static const int kColumns
= 4;
425 const int kSizeLimit
= 1024;
426 if (length
> kSizeLimit
|| mark_length
> kSizeLimit
) {
427 LOG(ERROR
) << "Only dumping first " << kSizeLimit
<< " bytes.";
428 length
= min(length
, kSizeLimit
);
429 mark_length
= min(mark_length
, kSizeLimit
);
433 for (const char* row
= data
; length
> 0;
434 row
+= kColumns
, length
-= kColumns
) {
435 for (const char *p
= row
; p
< row
+ 4; ++p
) {
436 if (p
< row
+ length
) {
438 (marks
&& (p
- data
) < mark_length
&& marks
[p
- data
]);
439 hex
+= mark
? '*' : ' ';
440 hex
+= kHexChars
[(*p
& 0xf0) >> 4];
441 hex
+= kHexChars
[*p
& 0x0f];
442 hex
+= mark
? '*' : ' ';
449 for (const char* p
= row
; p
< row
+ 4 && p
< row
+ length
; ++p
) {
450 hex
+= (*p
>= 0x20 && *p
<= 0x7f) ? (*p
) : '.';
460 IPAddressNumber
TestPeerIPAddress() { return Loopback4(); }
462 QuicVersion
QuicVersionMax() { return QuicSupportedVersions().front(); }
464 QuicVersion
QuicVersionMin() { return QuicSupportedVersions().back(); }
466 IPAddressNumber
Loopback4() {
467 IPAddressNumber addr
;
468 CHECK(ParseIPLiteralToNumber("127.0.0.1", &addr
));
472 IPAddressNumber
Loopback6() {
473 IPAddressNumber addr
;
474 CHECK(ParseIPLiteralToNumber("::1", &addr
));
478 void GenerateBody(string
* body
, int length
) {
480 body
->reserve(length
);
481 for (int i
= 0; i
< length
; ++i
) {
482 body
->append(1, static_cast<char>(32 + i
% (126 - 32)));
486 QuicEncryptedPacket
* ConstructEncryptedPacket(
487 QuicConnectionId connection_id
,
490 QuicPacketSequenceNumber sequence_number
,
491 const string
& data
) {
492 return ConstructEncryptedPacket(
493 connection_id
, version_flag
, reset_flag
, sequence_number
, data
,
494 PACKET_8BYTE_CONNECTION_ID
, PACKET_6BYTE_SEQUENCE_NUMBER
);
497 QuicEncryptedPacket
* ConstructEncryptedPacket(
498 QuicConnectionId connection_id
,
501 QuicPacketSequenceNumber sequence_number
,
503 QuicConnectionIdLength connection_id_length
,
504 QuicSequenceNumberLength sequence_number_length
) {
505 QuicPacketHeader header
;
506 header
.public_header
.connection_id
= connection_id
;
507 header
.public_header
.connection_id_length
= connection_id_length
;
508 header
.public_header
.version_flag
= version_flag
;
509 header
.public_header
.reset_flag
= reset_flag
;
510 header
.public_header
.sequence_number_length
= sequence_number_length
;
511 header
.packet_sequence_number
= sequence_number
;
512 header
.entropy_flag
= false;
513 header
.entropy_hash
= 0;
514 header
.fec_flag
= false;
515 header
.is_in_fec_group
= NOT_IN_FEC_GROUP
;
516 header
.fec_group
= 0;
517 QuicStreamFrame
stream_frame(1, false, 0, MakeIOVector(data
));
518 QuicFrame
frame(&stream_frame
);
520 frames
.push_back(frame
);
521 QuicFramer
framer(QuicSupportedVersions(), QuicTime::Zero(),
522 Perspective::IS_CLIENT
);
523 scoped_ptr
<QuicPacket
> packet(
524 BuildUnsizedDataPacket(&framer
, header
, frames
));
525 EXPECT_TRUE(packet
!= nullptr);
526 QuicEncryptedPacket
* encrypted
= framer
.EncryptPacket(ENCRYPTION_NONE
,
529 EXPECT_TRUE(encrypted
!= nullptr);
533 void CompareCharArraysWithHexError(
534 const string
& description
,
536 const int actual_len
,
537 const char* expected
,
538 const int expected_len
) {
539 EXPECT_EQ(actual_len
, expected_len
);
540 const int min_len
= min(actual_len
, expected_len
);
541 const int max_len
= max(actual_len
, expected_len
);
542 scoped_ptr
<bool[]> marks(new bool[max_len
]);
543 bool identical
= (actual_len
== expected_len
);
544 for (int i
= 0; i
< min_len
; ++i
) {
545 if (actual
[i
] != expected
[i
]) {
552 for (int i
= min_len
; i
< max_len
; ++i
) {
555 if (identical
) return;
560 << HexDumpWithMarks(expected
, expected_len
, marks
.get(), max_len
)
562 << HexDumpWithMarks(actual
, actual_len
, marks
.get(), max_len
);
565 bool DecodeHexString(const base::StringPiece
& hex
, std::string
* bytes
) {
569 std::vector
<uint8
> v
;
570 if (!base::HexStringToBytes(hex
.as_string(), &v
))
573 bytes
->assign(reinterpret_cast<const char*>(&v
[0]), v
.size());
577 static QuicPacket
* ConstructPacketFromHandshakeMessage(
578 QuicConnectionId connection_id
,
579 const CryptoHandshakeMessage
& message
,
580 bool should_include_version
) {
581 CryptoFramer crypto_framer
;
582 scoped_ptr
<QuicData
> data(crypto_framer
.ConstructHandshakeMessage(message
));
583 QuicFramer
quic_framer(QuicSupportedVersions(), QuicTime::Zero(),
584 Perspective::IS_CLIENT
);
586 QuicPacketHeader header
;
587 header
.public_header
.connection_id
= connection_id
;
588 header
.public_header
.reset_flag
= false;
589 header
.public_header
.version_flag
= should_include_version
;
590 header
.packet_sequence_number
= 1;
591 header
.entropy_flag
= false;
592 header
.entropy_hash
= 0;
593 header
.fec_flag
= false;
594 header
.fec_group
= 0;
596 QuicStreamFrame
stream_frame(kCryptoStreamId
, false, 0,
597 MakeIOVector(data
->AsStringPiece()));
599 QuicFrame
frame(&stream_frame
);
601 frames
.push_back(frame
);
602 return BuildUnsizedDataPacket(&quic_framer
, header
, frames
);
605 QuicPacket
* ConstructHandshakePacket(QuicConnectionId connection_id
,
607 CryptoHandshakeMessage message
;
608 message
.set_tag(tag
);
609 return ConstructPacketFromHandshakeMessage(connection_id
, message
, false);
612 size_t GetPacketLengthForOneStream(
614 bool include_version
,
615 QuicConnectionIdLength connection_id_length
,
616 QuicSequenceNumberLength sequence_number_length
,
617 InFecGroup is_in_fec_group
,
618 size_t* payload_length
) {
620 const size_t stream_length
=
621 NullEncrypter().GetCiphertextSize(*payload_length
) +
622 QuicPacketCreator::StreamFramePacketOverhead(
623 PACKET_8BYTE_CONNECTION_ID
, include_version
,
624 sequence_number_length
, 0u, is_in_fec_group
);
625 const size_t ack_length
= NullEncrypter().GetCiphertextSize(
626 QuicFramer::GetMinAckFrameSize(
627 sequence_number_length
, PACKET_1BYTE_SEQUENCE_NUMBER
)) +
628 GetPacketHeaderSize(connection_id_length
, include_version
,
629 sequence_number_length
, is_in_fec_group
);
630 if (stream_length
< ack_length
) {
631 *payload_length
= 1 + ack_length
- stream_length
;
634 return NullEncrypter().GetCiphertextSize(*payload_length
) +
635 QuicPacketCreator::StreamFramePacketOverhead(
636 connection_id_length
, include_version
,
637 sequence_number_length
, 0u, is_in_fec_group
);
640 TestEntropyCalculator::TestEntropyCalculator() {}
642 TestEntropyCalculator::~TestEntropyCalculator() {}
644 QuicPacketEntropyHash
TestEntropyCalculator::EntropyHash(
645 QuicPacketSequenceNumber sequence_number
) const {
649 MockEntropyCalculator::MockEntropyCalculator() {}
651 MockEntropyCalculator::~MockEntropyCalculator() {}
653 QuicConfig
DefaultQuicConfig() {
655 config
.SetInitialStreamFlowControlWindowToSend(
656 kInitialStreamFlowControlWindowForTest
);
657 config
.SetInitialSessionFlowControlWindowToSend(
658 kInitialSessionFlowControlWindowForTest
);
662 QuicVersionVector
SupportedVersions(QuicVersion version
) {
663 QuicVersionVector versions
;
664 versions
.push_back(version
);
668 TestWriterFactory::TestWriterFactory() : current_writer_(nullptr) {}
669 TestWriterFactory::~TestWriterFactory() {}
671 QuicPacketWriter
* TestWriterFactory::Create(QuicPacketWriter
* writer
,
672 QuicConnection
* connection
) {
673 return new PerConnectionPacketWriter(this, writer
, connection
);
676 void TestWriterFactory::OnPacketSent(WriteResult result
) {
677 if (current_writer_
!= nullptr && result
.status
== WRITE_STATUS_ERROR
) {
678 current_writer_
->connection()->OnWriteError(result
.error_code
);
679 current_writer_
= nullptr;
683 void TestWriterFactory::Unregister(PerConnectionPacketWriter
* writer
) {
684 if (current_writer_
== writer
) {
685 current_writer_
= nullptr;
689 TestWriterFactory::PerConnectionPacketWriter::PerConnectionPacketWriter(
690 TestWriterFactory
* factory
,
691 QuicPacketWriter
* writer
,
692 QuicConnection
* connection
)
693 : QuicPerConnectionPacketWriter(writer
, connection
),
697 TestWriterFactory::PerConnectionPacketWriter::~PerConnectionPacketWriter() {
698 factory_
->Unregister(this);
701 WriteResult
TestWriterFactory::PerConnectionPacketWriter::WritePacket(
704 const IPAddressNumber
& self_address
,
705 const IPEndPoint
& peer_address
) {
706 // A DCHECK(factory_current_writer_ == nullptr) would be wrong here -- this
707 // class may be used in a setting where connection()->OnPacketSent() is called
708 // in a different way, so TestWriterFactory::OnPacketSent might never be
710 factory_
->current_writer_
= this;
711 return tools::QuicPerConnectionPacketWriter::WritePacket(buffer
,
717 MockQuicConnectionDebugVisitor::MockQuicConnectionDebugVisitor() {
720 MockQuicConnectionDebugVisitor::~MockQuicConnectionDebugVisitor() {