quic_test_utils.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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/test_tools/quic_test_utils.h" 6 7#include "base/stl_util.h" 8#include "base/strings/string_number_conversions.h" 9#include "net/quic/crypto/crypto_framer.h" 10#include "net/quic/crypto/crypto_handshake.h" 11#include "net/quic/crypto/crypto_utils.h" 12#include "net/quic/crypto/null_encrypter.h" 13#include "net/quic/crypto/quic_decrypter.h" 14#include "net/quic/crypto/quic_encrypter.h" 15#include "net/quic/quic_framer.h" 16#include "net/quic/quic_packet_creator.h" 17#include "net/quic/quic_utils.h" 18#include "net/quic/test_tools/quic_connection_peer.h" 19#include "net/spdy/spdy_frame_builder.h" 20 21using base::StringPiece; 22using std::max; 23using std::min; 24using std::string; 25using testing::_; 26using testing::AnyNumber; 27 28namespace net { 29namespace test { 30namespace { 31 32// No-op alarm implementation used by MockHelper. 33class TestAlarm : public QuicAlarm { 34 public: 35 explicit TestAlarm(QuicAlarm::Delegate* delegate) 36 : QuicAlarm(delegate) { 37 } 38 39 virtual void SetImpl() OVERRIDE {} 40 virtual void CancelImpl() OVERRIDE {} 41}; 42 43} // namespace 44 45MockFramerVisitor::MockFramerVisitor() { 46 // By default, we want to accept packets. 47 ON_CALL(*this, OnProtocolVersionMismatch(_)) 48 .WillByDefault(testing::Return(false)); 49 50 // By default, we want to accept packets. 51 ON_CALL(*this, OnUnauthenticatedHeader(_)) 52 .WillByDefault(testing::Return(true)); 53 54 ON_CALL(*this, OnUnauthenticatedPublicHeader(_)) 55 .WillByDefault(testing::Return(true)); 56 57 ON_CALL(*this, OnPacketHeader(_)) 58 .WillByDefault(testing::Return(true)); 59 60 ON_CALL(*this, OnStreamFrame(_)) 61 .WillByDefault(testing::Return(true)); 62 63 ON_CALL(*this, OnAckFrame(_)) 64 .WillByDefault(testing::Return(true)); 65 66 ON_CALL(*this, OnCongestionFeedbackFrame(_)) 67 .WillByDefault(testing::Return(true)); 68 69 ON_CALL(*this, OnStopWaitingFrame(_)) 70 .WillByDefault(testing::Return(true)); 71 72 ON_CALL(*this, OnRstStreamFrame(_)) 73 .WillByDefault(testing::Return(true)); 74 75 ON_CALL(*this, OnConnectionCloseFrame(_)) 76 .WillByDefault(testing::Return(true)); 77 78 ON_CALL(*this, OnGoAwayFrame(_)) 79 .WillByDefault(testing::Return(true)); 80} 81 82MockFramerVisitor::~MockFramerVisitor() { 83} 84 85bool NoOpFramerVisitor::OnProtocolVersionMismatch(QuicVersion version) { 86 return false; 87} 88 89bool NoOpFramerVisitor::OnUnauthenticatedPublicHeader( 90 const QuicPacketPublicHeader& header) { 91 return true; 92} 93 94bool NoOpFramerVisitor::OnUnauthenticatedHeader( 95 const QuicPacketHeader& header) { 96 return true; 97} 98 99bool NoOpFramerVisitor::OnPacketHeader(const QuicPacketHeader& header) { 100 return true; 101} 102 103bool NoOpFramerVisitor::OnStreamFrame(const QuicStreamFrame& frame) { 104 return true; 105} 106 107bool NoOpFramerVisitor::OnAckFrame(const QuicAckFrame& frame) { 108 return true; 109} 110 111bool NoOpFramerVisitor::OnCongestionFeedbackFrame( 112 const QuicCongestionFeedbackFrame& frame) { 113 return true; 114} 115 116bool NoOpFramerVisitor::OnStopWaitingFrame( 117 const QuicStopWaitingFrame& frame) { 118 return true; 119} 120 121bool NoOpFramerVisitor::OnRstStreamFrame( 122 const QuicRstStreamFrame& frame) { 123 return true; 124} 125 126bool NoOpFramerVisitor::OnConnectionCloseFrame( 127 const QuicConnectionCloseFrame& frame) { 128 return true; 129} 130 131bool NoOpFramerVisitor::OnGoAwayFrame(const QuicGoAwayFrame& frame) { 132 return true; 133} 134 135bool NoOpFramerVisitor::OnWindowUpdateFrame( 136 const QuicWindowUpdateFrame& frame) { 137 return true; 138} 139 140bool NoOpFramerVisitor::OnBlockedFrame(const QuicBlockedFrame& frame) { 141 return true; 142} 143 144FramerVisitorCapturingFrames::FramerVisitorCapturingFrames() : frame_count_(0) { 145} 146 147FramerVisitorCapturingFrames::~FramerVisitorCapturingFrames() { 148 Reset(); 149} 150 151void FramerVisitorCapturingFrames::Reset() { 152 STLDeleteElements(&stream_data_); 153 stream_frames_.clear(); 154 frame_count_ = 0; 155 ack_.reset(); 156 feedback_.reset(); 157 rst_.reset(); 158 close_.reset(); 159 goaway_.reset(); 160 version_negotiation_packet_.reset(); 161} 162 163bool FramerVisitorCapturingFrames::OnPacketHeader( 164 const QuicPacketHeader& header) { 165 header_ = header; 166 frame_count_ = 0; 167 return true; 168} 169 170bool FramerVisitorCapturingFrames::OnStreamFrame(const QuicStreamFrame& frame) { 171 // Make a copy of the frame and store a copy of underlying string, since 172 // frame.data may not exist outside this callback. 173 stream_data_.push_back(frame.GetDataAsString()); 174 QuicStreamFrame frame_copy = frame; 175 frame_copy.data.Clear(); 176 frame_copy.data.Append(const_cast<char*>(stream_data_.back()->data()), 177 stream_data_.back()->size()); 178 stream_frames_.push_back(frame_copy); 179 ++frame_count_; 180 return true; 181} 182 183bool FramerVisitorCapturingFrames::OnAckFrame(const QuicAckFrame& frame) { 184 ack_.reset(new QuicAckFrame(frame)); 185 ++frame_count_; 186 return true; 187} 188 189bool FramerVisitorCapturingFrames::OnCongestionFeedbackFrame( 190 const QuicCongestionFeedbackFrame& frame) { 191 feedback_.reset(new QuicCongestionFeedbackFrame(frame)); 192 ++frame_count_; 193 return true; 194} 195 196bool FramerVisitorCapturingFrames::OnStopWaitingFrame( 197 const QuicStopWaitingFrame& frame) { 198 stop_waiting_.reset(new QuicStopWaitingFrame(frame)); 199 ++frame_count_; 200 return true; 201} 202 203bool FramerVisitorCapturingFrames::OnRstStreamFrame( 204 const QuicRstStreamFrame& frame) { 205 rst_.reset(new QuicRstStreamFrame(frame)); 206 ++frame_count_; 207 return true; 208} 209 210bool FramerVisitorCapturingFrames::OnConnectionCloseFrame( 211 const QuicConnectionCloseFrame& frame) { 212 close_.reset(new QuicConnectionCloseFrame(frame)); 213 ++frame_count_; 214 return true; 215} 216 217bool FramerVisitorCapturingFrames::OnGoAwayFrame(const QuicGoAwayFrame& frame) { 218 goaway_.reset(new QuicGoAwayFrame(frame)); 219 ++frame_count_; 220 return true; 221} 222 223void FramerVisitorCapturingFrames::OnVersionNegotiationPacket( 224 const QuicVersionNegotiationPacket& packet) { 225 version_negotiation_packet_.reset(new QuicVersionNegotiationPacket(packet)); 226 frame_count_ = 0; 227} 228 229FramerVisitorCapturingPublicReset::FramerVisitorCapturingPublicReset() { 230} 231 232FramerVisitorCapturingPublicReset::~FramerVisitorCapturingPublicReset() { 233} 234 235void FramerVisitorCapturingPublicReset::OnPublicResetPacket( 236 const QuicPublicResetPacket& public_reset) { 237 public_reset_packet_ = public_reset; 238} 239 240MockConnectionVisitor::MockConnectionVisitor() { 241} 242 243MockConnectionVisitor::~MockConnectionVisitor() { 244} 245 246MockHelper::MockHelper() { 247} 248 249MockHelper::~MockHelper() { 250} 251 252const QuicClock* MockHelper::GetClock() const { 253 return &clock_; 254} 255 256QuicRandom* MockHelper::GetRandomGenerator() { 257 return &random_generator_; 258} 259 260QuicAlarm* MockHelper::CreateAlarm(QuicAlarm::Delegate* delegate) { 261 return new TestAlarm(delegate); 262} 263 264void MockHelper::AdvanceTime(QuicTime::Delta delta) { 265 clock_.AdvanceTime(delta); 266} 267 268MockConnection::MockConnection(bool is_server) 269 : QuicConnection(kTestConnectionId, 270 IPEndPoint(TestPeerIPAddress(), kTestPort), 271 new testing::NiceMock<MockHelper>(), 272 new testing::NiceMock<MockPacketWriter>(), 273 is_server, QuicSupportedVersions(), 274 kInitialFlowControlWindowForTest), 275 writer_(QuicConnectionPeer::GetWriter(this)), 276 helper_(helper()) { 277} 278 279MockConnection::MockConnection(IPEndPoint address, 280 bool is_server) 281 : QuicConnection(kTestConnectionId, address, 282 new testing::NiceMock<MockHelper>(), 283 new testing::NiceMock<MockPacketWriter>(), 284 is_server, QuicSupportedVersions(), 285 kInitialFlowControlWindowForTest), 286 writer_(QuicConnectionPeer::GetWriter(this)), 287 helper_(helper()) { 288} 289 290MockConnection::MockConnection(QuicConnectionId connection_id, 291 bool is_server) 292 : QuicConnection(connection_id, 293 IPEndPoint(TestPeerIPAddress(), kTestPort), 294 new testing::NiceMock<MockHelper>(), 295 new testing::NiceMock<MockPacketWriter>(), 296 is_server, QuicSupportedVersions(), 297 kInitialFlowControlWindowForTest), 298 writer_(QuicConnectionPeer::GetWriter(this)), 299 helper_(helper()) { 300} 301 302MockConnection::MockConnection(bool is_server, 303 const QuicVersionVector& supported_versions) 304 : QuicConnection(kTestConnectionId, 305 IPEndPoint(TestPeerIPAddress(), kTestPort), 306 new testing::NiceMock<MockHelper>(), 307 new testing::NiceMock<MockPacketWriter>(), 308 is_server, supported_versions, 309 kInitialFlowControlWindowForTest), 310 writer_(QuicConnectionPeer::GetWriter(this)), 311 helper_(helper()) { 312} 313 314MockConnection::~MockConnection() { 315} 316 317void MockConnection::AdvanceTime(QuicTime::Delta delta) { 318 static_cast<MockHelper*>(helper())->AdvanceTime(delta); 319} 320 321PacketSavingConnection::PacketSavingConnection(bool is_server) 322 : MockConnection(is_server) { 323} 324 325PacketSavingConnection::PacketSavingConnection( 326 bool is_server, 327 const QuicVersionVector& supported_versions) 328 : MockConnection(is_server, supported_versions) { 329} 330 331PacketSavingConnection::~PacketSavingConnection() { 332 STLDeleteElements(&packets_); 333 STLDeleteElements(&encrypted_packets_); 334} 335 336bool PacketSavingConnection::SendOrQueuePacket( 337 EncryptionLevel level, 338 const SerializedPacket& packet, 339 TransmissionType transmission_type) { 340 packets_.push_back(packet.packet); 341 QuicEncryptedPacket* encrypted = QuicConnectionPeer::GetFramer(this)-> 342 EncryptPacket(level, packet.sequence_number, *packet.packet); 343 encrypted_packets_.push_back(encrypted); 344 return true; 345} 346 347MockSession::MockSession(QuicConnection* connection) 348 : QuicSession(connection, DefaultQuicConfig()) { 349 ON_CALL(*this, WritevData(_, _, _, _, _)) 350 .WillByDefault(testing::Return(QuicConsumedData(0, false))); 351} 352 353MockSession::~MockSession() { 354} 355 356TestSession::TestSession(QuicConnection* connection, 357 const QuicConfig& config) 358 : QuicSession(connection, config), 359 crypto_stream_(NULL) { 360} 361 362TestSession::~TestSession() {} 363 364void TestSession::SetCryptoStream(QuicCryptoStream* stream) { 365 crypto_stream_ = stream; 366} 367 368QuicCryptoStream* TestSession::GetCryptoStream() { 369 return crypto_stream_; 370} 371 372TestClientSession::TestClientSession(QuicConnection* connection, 373 const QuicConfig& config) 374 : QuicClientSessionBase(connection, config), 375 crypto_stream_(NULL) { 376 EXPECT_CALL(*this, OnProofValid(_)).Times(AnyNumber()); 377} 378 379TestClientSession::~TestClientSession() {} 380 381void TestClientSession::SetCryptoStream(QuicCryptoStream* stream) { 382 crypto_stream_ = stream; 383} 384 385QuicCryptoStream* TestClientSession::GetCryptoStream() { 386 return crypto_stream_; 387} 388 389MockPacketWriter::MockPacketWriter() { 390} 391 392MockPacketWriter::~MockPacketWriter() { 393} 394 395MockSendAlgorithm::MockSendAlgorithm() { 396} 397 398MockSendAlgorithm::~MockSendAlgorithm() { 399} 400 401MockLossAlgorithm::MockLossAlgorithm() { 402} 403 404MockLossAlgorithm::~MockLossAlgorithm() { 405} 406 407MockAckNotifierDelegate::MockAckNotifierDelegate() { 408} 409 410MockAckNotifierDelegate::~MockAckNotifierDelegate() { 411} 412 413namespace { 414 415string HexDumpWithMarks(const char* data, int length, 416 const bool* marks, int mark_length) { 417 static const char kHexChars[] = "0123456789abcdef"; 418 static const int kColumns = 4; 419 420 const int kSizeLimit = 1024; 421 if (length > kSizeLimit || mark_length > kSizeLimit) { 422 LOG(ERROR) << "Only dumping first " << kSizeLimit << " bytes."; 423 length = min(length, kSizeLimit); 424 mark_length = min(mark_length, kSizeLimit); 425 } 426 427 string hex; 428 for (const char* row = data; length > 0; 429 row += kColumns, length -= kColumns) { 430 for (const char *p = row; p < row + 4; ++p) { 431 if (p < row + length) { 432 const bool mark = 433 (marks && (p - data) < mark_length && marks[p - data]); 434 hex += mark ? '*' : ' '; 435 hex += kHexChars[(*p & 0xf0) >> 4]; 436 hex += kHexChars[*p & 0x0f]; 437 hex += mark ? '*' : ' '; 438 } else { 439 hex += " "; 440 } 441 } 442 hex = hex + " "; 443 444 for (const char *p = row; p < row + 4 && p < row + length; ++p) 445 hex += (*p >= 0x20 && *p <= 0x7f) ? (*p) : '.'; 446 447 hex = hex + '\n'; 448 } 449 return hex; 450} 451 452} // namespace 453 454IPAddressNumber TestPeerIPAddress() { return Loopback4(); } 455 456QuicVersion QuicVersionMax() { return QuicSupportedVersions().front(); } 457 458QuicVersion QuicVersionMin() { return QuicSupportedVersions().back(); } 459 460IPAddressNumber Loopback4() { 461 IPAddressNumber addr; 462 CHECK(ParseIPLiteralToNumber("127.0.0.1", &addr)); 463 return addr; 464} 465 466void GenerateBody(string* body, int length) { 467 body->clear(); 468 body->reserve(length); 469 for (int i = 0; i < length; ++i) { 470 body->append(1, static_cast<char>(32 + i % (126 - 32))); 471 } 472} 473 474QuicEncryptedPacket* ConstructEncryptedPacket( 475 QuicConnectionId connection_id, 476 bool version_flag, 477 bool reset_flag, 478 QuicPacketSequenceNumber sequence_number, 479 const string& data) { 480 QuicPacketHeader header; 481 header.public_header.connection_id = connection_id; 482 header.public_header.connection_id_length = PACKET_8BYTE_CONNECTION_ID; 483 header.public_header.version_flag = version_flag; 484 header.public_header.reset_flag = reset_flag; 485 header.public_header.sequence_number_length = PACKET_6BYTE_SEQUENCE_NUMBER; 486 header.packet_sequence_number = sequence_number; 487 header.entropy_flag = false; 488 header.entropy_hash = 0; 489 header.fec_flag = false; 490 header.is_in_fec_group = NOT_IN_FEC_GROUP; 491 header.fec_group = 0; 492 QuicStreamFrame stream_frame(1, false, 0, MakeIOVector(data)); 493 QuicFrame frame(&stream_frame); 494 QuicFrames frames; 495 frames.push_back(frame); 496 QuicFramer framer(QuicSupportedVersions(), QuicTime::Zero(), false); 497 scoped_ptr<QuicPacket> packet( 498 framer.BuildUnsizedDataPacket(header, frames).packet); 499 EXPECT_TRUE(packet != NULL); 500 QuicEncryptedPacket* encrypted = framer.EncryptPacket(ENCRYPTION_NONE, 501 sequence_number, 502 *packet); 503 EXPECT_TRUE(encrypted != NULL); 504 return encrypted; 505} 506 507void CompareCharArraysWithHexError( 508 const string& description, 509 const char* actual, 510 const int actual_len, 511 const char* expected, 512 const int expected_len) { 513 EXPECT_EQ(actual_len, expected_len); 514 const int min_len = min(actual_len, expected_len); 515 const int max_len = max(actual_len, expected_len); 516 scoped_ptr<bool[]> marks(new bool[max_len]); 517 bool identical = (actual_len == expected_len); 518 for (int i = 0; i < min_len; ++i) { 519 if (actual[i] != expected[i]) { 520 marks[i] = true; 521 identical = false; 522 } else { 523 marks[i] = false; 524 } 525 } 526 for (int i = min_len; i < max_len; ++i) { 527 marks[i] = true; 528 } 529 if (identical) return; 530 ADD_FAILURE() 531 << "Description:\n" 532 << description 533 << "\n\nExpected:\n" 534 << HexDumpWithMarks(expected, expected_len, marks.get(), max_len) 535 << "\nActual:\n" 536 << HexDumpWithMarks(actual, actual_len, marks.get(), max_len); 537} 538 539bool DecodeHexString(const base::StringPiece& hex, std::string* bytes) { 540 bytes->clear(); 541 if (hex.empty()) 542 return true; 543 std::vector<uint8> v; 544 if (!base::HexStringToBytes(hex.as_string(), &v)) 545 return false; 546 if (!v.empty()) 547 bytes->assign(reinterpret_cast<const char*>(&v[0]), v.size()); 548 return true; 549} 550 551static QuicPacket* ConstructPacketFromHandshakeMessage( 552 QuicConnectionId connection_id, 553 const CryptoHandshakeMessage& message, 554 bool should_include_version) { 555 CryptoFramer crypto_framer; 556 scoped_ptr<QuicData> data(crypto_framer.ConstructHandshakeMessage(message)); 557 QuicFramer quic_framer(QuicSupportedVersions(), QuicTime::Zero(), false); 558 559 QuicPacketHeader header; 560 header.public_header.connection_id = connection_id; 561 header.public_header.reset_flag = false; 562 header.public_header.version_flag = should_include_version; 563 header.packet_sequence_number = 1; 564 header.entropy_flag = false; 565 header.entropy_hash = 0; 566 header.fec_flag = false; 567 header.fec_group = 0; 568 569 QuicStreamFrame stream_frame(kCryptoStreamId, false, 0, 570 MakeIOVector(data->AsStringPiece())); 571 572 QuicFrame frame(&stream_frame); 573 QuicFrames frames; 574 frames.push_back(frame); 575 return quic_framer.BuildUnsizedDataPacket(header, frames).packet; 576} 577 578QuicPacket* ConstructHandshakePacket(QuicConnectionId connection_id, 579 QuicTag tag) { 580 CryptoHandshakeMessage message; 581 message.set_tag(tag); 582 return ConstructPacketFromHandshakeMessage(connection_id, message, false); 583} 584 585size_t GetPacketLengthForOneStream( 586 QuicVersion version, 587 bool include_version, 588 QuicSequenceNumberLength sequence_number_length, 589 InFecGroup is_in_fec_group, 590 size_t* payload_length) { 591 *payload_length = 1; 592 const size_t stream_length = 593 NullEncrypter().GetCiphertextSize(*payload_length) + 594 QuicPacketCreator::StreamFramePacketOverhead( 595 version, PACKET_8BYTE_CONNECTION_ID, include_version, 596 sequence_number_length, is_in_fec_group); 597 const size_t ack_length = NullEncrypter().GetCiphertextSize( 598 QuicFramer::GetMinAckFrameSize( 599 version, sequence_number_length, PACKET_1BYTE_SEQUENCE_NUMBER)) + 600 GetPacketHeaderSize(PACKET_8BYTE_CONNECTION_ID, include_version, 601 sequence_number_length, is_in_fec_group); 602 if (stream_length < ack_length) { 603 *payload_length = 1 + ack_length - stream_length; 604 } 605 606 return NullEncrypter().GetCiphertextSize(*payload_length) + 607 QuicPacketCreator::StreamFramePacketOverhead( 608 version, PACKET_8BYTE_CONNECTION_ID, include_version, 609 sequence_number_length, is_in_fec_group); 610} 611 612TestEntropyCalculator::TestEntropyCalculator() { } 613 614TestEntropyCalculator::~TestEntropyCalculator() { } 615 616QuicPacketEntropyHash TestEntropyCalculator::EntropyHash( 617 QuicPacketSequenceNumber sequence_number) const { 618 return 1u; 619} 620 621MockEntropyCalculator::MockEntropyCalculator() { } 622 623MockEntropyCalculator::~MockEntropyCalculator() { } 624 625QuicConfig DefaultQuicConfig() { 626 QuicConfig config; 627 config.SetDefaults(); 628 return config; 629} 630 631QuicVersionVector SupportedVersions(QuicVersion version) { 632 QuicVersionVector versions; 633 versions.push_back(version); 634 return versions; 635} 636 637} // namespace test 638} // namespace net 639