| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2009 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2009 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #ifndef WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ | 11 #ifndef WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ |
| 12 #define WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ | 12 #define WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ |
| 13 | 13 |
| 14 #include <map> | 14 #include <map> |
| 15 #include <memory> | 15 #include <memory> |
| 16 #include <string> | 16 #include <string> |
| 17 #include <vector> | 17 #include <vector> |
| 18 | 18 |
| 19 #include "webrtc/p2p/base/candidatepairinterface.h" | 19 #include "webrtc/p2p/base/candidatepairinterface.h" |
| 20 #include "webrtc/p2p/base/transport.h" | |
| 21 #include "webrtc/p2p/base/transportchannel.h" | 20 #include "webrtc/p2p/base/transportchannel.h" |
| 22 #include "webrtc/p2p/base/transportcontroller.h" | 21 #include "webrtc/p2p/base/transportcontroller.h" |
| 23 #include "webrtc/p2p/base/transportchannelimpl.h" | 22 #include "webrtc/p2p/base/transportchannelimpl.h" |
| 24 #include "webrtc/base/bind.h" | 23 #include "webrtc/base/bind.h" |
| 25 #include "webrtc/base/buffer.h" | 24 #include "webrtc/base/buffer.h" |
| 26 #include "webrtc/base/fakesslidentity.h" | 25 #include "webrtc/base/fakesslidentity.h" |
| 27 #include "webrtc/base/messagequeue.h" | 26 #include "webrtc/base/messagequeue.h" |
| 28 #include "webrtc/base/sigslot.h" | 27 #include "webrtc/base/sigslot.h" |
| 29 #include "webrtc/base/sslfingerprint.h" | 28 #include "webrtc/base/sslfingerprint.h" |
| 30 #include "webrtc/base/thread.h" | 29 #include "webrtc/base/thread.h" |
| 31 | 30 |
| 32 #ifdef HAVE_QUIC | 31 #ifdef HAVE_QUIC |
| 33 #include "webrtc/p2p/quic/quictransport.h" | 32 #include "webrtc/p2p/quic/quictransport.h" |
| 34 #endif | 33 #endif |
| 35 | 34 |
| 36 namespace cricket { | 35 namespace cricket { |
| 37 | 36 |
| 38 class FakeTransport; | |
| 39 | |
| 40 namespace { | 37 namespace { |
| 41 struct PacketMessageData : public rtc::MessageData { | 38 struct PacketMessageData : public rtc::MessageData { |
| 42 PacketMessageData(const char* data, size_t len) : packet(data, len) {} | 39 PacketMessageData(const char* data, size_t len) : packet(data, len) {} |
| 43 rtc::Buffer packet; | 40 rtc::Buffer packet; |
| 44 }; | 41 }; |
| 45 } // namespace | 42 } // namespace |
| 46 | 43 |
| 47 // Fake transport channel class, which can be passed to anything that needs a | 44 // Fake transport channel class, which can be passed to anything that needs a |
| 48 // transport channel. Can be informed of another FakeTransportChannel via | 45 // transport channel. Can be informed of another FakeTransportChannel via |
| 49 // SetDestination. | 46 // SetDestination. |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 std::string remote_ice_pwd_; | 333 std::string remote_ice_pwd_; |
| 337 IceMode remote_ice_mode_ = ICEMODE_FULL; | 334 IceMode remote_ice_mode_ = ICEMODE_FULL; |
| 338 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; | 335 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; |
| 339 rtc::SSLFingerprint dtls_fingerprint_; | 336 rtc::SSLFingerprint dtls_fingerprint_; |
| 340 rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT; | 337 rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT; |
| 341 size_t connection_count_ = 0; | 338 size_t connection_count_ = 0; |
| 342 IceGatheringState gathering_state_ = kIceGatheringNew; | 339 IceGatheringState gathering_state_ = kIceGatheringNew; |
| 343 bool had_connection_ = false; | 340 bool had_connection_ = false; |
| 344 }; | 341 }; |
| 345 | 342 |
| 346 // Fake transport class, which can be passed to anything that needs a Transport. | |
| 347 // Can be informed of another FakeTransport via SetDestination (low-tech way | |
| 348 // of doing candidates) | |
| 349 class FakeTransport : public Transport { | |
| 350 public: | |
| 351 typedef std::map<int, FakeTransportChannel*> ChannelMap; | |
| 352 | |
| 353 explicit FakeTransport(const std::string& name) : Transport(name, nullptr) {} | |
| 354 | |
| 355 // Note that we only have a constructor with the allocator parameter so it can | |
| 356 // be wrapped by a DtlsTransport. | |
| 357 FakeTransport(const std::string& name, PortAllocator* allocator) | |
| 358 : Transport(name, nullptr) {} | |
| 359 | |
| 360 ~FakeTransport() { DestroyAllChannels(); } | |
| 361 | |
| 362 const ChannelMap& channels() const { return channels_; } | |
| 363 | |
| 364 // If async, will send packets by "Post"-ing to message queue instead of | |
| 365 // synchronously "Send"-ing. | |
| 366 void SetAsync(bool async) { async_ = async; } | |
| 367 void SetAsyncDelay(int delay_ms) { async_delay_ms_ = delay_ms; } | |
| 368 | |
| 369 // If |asymmetric| is true, only set the destination for this transport, and | |
| 370 // not |dest|. | |
| 371 void SetDestination(FakeTransport* dest, bool asymmetric = false) { | |
| 372 dest_ = dest; | |
| 373 for (const auto& kv : channels_) { | |
| 374 kv.second->SetLocalCertificate(certificate_); | |
| 375 SetChannelDestination(kv.first, kv.second, asymmetric); | |
| 376 } | |
| 377 } | |
| 378 | |
| 379 void SetWritable(bool writable) { | |
| 380 for (const auto& kv : channels_) { | |
| 381 kv.second->SetWritable(writable); | |
| 382 } | |
| 383 } | |
| 384 | |
| 385 void SetLocalCertificate( | |
| 386 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override { | |
| 387 certificate_ = certificate; | |
| 388 } | |
| 389 bool GetLocalCertificate( | |
| 390 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override { | |
| 391 if (!certificate_) | |
| 392 return false; | |
| 393 | |
| 394 *certificate = certificate_; | |
| 395 return true; | |
| 396 } | |
| 397 | |
| 398 bool GetSslRole(rtc::SSLRole* role) const override { | |
| 399 if (channels_.empty()) { | |
| 400 return false; | |
| 401 } | |
| 402 return channels_.begin()->second->GetSslRole(role); | |
| 403 } | |
| 404 | |
| 405 bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override { | |
| 406 ssl_max_version_ = version; | |
| 407 for (const auto& kv : channels_) { | |
| 408 kv.second->set_ssl_max_protocol_version(ssl_max_version_); | |
| 409 } | |
| 410 return true; | |
| 411 } | |
| 412 rtc::SSLProtocolVersion ssl_max_protocol_version() const { | |
| 413 return ssl_max_version_; | |
| 414 } | |
| 415 | |
| 416 using Transport::local_description; | |
| 417 using Transport::remote_description; | |
| 418 using Transport::VerifyCertificateFingerprint; | |
| 419 using Transport::NegotiateRole; | |
| 420 | |
| 421 protected: | |
| 422 TransportChannelImpl* CreateTransportChannel(int component) override { | |
| 423 if (channels_.find(component) != channels_.end()) { | |
| 424 return nullptr; | |
| 425 } | |
| 426 FakeTransportChannel* channel = new FakeTransportChannel(name(), component); | |
| 427 channel->set_ssl_max_protocol_version(ssl_max_version_); | |
| 428 channel->SetAsync(async_); | |
| 429 channel->SetAsyncDelay(async_delay_ms_); | |
| 430 SetChannelDestination(component, channel, false); | |
| 431 channels_[component] = channel; | |
| 432 return channel; | |
| 433 } | |
| 434 | |
| 435 void DestroyTransportChannel(TransportChannelImpl* channel) override { | |
| 436 channels_.erase(channel->component()); | |
| 437 delete channel; | |
| 438 } | |
| 439 | |
| 440 private: | |
| 441 FakeTransportChannel* GetFakeChannel(int component) { | |
| 442 auto it = channels_.find(component); | |
| 443 return (it != channels_.end()) ? it->second : nullptr; | |
| 444 } | |
| 445 | |
| 446 void SetChannelDestination(int component, | |
| 447 FakeTransportChannel* channel, | |
| 448 bool asymmetric) { | |
| 449 FakeTransportChannel* dest_channel = nullptr; | |
| 450 if (dest_) { | |
| 451 dest_channel = dest_->GetFakeChannel(component); | |
| 452 if (dest_channel && !asymmetric) { | |
| 453 dest_channel->SetLocalCertificate(dest_->certificate_); | |
| 454 } | |
| 455 } | |
| 456 channel->SetDestination(dest_channel, asymmetric); | |
| 457 } | |
| 458 | |
| 459 // Note, this is distinct from the Channel map owned by Transport. | |
| 460 // This map just tracks the FakeTransportChannels created by this class. | |
| 461 // It's mainly needed so that we can access a FakeTransportChannel directly, | |
| 462 // even if wrapped by a DtlsTransportChannelWrapper. | |
| 463 ChannelMap channels_; | |
| 464 FakeTransport* dest_ = nullptr; | |
| 465 bool async_ = false; | |
| 466 int async_delay_ms_ = 0; | |
| 467 rtc::scoped_refptr<rtc::RTCCertificate> certificate_; | |
| 468 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12; | |
| 469 }; | |
| 470 | |
| 471 #ifdef HAVE_QUIC | |
| 472 class FakeQuicTransport : public QuicTransport { | |
| 473 public: | |
| 474 FakeQuicTransport(const std::string& transport_name) | |
| 475 : QuicTransport(transport_name, nullptr, nullptr) {} | |
| 476 | |
| 477 protected: | |
| 478 QuicTransportChannel* CreateTransportChannel(int component) override { | |
| 479 FakeTransportChannel* fake_ice_transport_channel = | |
| 480 new FakeTransportChannel(name(), component); | |
| 481 return new QuicTransportChannel(fake_ice_transport_channel); | |
| 482 } | |
| 483 }; | |
| 484 #endif | |
| 485 | |
| 486 // Fake candidate pair class, which can be passed to BaseChannel for testing | 343 // Fake candidate pair class, which can be passed to BaseChannel for testing |
| 487 // purposes. | 344 // purposes. |
| 488 class FakeCandidatePair : public CandidatePairInterface { | 345 class FakeCandidatePair : public CandidatePairInterface { |
| 489 public: | 346 public: |
| 490 FakeCandidatePair(const Candidate& local_candidate, | 347 FakeCandidatePair(const Candidate& local_candidate, |
| 491 const Candidate& remote_candidate) | 348 const Candidate& remote_candidate) |
| 492 : local_candidate_(local_candidate), | 349 : local_candidate_(local_candidate), |
| 493 remote_candidate_(remote_candidate) {} | 350 remote_candidate_(remote_candidate) {} |
| 494 const Candidate& local_candidate() const override { return local_candidate_; } | 351 const Candidate& local_candidate() const override { return local_candidate_; } |
| 495 const Candidate& remote_candidate() const override { | 352 const Candidate& remote_candidate() const override { |
| 496 return remote_candidate_; | 353 return remote_candidate_; |
| 497 } | 354 } |
| 498 | 355 |
| 499 private: | 356 private: |
| 500 Candidate local_candidate_; | 357 Candidate local_candidate_; |
| 501 Candidate remote_candidate_; | 358 Candidate remote_candidate_; |
| 502 }; | 359 }; |
| 503 | 360 |
| 504 // Fake TransportController class, which can be passed into a BaseChannel object | 361 // Fake TransportController class, which can be passed into a BaseChannel object |
| 505 // for test purposes. Can be connected to other FakeTransportControllers via | 362 // for test purposes. Can be connected to other FakeTransportControllers via |
| 506 // Connect(). | 363 // Connect(). |
| 507 // | 364 // |
| 508 // This fake is unusual in that for the most part, it's implemented with the | 365 // This fake is unusual in that for the most part, it's implemented with the |
| 509 // real TransportController code, but with fake TransportChannels underneath. | 366 // real TransportController code, but with fake TransportChannels underneath. |
| 510 class FakeTransportController : public TransportController { | 367 class FakeTransportController : public TransportController { |
| 511 public: | 368 public: |
| 512 FakeTransportController() | 369 FakeTransportController() |
| 513 : TransportController(rtc::Thread::Current(), | 370 : TransportController(rtc::Thread::Current(), |
| 514 rtc::Thread::Current(), | 371 rtc::Thread::Current(), |
| 515 nullptr), | 372 nullptr) {} |
| 516 fail_create_channel_(false) {} | |
| 517 | 373 |
| 518 explicit FakeTransportController(bool redetermine_role_on_ice_restart) | 374 explicit FakeTransportController(bool redetermine_role_on_ice_restart) |
| 519 : TransportController(rtc::Thread::Current(), | 375 : TransportController(rtc::Thread::Current(), |
| 520 rtc::Thread::Current(), | 376 rtc::Thread::Current(), |
| 521 nullptr, | 377 nullptr, |
| 522 redetermine_role_on_ice_restart), | 378 redetermine_role_on_ice_restart) {} |
| 523 fail_create_channel_(false) {} | |
| 524 | 379 |
| 525 explicit FakeTransportController(IceRole role) | 380 explicit FakeTransportController(IceRole role) |
| 526 : TransportController(rtc::Thread::Current(), | 381 : TransportController(rtc::Thread::Current(), |
| 527 rtc::Thread::Current(), | 382 rtc::Thread::Current(), |
| 528 nullptr), | 383 nullptr) { |
| 529 fail_create_channel_(false) { | |
| 530 SetIceRole(role); | 384 SetIceRole(role); |
| 531 } | 385 } |
| 532 | 386 |
| 533 explicit FakeTransportController(rtc::Thread* network_thread) | 387 explicit FakeTransportController(rtc::Thread* network_thread) |
| 534 : TransportController(rtc::Thread::Current(), network_thread, nullptr), | 388 : TransportController(rtc::Thread::Current(), network_thread, nullptr) {} |
| 535 fail_create_channel_(false) {} | |
| 536 | 389 |
| 537 FakeTransportController(rtc::Thread* network_thread, IceRole role) | 390 FakeTransportController(rtc::Thread* network_thread, IceRole role) |
| 538 : TransportController(rtc::Thread::Current(), network_thread, nullptr), | 391 : TransportController(rtc::Thread::Current(), network_thread, nullptr) { |
| 539 fail_create_channel_(false) { | |
| 540 SetIceRole(role); | 392 SetIceRole(role); |
| 541 } | 393 } |
| 542 | 394 |
| 543 FakeTransport* GetTransport_n(const std::string& transport_name) { | 395 FakeTransportChannel* GetFakeTransportChannel_n( |
| 544 return static_cast<FakeTransport*>( | 396 const std::string& transport_name, |
| 545 TransportController::GetTransport_n(transport_name)); | 397 int component) { |
| 398 return static_cast<FakeTransportChannel*>( |
| 399 get_channel_for_testing(transport_name, component)); |
| 546 } | 400 } |
| 547 | 401 |
| 402 // Simulate the exchange of transport descriptions, and the gathering and |
| 403 // exchange of ICE candidates. |
| 548 void Connect(FakeTransportController* dest) { | 404 void Connect(FakeTransportController* dest) { |
| 405 for (const std::string& transport_name : transport_names_for_testing()) { |
| 406 TransportDescription local_desc( |
| 407 std::vector<std::string>(), |
| 408 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH), |
| 409 rtc::CreateRandomString(cricket::ICE_PWD_LENGTH), |
| 410 cricket::ICEMODE_FULL, cricket::CONNECTIONROLE_NONE, nullptr); |
| 411 TransportDescription remote_desc( |
| 412 std::vector<std::string>(), |
| 413 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH), |
| 414 rtc::CreateRandomString(cricket::ICE_PWD_LENGTH), |
| 415 cricket::ICEMODE_FULL, cricket::CONNECTIONROLE_NONE, nullptr); |
| 416 std::string err; |
| 417 SetLocalTransportDescription(transport_name, local_desc, |
| 418 cricket::CA_OFFER, &err); |
| 419 dest->SetRemoteTransportDescription(transport_name, local_desc, |
| 420 cricket::CA_OFFER, &err); |
| 421 dest->SetLocalTransportDescription(transport_name, remote_desc, |
| 422 cricket::CA_ANSWER, &err); |
| 423 SetRemoteTransportDescription(transport_name, remote_desc, |
| 424 cricket::CA_ANSWER, &err); |
| 425 } |
| 426 MaybeStartGathering(); |
| 427 dest->MaybeStartGathering(); |
| 549 network_thread()->Invoke<void>( | 428 network_thread()->Invoke<void>( |
| 550 RTC_FROM_HERE, | 429 RTC_FROM_HERE, |
| 551 rtc::Bind(&FakeTransportController::Connect_n, this, dest)); | 430 rtc::Bind(&FakeTransportController::SetChannelDestinations_n, this, |
| 552 } | 431 dest)); |
| 553 | |
| 554 TransportChannel* CreateTransportChannel_n(const std::string& transport_name, | |
| 555 int component) override { | |
| 556 if (fail_create_channel_) { | |
| 557 return nullptr; | |
| 558 } | |
| 559 return TransportController::CreateTransportChannel_n(transport_name, | |
| 560 component); | |
| 561 } | 432 } |
| 562 | 433 |
| 563 FakeCandidatePair* CreateFakeCandidatePair( | 434 FakeCandidatePair* CreateFakeCandidatePair( |
| 564 const rtc::SocketAddress& local_address, | 435 const rtc::SocketAddress& local_address, |
| 565 int16_t local_network_id, | 436 int16_t local_network_id, |
| 566 const rtc::SocketAddress& remote_address, | 437 const rtc::SocketAddress& remote_address, |
| 567 int16_t remote_network_id) { | 438 int16_t remote_network_id) { |
| 568 Candidate local_candidate(0, "udp", local_address, 0u, "", "", "local", 0, | 439 Candidate local_candidate(0, "udp", local_address, 0u, "", "", "local", 0, |
| 569 "foundation", local_network_id, 0); | 440 "foundation", local_network_id, 0); |
| 570 Candidate remote_candidate(0, "udp", remote_address, 0u, "", "", "local", 0, | 441 Candidate remote_candidate(0, "udp", remote_address, 0u, "", "", "local", 0, |
| 571 "foundation", remote_network_id, 0); | 442 "foundation", remote_network_id, 0); |
| 572 return new FakeCandidatePair(local_candidate, remote_candidate); | 443 return new FakeCandidatePair(local_candidate, remote_candidate); |
| 573 } | 444 } |
| 574 | 445 |
| 575 void set_fail_channel_creation(bool fail_channel_creation) { | 446 protected: |
| 576 fail_create_channel_ = fail_channel_creation; | 447 // The ICE channel is never actually used by TransportController directly, |
| 448 // since (currently) the DTLS channel pretends to be both ICE + DTLS. This |
| 449 // will change when we get rid of TransportChannelImpl. |
| 450 TransportChannelImpl* CreateIceTransportChannel_n( |
| 451 const std::string& transport_name, |
| 452 int component) override { |
| 453 return nullptr; |
| 577 } | 454 } |
| 578 | 455 |
| 579 protected: | 456 TransportChannelImpl* CreateDtlsTransportChannel_n( |
| 580 Transport* CreateTransport_n(const std::string& transport_name) override { | 457 const std::string& transport_name, |
| 581 #ifdef HAVE_QUIC | 458 int component, |
| 582 if (quic()) { | 459 TransportChannelImpl*) override { |
| 583 return new FakeQuicTransport(transport_name); | 460 return new FakeTransportChannel(transport_name, component); |
| 584 } | |
| 585 #endif | |
| 586 return new FakeTransport(transport_name); | |
| 587 } | |
| 588 | |
| 589 void Connect_n(FakeTransportController* dest) { | |
| 590 // Simulate the exchange of candidates. | |
| 591 ConnectChannels_n(); | |
| 592 dest->ConnectChannels_n(); | |
| 593 for (auto& kv : transports()) { | |
| 594 FakeTransport* transport = static_cast<FakeTransport*>(kv.second); | |
| 595 transport->SetDestination(dest->GetTransport_n(kv.first)); | |
| 596 } | |
| 597 } | |
| 598 | |
| 599 void ConnectChannels_n() { | |
| 600 TransportDescription faketransport_desc( | |
| 601 std::vector<std::string>(), | |
| 602 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH), | |
| 603 rtc::CreateRandomString(cricket::ICE_PWD_LENGTH), cricket::ICEMODE_FULL, | |
| 604 cricket::CONNECTIONROLE_NONE, nullptr); | |
| 605 for (auto& kv : transports()) { | |
| 606 FakeTransport* transport = static_cast<FakeTransport*>(kv.second); | |
| 607 // Set local transport description for FakeTransport before connecting. | |
| 608 // Otherwise, the RTC_CHECK in Transport.ConnectChannel will fail. | |
| 609 if (!transport->local_description()) { | |
| 610 transport->SetLocalTransportDescription(faketransport_desc, | |
| 611 cricket::CA_OFFER, nullptr); | |
| 612 } | |
| 613 transport->MaybeStartGathering(); | |
| 614 } | |
| 615 } | 461 } |
| 616 | 462 |
| 617 private: | 463 private: |
| 618 bool fail_create_channel_; | 464 void SetChannelDestinations_n(FakeTransportController* dest) { |
| 465 for (TransportChannelImpl* tc : channels_for_testing()) { |
| 466 FakeTransportChannel* local = static_cast<FakeTransportChannel*>(tc); |
| 467 FakeTransportChannel* remote = dest->GetFakeTransportChannel_n( |
| 468 local->transport_name(), local->component()); |
| 469 if (remote) { |
| 470 bool asymmetric = false; |
| 471 local->SetDestination(remote, asymmetric); |
| 472 } |
| 473 } |
| 474 } |
| 619 }; | 475 }; |
| 620 | 476 |
| 621 } // namespace cricket | 477 } // namespace cricket |
| 622 | 478 |
| 623 #endif // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ | 479 #endif // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_ |
| OLD | NEW |