| 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 | 
|---|